From 05e66b30b14eb0642acaaa1ab4f79a29602af0e6 Mon Sep 17 00:00:00 2001 From: Rajon Ahmed Date: Fri, 28 Aug 2026 12:57:35 +0800 Subject: [PATCH] upd: essential/file updated helper progress updated --- .../service/helper/progress/progress.go | 375 ++++++++++++++++++ 1 file changed, 375 insertions(+) diff --git a/essential/visible/service/helper/progress/progress.go b/essential/visible/service/helper/progress/progress.go index e69de29..cfa1bde 100644 --- a/essential/visible/service/helper/progress/progress.go +++ b/essential/visible/service/helper/progress/progress.go @@ -0,0 +1,375 @@ +/* +|-------------------------------------------------------------------------- +| Description +|-------------------------------------------------------------------------- +| +| Name: +| - Progress +| +| Purpose: +| - Manage, monitor, and report lifecycle-aware task progress through +| standardized progress tracking for countable and uncountable workflows. +| +|-------------------------------------------------------------------------- +*/ + +/* +|-------------------------------------------------------------------------- +| Instruction +|-------------------------------------------------------------------------- +| +| Guideline: +| - Use countable progress when tracking numeric progress using current +| and target values. +| - Use uncountable progress when tracking activity-based progress +| without percentage calculation. +| - Provide the lifecycle state through the state configuration value. +| - Provide current and target values when using countable progress. +| +| Example: +| - ObrimProgress("countable", map[string]any{ +| "state": "running", +| "current": 50, +| "target": 100, +| }) +| +| - ObrimProgress("uncountable", map[string]any{ +| "state": "running", +| }) +| +|-------------------------------------------------------------------------- +*/ + +/* +|-------------------------------------------------------------------------- +| Credit +|-------------------------------------------------------------------------- +| +| Contributor: +| - Rajon Ahmed +| - Blockonite +| +|-------------------------------------------------------------------------- +*/ + +package progress + +import ( + "math" +) + +const ( + obrimProgressTypeCountable = "countable" + obrimProgressTypeUncountable = "uncountable" + + obrimProgressStateStarted = "started" + obrimProgressStateRunning = "running" + obrimProgressStateCompleted = "completed" + obrimProgressStateCanceled = "canceled" + + obrimProgressSuccessStarted = "SUCCESS_STARTED" + obrimProgressSuccessRunning = "SUCCESS_RUNNING" + obrimProgressSuccessCompleted = "SUCCESS_COMPLETED" + obrimProgressSuccessCanceled = "SUCCESS_CANCELED" + + obrimProgressFailureInvalidType = "FAILURE_INVALID_TYPE" + obrimProgressFailureMissingState = "FAILURE_MISSING_STATE" + obrimProgressFailureInvalidState = "FAILURE_INVALID_STATE" + obrimProgressFailureMissingCurrent = "FAILURE_MISSING_CURRENT" + obrimProgressFailureInvalidCurrent = "FAILURE_INVALID_CURRENT" + obrimProgressFailureMissingTarget = "FAILURE_MISSING_TARGET" + obrimProgressFailureInvalidTarget = "FAILURE_INVALID_TARGET" + obrimProgressFailureNonPositiveTarget = "FAILURE_NON_POSITIVE_TARGET" +) + +type obrimProgressPayload struct { + Type string + State string + Current any + Target any + Percentage any +} + +type obrimProgressOutput struct { + Status bool + Code string + Payload any +} + +// ObrimProgress manages lifecycle-aware countable and uncountable progress. +func ObrimProgress(progressType string, config map[string]any) map[string]any { + if code := obrimProgressValidateInput(progressType, config); code != "" { + return obrimProgressBuildOutput(false, code, nil) + } + + return obrimProgressRouteRequest(progressType, config) +} + +// obrimProgressValidateInput validates the requested progress type and configuration. +func obrimProgressValidateInput(progressType string, config map[string]any) string { + switch progressType { + case obrimProgressTypeCountable: + state, exists := config["state"] + if !exists { + return obrimProgressFailureMissingState + } + + stateValue, ok := state.(string) + if !ok { + return obrimProgressFailureInvalidState + } + + switch stateValue { + case obrimProgressStateStarted, + obrimProgressStateRunning, + obrimProgressStateCompleted, + obrimProgressStateCanceled: + default: + return obrimProgressFailureInvalidState + } + + if _, exists := config["current"]; !exists { + return obrimProgressFailureMissingCurrent + } + + switch config["current"].(type) { + case int, int8, int16, int32, int64, + uint, uint8, uint16, uint32, uint64, + float32, float64: + default: + return obrimProgressFailureInvalidCurrent + } + + if _, exists := config["target"]; !exists { + return obrimProgressFailureMissingTarget + } + + switch config["target"].(type) { + case int, int8, int16, int32, int64, + uint, uint8, uint16, uint32, uint64, + float32, float64: + default: + return obrimProgressFailureInvalidTarget + } + + target := 0.0 + + switch value := config["target"].(type) { + case int: + target = float64(value) + case int8: + target = float64(value) + case int16: + target = float64(value) + case int32: + target = float64(value) + case int64: + target = float64(value) + case uint: + target = float64(value) + case uint8: + target = float64(value) + case uint16: + target = float64(value) + case uint32: + target = float64(value) + case uint64: + target = float64(value) + case float32: + target = float64(value) + case float64: + target = value + } + + if target <= 0 { + return obrimProgressFailureNonPositiveTarget + } + + case obrimProgressTypeUncountable: + state, exists := config["state"] + if !exists { + return obrimProgressFailureMissingState + } + + stateValue, ok := state.(string) + if !ok { + return obrimProgressFailureInvalidState + } + + switch stateValue { + case obrimProgressStateStarted, + obrimProgressStateRunning, + obrimProgressStateCompleted, + obrimProgressStateCanceled: + default: + return obrimProgressFailureInvalidState + } + + default: + return obrimProgressFailureInvalidType + } + + return "" +} + +// obrimProgressRouteRequest routes progress processing to its type-specific entry function. +func obrimProgressRouteRequest(progressType string, config map[string]any) map[string]any { + switch progressType { + case obrimProgressTypeCountable: + return obrimProgressCountable(config) + case obrimProgressTypeUncountable: + return obrimProgressUncountable(config) + default: + return obrimProgressBuildOutput(false, obrimProgressFailureInvalidType, nil) + } +} + +// obrimProgressBuildOutput builds the standardized progress utility output. +func obrimProgressBuildOutput(status bool, code string, payload *obrimProgressPayload) map[string]any { + output := map[string]any{ + "status": status, + "code": code, + "payload": nil, + } + + if payload == nil { + return output + } + + output["payload"] = map[string]any{ + "type": payload.Type, + "state": payload.State, + "current": payload.Current, + "target": payload.Target, + "percentage": payload.Percentage, + } + + return output +} + +// obrimProgressCountable processes countable progress workflows. +func obrimProgressCountable(config map[string]any) map[string]any { + state := config["state"].(string) + + var current float64 + var target float64 + + switch value := config["current"].(type) { + case int: + current = float64(value) + case int8: + current = float64(value) + case int16: + current = float64(value) + case int32: + current = float64(value) + case int64: + current = float64(value) + case uint: + current = float64(value) + case uint8: + current = float64(value) + case uint16: + current = float64(value) + case uint32: + current = float64(value) + case uint64: + current = float64(value) + case float32: + current = float64(value) + case float64: + current = value + } + + switch value := config["target"].(type) { + case int: + target = float64(value) + case int8: + target = float64(value) + case int16: + target = float64(value) + case int32: + target = float64(value) + case int64: + target = float64(value) + case uint: + target = float64(value) + case uint8: + target = float64(value) + case uint16: + target = float64(value) + case uint32: + target = float64(value) + case uint64: + target = float64(value) + case float32: + target = float64(value) + case float64: + target = value + } + + percentage := int(math.Round((current / target) * 100)) + + if percentage < 0 { + percentage = 0 + } + + if percentage > 100 { + percentage = 100 + } + + code := obrimProgressSuccessRunning + + switch state { + case obrimProgressStateStarted: + code = obrimProgressSuccessStarted + case obrimProgressStateRunning: + code = obrimProgressSuccessRunning + case obrimProgressStateCompleted: + code = obrimProgressSuccessCompleted + case obrimProgressStateCanceled: + code = obrimProgressSuccessCanceled + } + + return obrimProgressBuildOutput( + true, + code, + &obrimProgressPayload{ + Type: obrimProgressTypeCountable, + State: state, + Current: current, + Target: target, + Percentage: percentage, + }, + ) +} + +// obrimProgressUncountable processes uncountable progress workflows. +func obrimProgressUncountable(config map[string]any) map[string]any { + state := config["state"].(string) + + code := obrimProgressSuccessRunning + + switch state { + case obrimProgressStateStarted: + code = obrimProgressSuccessStarted + case obrimProgressStateRunning: + code = obrimProgressSuccessRunning + case obrimProgressStateCompleted: + code = obrimProgressSuccessCompleted + case obrimProgressStateCanceled: + code = obrimProgressSuccessCanceled + } + + return obrimProgressBuildOutput( + true, + code, + &obrimProgressPayload{ + Type: obrimProgressTypeUncountable, + State: state, + Current: nil, + Target: nil, + Percentage: nil, + }, + ) +}