1
0
forked from x/icebergs
This commit is contained in:
shaoying 2020-10-10 00:03:57 +08:00
parent 133eff9527
commit 15a24e892f
11 changed files with 83 additions and 152 deletions

View File

@ -68,7 +68,6 @@ var Index = &ice.Context{Name: "log", Help: "日志模块",
ice.LOG_INSERT, ice.LOG_DELETE,
ice.LOG_SELECT, ice.LOG_MODIFY,
ice.LOG_EXPORT, ice.LOG_IMPORT,
ice.LOG_ENABLE,
}),
"bench", kit.Dict("path", "var/log/bench.log", "list", []string{}),
"error", kit.Dict("path", "var/log/error.log", "list", []string{

View File

@ -18,8 +18,6 @@ import (
)
func Render(msg *ice.Message, cmd string, args ...interface{}) {
defer func() { msg.Log_EXPORT(mdb.RENDER, cmd, kit.Simple(args...)) }()
switch arg := kit.Simple(args...); cmd {
case ice.RENDER_VOID:
case ice.RENDER_RESULT:
@ -196,7 +194,7 @@ func (f *Frame) parse(m *ice.Message, line string) string {
async, one = true, strings.TrimSuffix(one, "&")
}
msg := m.Spawns(f.target)
msg := m.Spawn(f.target)
msg.Option("_cmd", one)
ls := kit.Split(one)
@ -234,15 +232,17 @@ func (f *Frame) scan(m *ice.Message, h, line string, r io.Reader) *Frame {
m.I, m.O = r, f.stdout
bio := bufio.NewScanner(r)
for f.prompt(m, ps...); bio.Scan() && !f.exit; f.prompt(m, ps...) {
if h == STDIO && len(bio.Text()) == 0 {
continue // 空行
}
m.Cmdx(mdb.INSERT, SOURCE, kit.Keys(kit.MDB_HASH, h), mdb.LIST, kit.MDB_TEXT, bio.Text())
f.count++
if len(bio.Text()) == 0 {
if h == STDIO {
f.count--
}
continue // 空行
}
if strings.HasSuffix(bio.Text(), "\\") {
line += bio.Text()[:len(bio.Text())-1]
ps = f.ps2

View File

@ -55,7 +55,7 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
m.Log_CREATE(SPACE, dev, "retry", i, "uri", uri)
// 连接成功
m = m.Spawns()
m = m.Spawn()
if i = 0; _space_handle(m, true, web.send, s, dev) {
i = -1 // 连接关闭
}
@ -136,7 +136,7 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w
// 解析失败
break
} else {
socket, msg := c, m.Spawns(b)
socket, msg := c, m.Spawn(b)
target := kit.Simple(msg.Optionv(ice.MSG_TARGET))
source := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name)
msg.Log("recv", "%v<-%v %s %v", target, source, msg.Detailv(), msg.Format("meta"))

View File

@ -42,7 +42,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
w.ServeMux = http.NewServeMux()
// 静态路由
msg := m.Spawns(s)
msg := m.Spawn(s)
m.Confm(SERVE, "meta.static", func(key string, value string) {
m.Log("route", "%s <- %s <- %s", s.Name, key, value)
w.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
@ -60,7 +60,7 @@ func (web *Frame) Start(m *ice.Message, arg ...string) bool {
if s == sub && k[0] == '/' {
msg.Log("route", "%s <- %s", s.Name, k)
w.HandleFunc(k, func(w http.ResponseWriter, r *http.Request) {
m.TryCatch(msg.Spawns(), true, func(msg *ice.Message) {
m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) {
_serve_handle(k, x, msg, w, r)
})
})

22
conf.go
View File

@ -48,17 +48,17 @@ const ( // MSG
MSG_METHOD = "sess.method"
)
const ( // CTX
CTX_STREAM = "stream"
CTX_STATUS = "status"
CTX_FOLLOW = "follow"
CTX_INIT = "_init"
CTX_EXIT = "_exit"
CTX_STATUS = "status"
CTX_STREAM = "stream"
CTX_BEGIN = "begin"
CTX_START = "start"
CTX_SERVE = "serve"
CTX_CLOSE = "close"
CTX_INIT = "_init"
CTX_EXIT = "_exit"
)
const ( // LOG
// 数据
@ -71,16 +71,6 @@ const ( // LOG
LOG_SELECT = "select"
LOG_MODIFY = "modify"
// 事件
LOG_ENABLE = "enable"
LOG_STATUS = "status"
LOG_LISTEN = "listen"
LOG_ACCEPT = "accept"
LOG_FINISH = "finish"
LOG_SIGNAL = "signal"
LOG_TIMERS = "timers"
LOG_EVENTS = "events"
// 状态
LOG_BEGIN = "begin"
LOG_START = "start"
@ -88,14 +78,12 @@ const ( // LOG
LOG_CLOSE = "close"
// 分类
LOG_CONF = "conf"
LOG_CMDS = "cmds"
LOG_AUTH = "auth"
LOG_COST = "cost"
LOG_INFO = "info"
LOG_WARN = "warn"
LOG_ERROR = "error"
LOG_TRACE = "trace"
LOG_DEBUG = "debug"
)
const ( // RENDER

View File

@ -2,13 +2,12 @@ package ice
import (
kit "github.com/shylinux/toolkits"
"github.com/shylinux/toolkits/task"
"errors"
"fmt"
"io"
"time"
"github.com/shylinux/toolkits/task"
)
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
@ -63,7 +62,6 @@ func (m *Message) Hold(n int) *Message {
}
ctx.wg.Add(n)
m.Log(LOG_TRACE, "%s wait %s %v", ctx.Name, m.target.Name, ctx.wg)
return m
}
func (m *Message) Done(b bool) bool {
@ -77,7 +75,6 @@ func (m *Message) Done(b bool) bool {
ctx = c.context
}
m.Log(LOG_TRACE, "%s done %s %v", ctx.Name, m.target.Name, ctx.wg)
ctx.wg.Done()
return true
}

6
go.sum
View File

@ -4,10 +4,9 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/maruel/rs v0.0.0-20150922171536-2c81c4312fe4/go.mod h1:kcRFpEzolcEklV6rD7W95mG49/sbdX/PlFmd7ni3RvA=
github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369 h1:Yp0zFEufLz0H7jzffb4UPXijavlyqlYeOg7dcyVUNnQ=
github.com/nareix/joy4 v0.0.0-20200507095837-05a4ffbb5369/go.mod h1:aFJ1ZwLjvHN4yEzE5Bkz8rD8/d8Vlj3UIuvz2yfET7I=
github.com/shylinux/toolkits v0.1.8 h1:Lh5HkR1aRzhOOVu9eHwZ5y7dfW7hcFy29IR5tQ5qUeM=
github.com/shylinux/toolkits v0.1.8/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g=
github.com/shylinux/toolkits v0.1.9 h1:gfQnXSBBuCtUueNF5eL0kZAjJS8pzODrjxIL0WynqsQ=
github.com/shylinux/toolkits v0.1.9/go.mod h1:Y68Ot6xOmo1bun67YvqC3chDGeU2gDxtsUnvVDGJm4g=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2/go.mod h1:lPnW9HVS0vJdeYyQtOvIvlXgZPNhUAhwz+z5r8AJk0Y=
@ -16,5 +15,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

26
init.go
View File

@ -1,8 +1,6 @@
package ice
import (
"encoding/json"
kit "github.com/shylinux/toolkits"
"os"
@ -40,7 +38,7 @@ func (f *Frame) Begin(m *Message, arg ...string) Server {
m.Travel(func(p *Context, s *Context) {
s.root = m.target
if msg, ok := list[p]; ok && msg != nil {
list[s] = msg.Spawns(s)
list[s] = msg.Spawn(s)
s.Begin(list[s], arg...)
}
})
@ -67,7 +65,7 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
list := map[*Context]*Message{m.target: m}
m.Travel(func(p *Context, s *Context) {
if msg, ok := list[p]; ok && msg != nil {
list[s] = msg.Spawns(s)
list[s] = msg.Spawn(s)
s.Close(list[s], arg...)
}
})
@ -98,7 +96,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
defer m.Cost("_init ice")
m.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[CTX_INIT]; ok && p != nil {
c.cmd(m.Spawns(c), cmd, CTX_INIT, arg...)
c.cmd(m.Spawn(c), cmd, CTX_INIT, arg...)
}
})
}},
@ -123,7 +121,7 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
defer m.Cost(CTX_EXIT)
m.root.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[CTX_EXIT]; ok && p != nil {
m.TryCatch(m.Spawns(c), true, func(msg *Message) {
m.TryCatch(m.Spawn(c), true, func(msg *Message) {
c.cmd(msg, cmd, CTX_EXIT, arg...)
})
}
@ -141,16 +139,6 @@ var Pulse = &Message{
}
var wait = make(chan bool, 1)
func Init(file string) {
if f, e := os.Open(file); e == nil {
defer f.Close()
var data interface{}
json.NewDecoder(f).Decode(&data)
kit.Fetch(data, func(key string, value string) { Pulse.Option(key, value) })
}
}
func Run(arg ...string) string {
if len(arg) == 0 {
arg = os.Args[1:]
@ -168,8 +156,8 @@ func Run(arg ...string) string {
Pulse.Option("begin_time", Pulse.Time())
switch kit.Select("", arg, 0) {
case "space", "serve":
if _log_disable = false; frame.Begin(Pulse.Spawns(), arg...).Start(Pulse, arg...) {
frame.Close(Pulse.Spawns(), arg...)
if _log_disable = false; frame.Begin(Pulse.Spawn(), arg...).Start(Pulse, arg...) {
frame.Close(Pulse.Spawn(), arg...)
}
<-wait
@ -199,7 +187,7 @@ func Name(name string, value interface{}) string {
case *Context:
last = s.Name
}
panic(NewError(1, ErrNameExists, name, "last: ", last))
panic(kit.Format("name already exits: %s %v", name, last))
}
names[name] = value

14
logs.go
View File

@ -14,18 +14,6 @@ var ErrNotLogin = "not login: "
var ErrNotAuth = "not auth: "
var ErrNotJoin = "not join: "
type Error struct {
Arg []interface{}
FileLine string
}
func (e *Error) Error() string {
return e.FileLine + " " + strings.Join(kit.Simple(e.Arg), " ")
}
func NewError(n int, arg ...interface{}) *Error {
return &Error{Arg: arg, FileLine: kit.FileLine(n+3, 3)}
}
var _log_disable = true
var Log func(m *Message, p, l, s string)
@ -43,8 +31,6 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
switch level {
case LOG_IMPORT, LOG_CREATE, LOG_INSERT, LOG_MODIFY, LOG_EXPORT:
prefix, suffix = "\033[36;44m", "\033[0m"
case LOG_ENABLE, LOG_LISTEN, LOG_SIGNAL, LOG_TIMERS, LOG_EVENTS:
prefix, suffix = "\033[33m", "\033[0m"
case LOG_CMDS, LOG_START, LOG_SERVE:
prefix, suffix = "\033[32m", "\033[0m"

18
misc.go
View File

@ -54,6 +54,12 @@ func (m *Message) Space(arg interface{}) []string {
return []string{"web.space", kit.Format(arg)}
}
func (m *Message) PushPlugin(key string, arg ...string) *Message {
m.Option("_process", "_field")
m.Option("_prefix", arg)
m.Cmdy("command", key)
return m
}
func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
if m.Option(MSG_USERUA) == "" {
return m
@ -82,6 +88,9 @@ func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
}
return m
}
func (m *Message) PushButton(key string, arg ...string) {
m.PushRender("action", "button", key, arg...)
}
func (m *Message) PushAction(list ...interface{}) {
if len(m.meta[MSG_APPEND]) > 0 && m.meta[MSG_APPEND][0] == kit.MDB_KEY {
m.Push(kit.MDB_KEY, kit.MDB_ACTION)
@ -92,15 +101,6 @@ func (m *Message) PushAction(list ...interface{}) {
m.PushRender(kit.MDB_ACTION, kit.MDB_BUTTON, strings.Join(kit.Simple(list...), ","))
})
}
func (m *Message) PushButton(key string, arg ...string) {
m.PushRender("action", "button", key, arg...)
}
func (m *Message) PushPlugin(key string, arg ...string) *Message {
m.Option("_process", "_field")
m.Option("_prefix", arg)
m.Cmdy("command", key)
return m
}
var count = int32(0)

123
type.go
View File

@ -36,7 +36,7 @@ type Action struct {
}
type Command struct {
Name string
Help interface{} // string []string
Help string
List []interface{}
Meta map[string]interface{}
Hand func(m *Message, c *Context, key string, arg ...string)
@ -44,8 +44,7 @@ type Command struct {
}
type Context struct {
Name string
Help interface{} // string []string
Test interface{} // string []string
Help string
Caches map[string]*Cache
Configs map[string]*Config
@ -108,11 +107,11 @@ func (c *Context) _hand(m *Message, cmd *Command, key string, k string, h *Actio
return m
}
func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Message {
if m.meta[MSG_DETAIL] = kit.Simple(key, arg); cmd == nil {
if m.cmd = cmd; cmd == nil {
return m
}
m.cmd = cmd
m.meta[MSG_DETAIL] = kit.Simple(key, arg)
if m.Hand = true; len(arg) > 1 && arg[0] == "action" && cmd.Action != nil {
if h, ok := cmd.Action[arg[1]]; ok {
return c._hand(m, cmd, key, arg[1], h, arg[2:]...)
@ -134,11 +133,8 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess
}
}
if m.target.Name == "mdb" {
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg, kit.FileLine(8, 3))
} else {
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg, kit.FileLine(cmd.Hand, 3))
}
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg,
kit.Select(kit.FileLine(cmd.Hand, 3), kit.FileLine(8, 3), m.target.Name == "mdb"))
cmd.Hand(m, c, key, arg...)
return m
}
@ -158,11 +154,10 @@ func (c *Context) Register(s *Context, x Server, name ...string) *Context {
}
s.Merge(s, x)
// Pulse.Log("register", "%s <- %s", c.Name, s.Name)
if c.contexts == nil {
c.contexts = map[string]*Context{}
}
c.contexts[kit.Format(s.Name)] = s
c.contexts[s.Name] = s
s.root = c.root
s.context = c
s.server = x
@ -172,12 +167,6 @@ func (c *Context) Merge(s *Context, x Server) *Context {
if c.Commands == nil {
c.Commands = map[string]*Command{}
}
if c.Configs == nil {
c.Configs = map[string]*Config{}
}
if c.Caches == nil {
c.Caches = map[string]*Cache{}
}
for k, v := range s.Commands {
c.Commands[k] = v
if v.List == nil {
@ -198,12 +187,21 @@ func (c *Context) Merge(s *Context, x Server) *Context {
}
}
}
if c.Configs == nil {
c.Configs = map[string]*Config{}
}
for k, v := range s.Configs {
c.Configs[k] = v
}
if c.Caches == nil {
c.Caches = map[string]*Cache{}
}
for k, v := range s.Caches {
c.Caches[k] = v
}
s.server = x
return c
}
@ -266,18 +264,9 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co
return s
}
func (c *Context) Begin(m *Message, arg ...string) *Context {
if c.Caches == nil {
c.Caches = map[string]*Cache{}
}
if c.Configs == nil {
c.Configs = map[string]*Config{}
}
if c.Commands == nil {
c.Commands = map[string]*Command{}
}
c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
if c.context == Index {
c.Cap(CTX_FOLLOW, c.Name)
@ -288,36 +277,27 @@ func (c *Context) Begin(m *Message, arg ...string) *Context {
c.Cap(CTX_STATUS, CTX_BEGIN)
if c.begin = m; c.server != nil {
m.TryCatch(m, true, func(m *Message) {
// 初始化模块
c.server.Begin(m, arg...)
})
c.server.Begin(m, arg...)
}
return c
}
func (c *Context) Start(m *Message, arg ...string) bool {
c.start = m
m.Hold(1)
wait := make(chan bool)
var p interface{}
if c.server != nil {
p = c.server.Start
}
m.Hold(1)
m.Go(func() {
m.Log(LOG_START, c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_START)
c.start = m
// 启动模块
if wait <- true; c.server != nil {
c.server.Start(m, arg...)
}
if m.Done(true); m.wait != nil {
m.wait <- true
}
}, p)
})
<-wait
return true
}
@ -326,7 +306,6 @@ func (c *Context) Close(m *Message, arg ...string) bool {
c.Cap(CTX_STATUS, CTX_CLOSE)
if c.server != nil {
// 结束模块
return c.server.Close(m, arg...)
}
return true
@ -372,8 +351,7 @@ func (m *Message) Time(args ...interface{}) string {
if len(args) > 0 {
switch arg := args[0].(type) {
case string:
f = arg
if len(args) > 1 {
if f = arg; len(args) > 1 {
// 时间格式
f = fmt.Sprintf(f, args[1:]...)
}
@ -389,6 +367,8 @@ func (m *Message) Source() *Context {
}
func (m *Message) Format(key interface{}) string {
switch key := key.(type) {
case []byte:
json.Unmarshal(key, &m.meta)
case string:
switch key {
case "cost":
@ -467,8 +447,6 @@ func (m *Message) Format(key interface{}) string {
}
return strings.Join(meta, "")
}
case []byte:
json.Unmarshal(key, &m.meta)
}
return m.time.Format(MOD_TIME)
}
@ -479,15 +457,10 @@ func (m *Message) Formats(key string) string {
}
return m.Format(key)
}
func (m *Message) Spawns(arg ...interface{}) *Message {
msg := m.Spawn(arg...)
msg.code = int(m.target.root.ID())
// m.messages = append(m.messages, msg)
return msg
}
func (m *Message) Spawn(arg ...interface{}) *Message {
msg := &Message{
code: -1, time: time.Now(),
time: time.Now(),
code: int(m.target.root.ID()),
meta: map[string][]string{},
data: map[string]interface{}{},
@ -503,19 +476,17 @@ func (m *Message) Spawn(arg ...interface{}) *Message {
if len(arg) > 0 {
switch val := arg[0].(type) {
case *Context:
msg.target = val
case []byte:
json.Unmarshal(val, &msg.meta)
case *Context:
msg.target = val
}
}
return msg
}
func (m *Message) Start(key string, arg ...string) *Message {
m.Travel(func(p *Context, s *Context) {
if s.Name == key {
s.Start(m.Spawns(s), arg...)
}
m.Search(key+".", func(p *Context, s *Context) {
s.Start(m.Spawn(s), arg...)
})
return m
}
@ -648,17 +619,13 @@ func (m *Message) Search(key interface{}, cb interface{}) *Message {
}
case func(p *Context, s *Context, key string):
cb(p.context, p, key)
case func(p *Context, s *Context):
cb(p.context, p)
}
}
return m
}
func (m *Message) Cmdy(arg ...interface{}) *Message {
return m.Copy(m.__cmd(arg...))
}
func (m *Message) Cmdx(arg ...interface{}) string {
return kit.Select("", m.__cmd(arg...).meta[MSG_RESULT], 0)
}
func (m *Message) __cmd(arg ...interface{}) *Message {
list := kit.Simple(arg...)
if len(list) == 0 && m.Hand == false {
@ -669,7 +636,7 @@ func (m *Message) __cmd(arg ...interface{}) *Message {
}
m.Search(list[0], func(p *Context, s *Context, key string, cmd *Command) {
m.TryCatch(m.Spawns(s), true, func(msg *Message) {
m.TryCatch(m.Spawn(s), true, func(msg *Message) {
m = s.cmd(msg, cmd, key, list[1:]...)
})
})
@ -679,20 +646,18 @@ func (m *Message) __cmd(arg ...interface{}) *Message {
}
return m
}
func (m *Message) Cmdy(arg ...interface{}) *Message {
return m.Copy(m.__cmd(arg...))
}
func (m *Message) Cmdx(arg ...interface{}) string {
return kit.Select("", m.__cmd(arg...).meta[MSG_RESULT], 0)
}
func (m *Message) Cmds(arg ...interface{}) *Message {
return m.Go(func() { m.__cmd(arg...) })
}
func (m *Message) Cmd(arg ...interface{}) *Message {
return m.__cmd(arg...)
}
func (m *Message) Confm(key string, chain interface{}, cbs ...interface{}) map[string]interface{} {
val := m.Confv(key, chain)
if len(cbs) > 0 {
kit.Fetch(val, cbs[0])
}
value, _ := val.(map[string]interface{})
return value
}
func (m *Message) Confv(arg ...interface{}) (val interface{}) {
m.Search(arg[0], func(p *Context, s *Context, key string, conf *Config) {
if len(arg) == 1 {
@ -714,6 +679,14 @@ func (m *Message) Confv(arg ...interface{}) (val interface{}) {
})
return
}
func (m *Message) Confm(key string, chain interface{}, cbs ...interface{}) map[string]interface{} {
val := m.Confv(key, chain)
if len(cbs) > 0 {
kit.Fetch(val, cbs[0])
}
value, _ := val.(map[string]interface{})
return value
}
func (m *Message) Conf(arg ...interface{}) string {
return kit.Format(m.Confv(arg...))
}