mirror of
https://shylinux.com/x/icebergs
synced 2025-04-25 17:18:05 +08:00
238 lines
5.3 KiB
Go
238 lines
5.3 KiB
Go
package ice
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
|
|
kit "shylinux.com/x/toolkits"
|
|
)
|
|
|
|
type MakeInfo struct {
|
|
Hash string
|
|
Time string
|
|
Path string
|
|
Module string
|
|
Domain string
|
|
Remote string
|
|
Branch string
|
|
Version string
|
|
Hostname string
|
|
Username string
|
|
Email string
|
|
}
|
|
|
|
var Info = struct {
|
|
Make MakeInfo
|
|
|
|
Hostname string
|
|
Pathname string
|
|
Username string
|
|
PidPath string
|
|
Colors bool
|
|
|
|
Domain string
|
|
NodeType string
|
|
NodeName string
|
|
Localhost bool
|
|
Important bool
|
|
|
|
File Maps
|
|
Gomod Maps
|
|
Route Maps
|
|
Index Map
|
|
Stack map[string]func(m *Message, key string, arg ...Any) Any
|
|
|
|
merges []Any
|
|
render map[string]func(*Message, ...Any) string
|
|
Load func(m *Message, key ...string) *Message
|
|
Save func(m *Message, key ...string) *Message
|
|
Log func(m *Message, p, l, s string)
|
|
}{
|
|
Localhost: true,
|
|
|
|
File: Maps{},
|
|
Gomod: Maps{},
|
|
Route: Maps{},
|
|
Index: Map{},
|
|
Stack: map[string]func(m *Message, key string, arg ...Any) Any{},
|
|
|
|
render: map[string]func(*Message, ...Any) string{},
|
|
Load: func(m *Message, key ...string) *Message { return m },
|
|
Save: func(m *Message, key ...string) *Message { return m },
|
|
Log: func(m *Message, p, l, s string) {},
|
|
}
|
|
|
|
func AddMergeAction(h ...Any) { Info.merges = append(Info.merges, h...) }
|
|
|
|
func MergeHand(hand ...Handler) Handler {
|
|
if len(hand) == 0 {
|
|
return nil
|
|
}
|
|
if len(hand) == 1 {
|
|
return hand[0]
|
|
}
|
|
return func(m *Message, arg ...string) {
|
|
for _, h := range hand {
|
|
if h != nil {
|
|
h(m, arg...)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
func MergeActions(arg ...Any) Actions {
|
|
if len(arg) == 0 {
|
|
return nil
|
|
}
|
|
list := arg[0].(Actions)
|
|
for _, from := range arg[1:] {
|
|
switch from := from.(type) {
|
|
case Actions:
|
|
for k, v := range from {
|
|
if h, ok := list[k]; !ok {
|
|
list[k] = v
|
|
} else if k == CTX_INIT {
|
|
h.Hand = MergeHand(v.Hand, h.Hand)
|
|
} else if k == CTX_EXIT {
|
|
h.Hand = MergeHand(h.Hand, v.Hand)
|
|
} else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil {
|
|
h.Hand = v.Hand
|
|
}
|
|
}
|
|
case string:
|
|
h := list[CTX_INIT]
|
|
if h == nil {
|
|
list[CTX_INIT] = &Action{}
|
|
h = list[CTX_INIT]
|
|
}
|
|
h.Hand = MergeHand(h.Hand, func(m *Message, arg ...string) {
|
|
m.Search(from, func(p *Context, s *Context, key string, cmd *Command) {
|
|
for k, v := range cmd.Actions {
|
|
func(k string) {
|
|
if h, ok := list[k]; !ok {
|
|
list[k] = &Action{Name: v.Name, Help: v.Help, Hand: func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }}
|
|
} else if h.Hand == nil {
|
|
h.Hand = func(m *Message, arg ...string) { m.Cmdy(from, k, arg) }
|
|
}
|
|
}(k)
|
|
}
|
|
})
|
|
})
|
|
default:
|
|
Pulse.ErrorNotImplement(from)
|
|
}
|
|
}
|
|
return list
|
|
}
|
|
func SplitCmd(name string, actions Actions) (list []Any) {
|
|
const (
|
|
TEXT = "text"
|
|
TEXTAREA = "textarea"
|
|
PASSWORD = "password"
|
|
SELECT = "select"
|
|
BUTTON = "button"
|
|
)
|
|
const (
|
|
RUN = "run"
|
|
REFRESH = "refresh"
|
|
LIST = "list"
|
|
BACK = "back"
|
|
AUTO = "auto"
|
|
PAGE = "page"
|
|
ARGS = "args"
|
|
CONTENT = "content"
|
|
)
|
|
item, button := kit.Dict(), false
|
|
push := func(arg ...string) {
|
|
button = kit.Select("", arg, 0) == BUTTON
|
|
item = kit.Dict(TYPE, kit.Select("", arg, 0), NAME, kit.Select("", arg, 1), ACTION, kit.Select("", arg, 2))
|
|
list = append(list, item)
|
|
}
|
|
ls := kit.Split(name, SP, "*:=@")
|
|
for i := 1; i < len(ls); i++ {
|
|
switch ls[i] {
|
|
case RUN:
|
|
push(BUTTON, ls[i])
|
|
case REFRESH:
|
|
push(BUTTON, ls[i], AUTO)
|
|
case LIST:
|
|
push(BUTTON, ls[i], AUTO)
|
|
case AUTO:
|
|
push(BUTTON, LIST, AUTO)
|
|
push(BUTTON, BACK)
|
|
case PAGE:
|
|
push(BUTTON, "prev")
|
|
push(BUTTON, "next")
|
|
push(TEXT, "offend")
|
|
push(TEXT, "limit")
|
|
case ARGS, CONTENT, TEXTAREA, TEXT:
|
|
push(TEXTAREA, ls[i])
|
|
case PASSWORD:
|
|
push(PASSWORD, ls[i])
|
|
case "*":
|
|
item["need"] = "must"
|
|
case DF:
|
|
if item[TYPE] = kit.Select("", ls, i+1); item[TYPE] == BUTTON {
|
|
button = true
|
|
}
|
|
i++
|
|
case EQ:
|
|
if value := kit.Select("", ls, i+1); strings.Contains(value, FS) {
|
|
vs := kit.Split(value)
|
|
if strings.Count(value, vs[0]) > 1 {
|
|
item["values"] = vs[1:]
|
|
} else {
|
|
item["values"] = vs
|
|
}
|
|
item[VALUE] = vs[0]
|
|
item[TYPE] = SELECT
|
|
} else {
|
|
item[VALUE] = value
|
|
}
|
|
i++
|
|
case AT:
|
|
item[ACTION] = kit.Select("", ls, i+1)
|
|
i++
|
|
default:
|
|
push(kit.Select(TEXT, BUTTON, button || actions != nil && actions[ls[i]] != nil), ls[i])
|
|
}
|
|
}
|
|
return list
|
|
}
|
|
func Module(prefix string, arg ...Any) {
|
|
list := map[string]Any{}
|
|
for _, v := range arg {
|
|
list[kit.FuncName(v)] = v
|
|
}
|
|
Info.Stack[prefix] = func(m *Message, key string, arg ...Any) Any {
|
|
if len(arg) > 0 {
|
|
switch v := arg[0].(type) {
|
|
case *Message:
|
|
m, arg = v, arg[1:]
|
|
}
|
|
}
|
|
if v, ok := list[key]; ok {
|
|
switch v := v.(type) {
|
|
case func(m *Message):
|
|
v(m)
|
|
case func(m *Message, arg ...Any):
|
|
v(m, arg...)
|
|
case func(m *Message, arg ...Any) string:
|
|
return v(m, arg...)
|
|
case func(m *Message, arg ...Any) *Message:
|
|
return v(m, arg...)
|
|
case func(m *Message, arg ...string) *Message:
|
|
return v(m, kit.Simple(arg...)...)
|
|
default:
|
|
cb, args := reflect.ValueOf(v), []reflect.Value{reflect.ValueOf(m)}
|
|
kit.For(arg, func(v Any) { args = append(args, reflect.ValueOf(v)) })
|
|
if res := cb.Call(args); len(res) > 0 && res[0].CanInterface() {
|
|
return res[0].Interface()
|
|
}
|
|
}
|
|
} else {
|
|
m.ErrorNotImplement(key)
|
|
}
|
|
return m
|
|
}
|
|
}
|