yao/widgets/action/action.go
2022-09-27 21:16:57 +08:00

148 lines
2.9 KiB
Go

package action
import (
"fmt"
"github.com/yaoapp/gou"
"github.com/yaoapp/kun/any"
"github.com/yaoapp/kun/exception"
"github.com/yaoapp/yao/widgets/hook"
)
// Bind the process name
func (p *Process) Bind(name string) {
p.ProcessBind = name
}
// NewProcess create a new process
func NewProcess(name string, p *Process) *Process {
if p == nil {
p = &Process{}
}
p.Name = name
return p
}
// SetHandler set the handler
func (p *Process) SetHandler(handler Handler) *Process {
p.Handler = handler
return p
}
// SetDefault set the default value
func (p *Process) SetDefault(defaults map[string]*Process) *Process {
if defaultProcess, has := defaults[p.Name]; has {
p.Name = defaultProcess.Name
if p.Process == "" {
p.Process = defaultProcess.Process
}
if p.Guard == "" {
p.Guard = defaultProcess.Guard
}
if p.Default == nil {
p.Default = defaultProcess.Default
}
// format defaults
if len(p.Default) != len(defaultProcess.Default) {
defauts := defaultProcess.Default
nums := len(p.Default)
if nums > len(defaultProcess.Default) {
nums = len(defaultProcess.Default)
}
for i := 0; i < nums; i++ {
defauts[i] = p.Default[i]
}
p.Default = defauts
}
}
return p
}
// WithBefore bind before hook
func (p *Process) WithBefore(before *hook.Before) *Process {
p.Before = before
return p
}
// WithAfter bind after hook
func (p *Process) WithAfter(after *hook.After) *Process {
p.After = after
return p
}
// Args get the process args
func (p *Process) Args(process *gou.Process) []interface{} {
process.ValidateArgNums(1)
args := p.Default
nums := len(process.Args[1:])
if nums > len(args) {
nums = len(args)
}
for i := 0; i < nums; i++ {
args[i] = p.deepMergeDefault(process.Args[i+1], args[i])
}
return args
}
// Exec exec the process
func (p *Process) Exec(process *gou.Process) (interface{}, error) {
if p.Handler == nil {
return nil, fmt.Errorf("%s handler does not set", p.Name)
}
return p.Handler(p, process)
}
// MustExec exec the process
func (p *Process) MustExec(process *gou.Process) interface{} {
res, err := p.Exec(process)
if err != nil {
exception.New(err.Error(), 500).Throw()
}
return res
}
// deepMergeDefault deep merge args
func (p *Process) deepMergeDefault(value interface{}, defaults interface{}) interface{} {
if value == nil {
return defaults
}
switch defaults.(type) {
case map[string]interface{}:
defaultMap := defaults.(map[string]interface{})
valueMap := any.Of(value).MapStr()
for key, v := range defaultMap {
valueMap[key] = p.deepMergeDefault(valueMap[key], v)
}
return valueMap
case []interface{}:
defaultArr := defaults.([]interface{})
valueArr := any.Of(value).CArray()
// pad
nums := len(defaultArr) - len(valueArr)
for i := 0; i < nums; i++ {
valueArr = append(valueArr, nil)
}
// set default
for idx, v := range defaultArr {
valueArr[idx] = p.deepMergeDefault(valueArr[idx], v)
}
return valueArr
}
return value
}