Files
upstream-watermill/components/cqrs/marshaler.go
2026-09-15 21:27:46 +05:00

56 lines
1.8 KiB
Go

package cqrs
import (
"errors"
"fmt"
"github.com/ThreeDotsLabs/watermill/message"
)
// CommandEventMarshaler marshals Commands and Events to Watermill's messages and vice versa.
// Payload of the command needs to be marshaled to []bytes.
type CommandEventMarshaler interface {
// Marshal marshals Command or Event to Watermill's message.
Marshal(v interface{}) (*message.Message, error)
// Unmarshal unmarshals watermill's message to v Command or Event.
Unmarshal(msg *message.Message, v interface{}) (err error)
// Name returns the name of Command or Event.
// Name is used to determine, that received command or event is event which we want to handle.
Name(v interface{}) string
// NameFromMessage returns the name of Command or Event from Watermill's message (generated by Marshal).
//
// When we have Command or Event marshaled to Watermill's message,
// we should use NameFromMessage instead of Name to avoid unnecessary unmarshaling.
NameFromMessage(msg *message.Message) string
}
// CommandEventMarshalerDecorator decorates CommandEventMarshaler with additional functionality.
// It can be used to add additional metadata to the message.
type CommandEventMarshalerDecorator struct {
CommandEventMarshaler
// DecorateFunc is called after marshaling the message.
DecorateFunc func(v any, msg *message.Message) error
}
// Marshal marshals Command or Event to Watermill's message and decorates it.
func (c CommandEventMarshalerDecorator) Marshal(v any) (*message.Message, error) {
msg, err := c.CommandEventMarshaler.Marshal(v)
if err != nil {
return nil, err
}
if c.DecorateFunc == nil {
return nil, errors.New("DecorateFunc is nil")
}
if err := c.DecorateFunc(v, msg); err != nil {
return nil, fmt.Errorf("cannot decorate message: %w", err)
}
return msg, nil
}