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  }