go-scopes/core/message/message.go

126 lines
2 KiB
Go

package message
import (
"encoding/json"
"strings"
lib "git.sr.ht/~cco/go-scopes"
"git.sr.ht/~cco/go-scopes/logging/log"
)
// message head
type head struct {
domain, action, class, item string
}
func (h *head) String() string {
return strings.Join(h.Slice(), "/")
}
func (h *head) Slice() []string {
return []string{h.domain, h.action, h.class, h.item}
}
func (h *head) Domain() string {
return h.domain
}
func (h *head) Action() string {
return h.action
}
func (h *head) Class() string {
return h.class
}
func (h *head) Item() string {
return h.item
}
// message
type message struct {
*head
sender lib.Address
payload lib.Payload
}
func (msg *message) Head() lib.MsgHead {
return msg
}
func (msg *message) Sender() lib.Address {
return msg.sender
}
func (msg *message) Payload() lib.Payload {
return msg.payload
}
func (msg *message) WithSender(s lib.Address) lib.Message {
msg.sender = s
return msg
}
func (msg *message) WithPayload(p lib.Payload) lib.Message {
msg.payload = p
return msg
}
func New(args ...string) lib.Message {
args = append(args, "", "")[:4]
domain := args[0]
if domain == "" {
domain = "scopes"
}
return &message{
head: &head{
domain: domain,
action: args[1],
class: args[2],
item: args[3],
},
}
}
func SimpleMessage(action string) lib.Message {
return New("scopes", action)
}
var Quit = SimpleMessage("quit")
// payload
type payload struct {
data interface{}
}
func (pl *payload) String() string {
b, err := json.Marshal(pl.data)
if err != nil {
log.Error().Err(err).Msg("payload.String()")
}
return string(b)
}
func (pl *payload) Data() interface{} {
return pl.data
}
func (pl *payload) FromJson(s string) lib.Payload {
err := json.Unmarshal([]byte(s), &pl.data)
if err != nil {
log.Error().Err(err).Msg("payload.FromJson()")
}
return pl
}
func Payload(d interface{}) lib.Payload {
return &payload{d}
}
func PayloadFromJson[T any](s string) lib.Payload {
pl := &payload{new(T)}
return pl.FromJson(s)
}