github.com/ronaksoft/rony@v0.16.26-0.20230807065236-1743dbfe6959/registry/registry.go (about) 1 package registry 2 3 import ( 4 "fmt" 5 6 "github.com/goccy/go-json" 7 "google.golang.org/protobuf/encoding/protojson" 8 "google.golang.org/protobuf/proto" 9 ) 10 11 /* 12 Creation Time: 2020 - Aug - 27 13 Created by: (ehsan) 14 Maintainers: 15 1. Ehsan N. Moosa (E2) 16 Auditor: Ehsan N. Moosa (E2) 17 Copyright Ronak Software Group 2020 18 */ 19 20 // Message defines the behavior of messages in Rony. They must be able to 21 // encode/decode ProtocolBuffer and JSON formats. 22 type Message interface { 23 proto.Message 24 json.Marshaler 25 json.Unmarshaler 26 } 27 28 type Envelope interface { 29 GetConstructor() uint64 30 GetMessage() []byte 31 } 32 33 type Factory func() Message 34 35 var ( 36 constructors = map[uint64]string{} 37 constructorNames = map[string]uint64{} 38 factories = map[uint64]Factory{} 39 ) 40 41 func Register(c uint64, n string, f Factory) { 42 if old, ok := constructors[c]; ok { 43 panic(fmt.Sprintf("constructor already exists %s:%s", old, n)) 44 } else { 45 constructors[c] = n 46 constructorNames[n] = c 47 } 48 if f != nil { 49 factories[c] = f 50 } 51 } 52 53 func Get(c uint64) (Message, error) { 54 f := factories[c] 55 if f == nil { 56 return nil, errFactoryNotExists 57 } 58 59 return f(), nil 60 } 61 62 func Unwrap(envelope Envelope) (Message, error) { 63 m, err := Get(envelope.GetConstructor()) 64 if err != nil { 65 return nil, err 66 } 67 68 err = proto.UnmarshalOptions{Merge: true}.Unmarshal(envelope.GetMessage(), m) 69 70 if err != nil { 71 return nil, err 72 } 73 74 return m, nil 75 } 76 77 func UnwrapJSON(envelope Envelope) (Message, error) { 78 m, err := Get(envelope.GetConstructor()) 79 if err != nil { 80 return nil, err 81 } 82 83 err = protojson.Unmarshal(envelope.GetMessage(), m) 84 85 if err != nil { 86 return nil, err 87 } 88 89 return m, nil 90 } 91 92 func ConstructorName(c uint64) string { 93 return constructors[c] 94 } 95 96 func C(c uint64) string { 97 return constructors[c] 98 } 99 100 func ConstructorNumber(n string) uint64 { 101 return constructorNames[n] 102 } 103 104 func N(n string) uint64 { 105 return constructorNames[n] 106 } 107 108 type JSONEnvelope struct { 109 RequestID uint64 `json:"requestId,omitempty"` 110 Header map[string]string `json:"header,omitempty"` 111 Constructor string `json:"constructor"` 112 Message json.RawMessage `json:"message,omitempty"` 113 } 114 115 var ( 116 errFactoryNotExists = fmt.Errorf("factory not exists") 117 )