go-scopes/core/action/action.go

95 lines
1.7 KiB
Go

package action
import (
lib "git.sr.ht/~cco/go-scopes"
"git.sr.ht/~cco/go-scopes/core/message"
"git.sr.ht/~cco/go-scopes/logging"
)
type BaseSpec = baseSpec
type baseSpec struct {
handler lib.ActionHandler
receivers []string
}
func (spec *baseSpec) Handler() lib.ActionHandler {
return spec.handler
}
func (spec *baseSpec) Receivers() []string {
return spec.receivers
}
func Base(hdlr lib.ActionHandler, rcvrs ...string) *baseSpec {
return &baseSpec{hdlr, rcvrs}
}
// action selection
func Select(ctx lib.Context, msg lib.Message) []lib.Action {
var acts []lib.Action
for _, ac := range ctx.Config().Actions() {
if match(ac, msg) {
for _, spec := range ac.Specs() {
act := action{ctx, spec, msg}
logging.DebugA(&act).
Str("pattern", ac.Pattern().String()).
Msg("action.Select")
acts = append(acts, &act)
}
}
}
// if len(acts) == 0 { logging.Warn().... }
return acts
}
func match(ac lib.ActionConfig, msg lib.Message) bool {
pat := ac.Pattern().Slice()
if len(pat) == 1 {
return pat[0] == msg.Action()
}
mh := msg.Slice()
for idx, p := range pat {
if p != "" && mh[idx] != p {
return false
}
}
return true
}
// action handling
type action struct {
ctx lib.Context
spec lib.ActionSpec
msg lib.Message
}
func (act *action) Context() lib.Context {
return act.ctx
}
func (act *action) Spec() lib.ActionSpec {
return act.spec
}
func (act *action) Message() lib.Message {
return act.msg
}
func (act *action) Handle() bool {
return act.spec.Handler()(act)
}
// predefined action handlers
func Forward(act lib.Action) bool {
ctx := act.Context()
msg := act.Message()
for _, rcvr := range act.Spec().Receivers() {
addr := message.SimpleAddress(rcvr)
lib.Send(ctx, addr, msg)
}
return true
}