github.com/wfusion/gofusion@v1.1.14/common/infra/watermill/components/cqrs/marshaler_protobuf.go (about) 1 package cqrs 2 3 import ( 4 "reflect" 5 6 "github.com/pkg/errors" 7 "google.golang.org/protobuf/proto" 8 9 "github.com/wfusion/gofusion/common/infra/watermill/message" 10 "github.com/wfusion/gofusion/common/utils" 11 ) 12 13 // ProtobufMarshaler is the default Protocol Buffers marshaler. 14 type ProtobufMarshaler struct { 15 NewUUID func() string 16 GenerateName func(v any) string 17 } 18 19 // NoProtoMessageError is returned when the given value does not implement proto.Message. 20 type NoProtoMessageError struct { 21 v any 22 } 23 24 func (e NoProtoMessageError) Error() string { 25 rv := reflect.ValueOf(e.v) 26 if rv.Kind() != reflect.Ptr { 27 return "v is not proto.Message, you must pass pointer value to implement proto.Message" 28 } 29 30 return "v is not proto.Message" 31 } 32 33 // Marshal marshals the given protobuf's message into watermill's Message. 34 func (m ProtobufMarshaler) Marshal(v any) (*message.Message, error) { 35 protoMsg, ok := v.(proto.Message) 36 if !ok { 37 return nil, errors.WithStack(NoProtoMessageError{v}) 38 } 39 40 b, err := proto.Marshal(protoMsg) 41 if err != nil { 42 return nil, err 43 } 44 45 msg := message.NewMessage( 46 m.newUUID(), 47 b, 48 ) 49 msg.Metadata.Set("name", m.Name(v)) 50 51 return msg, nil 52 } 53 54 func (m ProtobufMarshaler) newUUID() string { 55 if m.NewUUID != nil { 56 return m.NewUUID() 57 } 58 59 // default 60 return utils.UUID() 61 } 62 63 // Unmarshal unmarshals given watermill's Message into protobuf's message. 64 func (ProtobufMarshaler) Unmarshal(msg *message.Message, v any) (err error) { 65 return proto.Unmarshal(msg.Payload, v.(proto.Message)) 66 } 67 68 // Name returns the command or event's name. 69 func (m ProtobufMarshaler) Name(cmdOrEvent any) string { 70 if m.GenerateName != nil { 71 return m.GenerateName(cmdOrEvent) 72 } 73 74 return FullyQualifiedStructName(cmdOrEvent) 75 } 76 77 // NameFromMessage returns the metadata name value for a given Message. 78 func (m ProtobufMarshaler) NameFromMessage(msg *message.Message) string { 79 return msg.Metadata.Get("name") 80 }