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