yao/widgets/component/action.go
2022-12-10 16:43:30 +08:00

133 lines
2.7 KiB
Go

package component
import (
"fmt"
"io"
"strings"
jsoniter "github.com/json-iterator/go"
"golang.org/x/crypto/md4"
)
// UnmarshalJSON for json UnmarshalJSON
func (action *ActionDSL) UnmarshalJSON(data []byte) error {
var alias aliasActionDSL
err := jsoniter.Unmarshal(data, &alias)
if err != nil {
return err
}
*action = ActionDSL(alias)
action.ID, err = action.Hash()
if err != nil {
return err
}
if action.Action == nil {
action.Action = ActionNodes{}
}
err = action.Action.Parse()
if err != nil {
return err
}
return nil
}
// UnmarshalJSON for json UnmarshalJSON
func (nodes *ActionNodes) UnmarshalJSON(data []byte) error {
var alias interface{}
err := jsoniter.Unmarshal(data, &alias)
if err != nil {
return err
}
switch values := alias.(type) {
case string: // "Actions.test.back"
*nodes = ActionNodes{{
"name": values,
"type": values,
"payload": map[string]interface{}{},
}}
return nil
case map[string]interface{}: // {"Form.delete": { "pathname": "/x/Table/env" }}
node := ActionNode{}
for name, payload := range values {
node["name"] = name
node["type"] = name
node["payload"] = payload
break
}
*nodes = ActionNodes{node}
return nil
case []interface{}, []map[string]interface{}: // [{ "name": "Save", "type": "Form.save", "payload": { "id": ":id", "status": "cured" }}]
new := aliasActionNodes{}
err := jsoniter.Unmarshal(data, &new)
if err != nil {
return err
}
*nodes = ActionNodes(new)
return nil
// case []ActionNode:
// *nodes = ActionNodes(values)
// return nil
// case ActionNodes:
// *nodes = values
// return nil
// case *ActionNodes:
// nodes = values
// return nil
}
return fmt.Errorf("the format does not support. %s", string(data))
}
// MarshalJSON for json MarshalJSON
// func (nodes ActionNodes) MarshalJSON() ([]byte, error) {
// return nil, nil
// }
// Parse the custom nodes
func (nodes *ActionNodes) Parse() error {
for i := range *nodes {
// merge the developer-defined actions
if (*nodes)[i].Custom() {
// (*nodes)[i]["custom"] = true
}
}
return nil
}
// Custom check if the action node is custom
func (node ActionNode) Custom() bool {
if name, ok := node["type"].(string); ok && strings.HasPrefix(strings.ToLower(name), "actions.") {
return true
}
return false
}
// Hash hash value
func (action ActionDSL) Hash() (string, error) {
h := md4.New()
origin := fmt.Sprintf("%#v", action.Action)
// fmt.Println(origin)
io.WriteString(h, origin)
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
// SetPath set actions xpath
func (actions Actions) SetPath(root string) Actions {
for i := range actions {
actions[i].Xpath = fmt.Sprintf("%s.%d", root, i)
}
return actions
}