github.com/clubpay/ronykit/kit@v0.14.4-0.20240515065620-d0dace45cbc7/message.go (about) 1 package kit 2 3 import ( 4 "mime/multipart" 5 6 "github.com/goccy/go-json" 7 "github.com/goccy/go-reflect" 8 ) 9 10 type ( 11 Marshaler interface { 12 Marshal() ([]byte, error) 13 } 14 Unmarshaler interface { 15 Unmarshal(data []byte) error 16 } 17 JSONMarshaler interface { 18 MarshalJSON() ([]byte, error) 19 } 20 JSONUnmarshaler interface { 21 UnmarshalJSON(data []byte) error 22 } 23 ProtoMarshaler interface { 24 MarshalProto() ([]byte, error) 25 } 26 ProtoUnmarshaler interface { 27 UnmarshalProto(data []byte) error 28 } 29 // Message is a generic interface for all messages. Message MUST BE serializable. 30 // It could implement one or many of the following interfaces: 31 // - Marshaler 32 // - Unmarshaler 33 // - JSONMarshaler 34 // - JSONUnmarshaler 35 // - ProtoMarshaler 36 // - ProtoUnmarshaler 37 // - encoding.BinaryMarshaler 38 // - encoding.BinaryUnmarshaler 39 // - encoding.TextMarshaler 40 // - encoding.TextUnmarshaler 41 Message any 42 MessageFactoryFunc func() Message 43 ) 44 45 func CreateMessageFactory(in Message) MessageFactoryFunc { 46 switch { 47 case in == nil: 48 fallthrough 49 case reflect.Indirect(reflect.ValueOf(in)).Type() == reflect.TypeOf(RawMessage{}): 50 return func() Message { 51 return RawMessage{} 52 } 53 case reflect.Indirect(reflect.ValueOf(in)).Type() == reflect.TypeOf(MultipartFormMessage{}): 54 return func() Message { 55 return MultipartFormMessage{} 56 } 57 } 58 59 var ff MessageFactoryFunc 60 61 reflect.ValueOf(&ff).Elem().Set( 62 reflect.MakeFunc( 63 reflect.TypeOf(ff), 64 func(args []reflect.Value) (results []reflect.Value) { 65 return []reflect.Value{reflect.New(reflect.TypeOf(in).Elem())} 66 }, 67 ), 68 ) 69 70 return ff 71 } 72 73 type MessageCodec interface { 74 Marshal(m any) ([]byte, error) 75 Unmarshal(data []byte, m any) error 76 } 77 78 type stdCodec struct{} 79 80 func (jm stdCodec) Marshal(m any) ([]byte, error) { 81 return json.MarshalNoEscape(m) 82 } 83 84 func (jm stdCodec) Unmarshal(data []byte, m any) error { 85 return json.UnmarshalNoEscape(data, m) 86 } 87 88 func SetCustomCodec(mm MessageCodec) { 89 defaultMessageCodec = mm 90 } 91 92 func GetMessageCodec() MessageCodec { 93 return defaultMessageCodec 94 } 95 96 var defaultMessageCodec MessageCodec = stdCodec{} 97 98 func UnmarshalMessage(data []byte, m Message) error { 99 return defaultMessageCodec.Unmarshal(data, m) 100 } 101 102 func MarshalMessage(m Message) ([]byte, error) { 103 switch v := m.(type) { 104 case RawMessage: 105 return v, nil 106 default: 107 return defaultMessageCodec.Marshal(m) 108 } 109 } 110 111 // RawMessage is a byte slice which could be used as a Message. 112 // This is helpful for raw data messages. 113 // Example: 114 // 115 // SetInput(kit.RawMessage) 116 type RawMessage []byte 117 118 func (rm RawMessage) Marshal() ([]byte, error) { 119 return rm, nil 120 } 121 122 func (rm RawMessage) MarshalJSON() ([]byte, error) { 123 return rm, nil 124 } 125 126 func (rm *RawMessage) CopyFrom(in []byte) { 127 *rm = append(*rm, in...) 128 } 129 130 func (rm *RawMessage) CopyTo(out []byte) { 131 copy(out, *rm) 132 } 133 134 // Clone copies the underlying byte slice into dst. It is SAFE to 135 // pass nil for dst. 136 func (rm *RawMessage) Clone(dst []byte) []byte { 137 dst = append(dst, *rm...) 138 139 return dst 140 } 141 142 func (rm *RawMessage) Unmarshal(data []byte) error { 143 *rm = append(*rm, data...) 144 145 return nil 146 } 147 148 func (rm *RawMessage) UnmarshalJSON(data []byte) error { 149 *rm = append(*rm, data...) 150 151 return nil 152 } 153 154 func CastRawMessage[M Message](rawMsg RawMessage) (*M, error) { 155 var m M 156 err := UnmarshalMessage(rawMsg, &m) 157 if err != nil { 158 return nil, err 159 } 160 161 return &m, nil 162 } 163 164 // ErrorMessage is a special kind of Message which is also an error. 165 type ErrorMessage interface { 166 GetCode() int 167 GetItem() string 168 Message 169 error 170 } 171 172 // EmptyMessage is a special kind of Message which is empty. 173 type EmptyMessage struct{} 174 175 type JSONMessage = json.RawMessage 176 177 // MultipartFormMessage is a message type for multipart form data. 178 // This is like RawMessage a special kind of message. When you define 179 // them in Descriptor, your MUST NOT pass address of them like normal 180 // messages. 181 // Example: 182 // 183 // SetInput(kit.MultipartFormMessage) 184 type MultipartFormMessage struct { 185 frm *multipart.Form 186 } 187 188 func (mfm *MultipartFormMessage) SetForm(frm *multipart.Form) { 189 mfm.frm = frm 190 } 191 192 func (mfm *MultipartFormMessage) GetForm() *multipart.Form { 193 return mfm.frm 194 }