upd: essential/file updated
helper progress updated
This commit is contained in:
parent
bfd7224538
commit
650b19d22d
@ -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,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user