github.com/RevenueMonster/sqlike@v1.0.6/jsonb/registry.go (about) 1 package jsonb 2 3 import ( 4 "encoding" 5 "encoding/json" 6 "reflect" 7 "sync" 8 "time" 9 10 "github.com/RevenueMonster/sqlike/reflext" 11 "golang.org/x/text/currency" 12 "golang.org/x/text/language" 13 ) 14 15 var ( 16 registry = buildDefaultRegistry() 17 18 jsonbUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem() 19 jsonUnmarshaler = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() 20 textUnmarshaler = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() 21 textMarshaler = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 22 ) 23 24 // ValueDecoder : 25 type ValueDecoder func(*Reader, reflect.Value) error 26 27 // ValueEncoder : 28 type ValueEncoder func(*Writer, reflect.Value) error 29 30 // Registry : 31 type Registry struct { 32 mutex *sync.Mutex 33 typeEncoders map[reflect.Type]ValueEncoder 34 typeDecoders map[reflect.Type]ValueDecoder 35 kindEncoders map[reflect.Kind]ValueEncoder 36 kindDecoders map[reflect.Kind]ValueDecoder 37 } 38 39 func buildDefaultRegistry() *Registry { 40 rg := NewRegistry() 41 enc := DefaultEncoder{rg} 42 dec := DefaultDecoder{rg} 43 rg.SetTypeCoder(reflect.TypeOf([]byte{}), enc.EncodeByte, dec.DecodeByte) 44 rg.SetTypeCoder(reflect.TypeOf(language.Tag{}), enc.EncodeStringer, dec.DecodeLanguage) 45 rg.SetTypeCoder(reflect.TypeOf(currency.Unit{}), enc.EncodeStringer, dec.DecodeCurrency) 46 rg.SetTypeCoder(reflect.TypeOf(time.Time{}), enc.EncodeTime, dec.DecodeTime) 47 rg.SetTypeCoder(reflect.TypeOf(json.RawMessage{}), enc.EncodeJSONRaw, dec.DecodeJSONRaw) 48 rg.SetTypeCoder(reflect.TypeOf(json.Number("")), enc.EncodeStringer, dec.DecodeJSONNumber) 49 rg.SetKindCoder(reflect.String, enc.EncodeString, dec.DecodeString) 50 rg.SetKindCoder(reflect.Bool, enc.EncodeBool, dec.DecodeBool) 51 rg.SetKindCoder(reflect.Int, enc.EncodeInt, dec.DecodeInt(false)) 52 rg.SetKindCoder(reflect.Int8, enc.EncodeInt, dec.DecodeInt(false)) 53 rg.SetKindCoder(reflect.Int16, enc.EncodeInt, dec.DecodeInt(false)) 54 rg.SetKindCoder(reflect.Int32, enc.EncodeInt, dec.DecodeInt(false)) 55 rg.SetKindCoder(reflect.Int64, enc.EncodeInt, dec.DecodeInt(false)) 56 rg.SetKindCoder(reflect.Uint, enc.EncodeUint, dec.DecodeUint(false)) 57 rg.SetKindCoder(reflect.Uint8, enc.EncodeUint, dec.DecodeUint(false)) 58 rg.SetKindCoder(reflect.Uint16, enc.EncodeUint, dec.DecodeUint(false)) 59 rg.SetKindCoder(reflect.Uint32, enc.EncodeUint, dec.DecodeUint(false)) 60 rg.SetKindCoder(reflect.Uint64, enc.EncodeUint, dec.DecodeUint(false)) 61 rg.SetKindCoder(reflect.Float32, enc.EncodeFloat, dec.DecodeFloat) 62 rg.SetKindCoder(reflect.Float64, enc.EncodeFloat, dec.DecodeFloat) 63 rg.SetKindCoder(reflect.Ptr, enc.EncodePtr, dec.DecodePtr) 64 rg.SetKindCoder(reflect.Struct, enc.EncodeStruct, dec.DecodeStruct) 65 rg.SetKindCoder(reflect.Array, enc.EncodeArray, dec.DecodeArray) 66 rg.SetKindCoder(reflect.Slice, enc.EncodeArray, dec.DecodeSlice) 67 rg.SetKindCoder(reflect.Map, enc.EncodeMap, dec.DecodeMap) 68 rg.SetKindCoder(reflect.Interface, enc.EncodeInterface, dec.DecodeInterface) 69 return rg 70 } 71 72 // NewRegistry creates a new empty Registry. 73 func NewRegistry() *Registry { 74 return &Registry{ 75 mutex: new(sync.Mutex), 76 typeEncoders: make(map[reflect.Type]ValueEncoder), 77 typeDecoders: make(map[reflect.Type]ValueDecoder), 78 kindEncoders: make(map[reflect.Kind]ValueEncoder), 79 kindDecoders: make(map[reflect.Kind]ValueDecoder), 80 } 81 } 82 83 // SetTypeCoder : 84 func (r *Registry) SetTypeCoder(t reflect.Type, enc ValueEncoder, dec ValueDecoder) { 85 if enc == nil { 86 panic("missing encoder") 87 } 88 if dec == nil { 89 panic("missing decoder") 90 } 91 r.mutex.Lock() 92 defer r.mutex.Unlock() 93 r.typeEncoders[t] = enc 94 r.typeDecoders[t] = dec 95 } 96 97 // SetKindCoder : 98 func (r *Registry) SetKindCoder(k reflect.Kind, enc ValueEncoder, dec ValueDecoder) { 99 if enc == nil { 100 panic("missing encoder") 101 } 102 if dec == nil { 103 panic("missing decoder") 104 } 105 r.mutex.Lock() 106 defer r.mutex.Unlock() 107 r.kindEncoders[k] = enc 108 r.kindDecoders[k] = dec 109 } 110 111 // LookupEncoder : 112 func (r *Registry) LookupEncoder(v reflect.Value) (ValueEncoder, error) { 113 var ( 114 enc ValueEncoder 115 ok bool 116 ) 117 118 if !v.IsValid() || reflext.IsNull(v) { 119 return func(w *Writer, v reflect.Value) error { 120 w.WriteString(null) 121 return nil 122 }, nil 123 } 124 125 it := v.Interface() 126 if _, ok := it.(Marshaler); ok { 127 return marshalerEncoder(), nil 128 } 129 130 if _, ok := it.(json.Marshaler); ok { 131 return jsonMarshalerEncoder(), nil 132 } 133 134 if _, ok := it.(encoding.TextMarshaler); ok { 135 return textMarshalerEncoder(), nil 136 } 137 138 t := v.Type() 139 enc, ok = r.typeEncoders[t] 140 if ok { 141 return enc, nil 142 } 143 144 enc, ok = r.kindEncoders[t.Kind()] 145 if ok { 146 return enc, nil 147 } 148 return nil, ErrNoEncoder{Type: t} 149 } 150 151 // LookupDecoder : 152 func (r *Registry) LookupDecoder(t reflect.Type) (ValueDecoder, error) { 153 var ( 154 dec ValueDecoder 155 ok bool 156 ) 157 158 ptrType := t 159 if t.Kind() != reflect.Ptr { 160 ptrType = reflect.PtrTo(t) 161 } 162 163 if ptrType.Implements(jsonbUnmarshaler) { 164 return unmarshalerDecoder(), nil 165 } 166 167 dec, ok = r.typeDecoders[t] 168 if ok { 169 return dec, nil 170 } 171 172 if ptrType.Implements(jsonUnmarshaler) { 173 return jsonUnmarshalerDecoder(), nil 174 } 175 176 if ptrType.Implements(textUnmarshaler) { 177 return textUnmarshalerDecoder(), nil 178 } 179 180 dec, ok = r.kindDecoders[t.Kind()] 181 if ok { 182 return dec, nil 183 } 184 return nil, ErrNoDecoder{Type: t} 185 }