github.com/RevenueMonster/sqlike@v1.0.6/jsonb/unmarshal.go (about) 1 package jsonb 2 3 import ( 4 "bytes" 5 "encoding" 6 "encoding/json" 7 "fmt" 8 "reflect" 9 10 "errors" 11 12 "github.com/RevenueMonster/sqlike/reflext" 13 ) 14 15 // Unmarshaler : 16 type Unmarshaler interface { 17 UnmarshalJSONB([]byte) error 18 } 19 20 // Unmarshal : 21 func Unmarshal(data []byte, dst interface{}) error { 22 v := reflext.ValueOf(dst) 23 if !v.IsValid() { 24 return errors.New("invalid value for Unmarshal") 25 } 26 27 t := v.Type() 28 if !reflext.IsKind(t, reflect.Ptr) { 29 return errors.New("unaddressable destination") 30 } 31 32 v = v.Elem() 33 if !v.CanSet() { 34 return errors.New("unaddressable destination") 35 } 36 37 t = t.Elem() 38 decoder, err := registry.LookupDecoder(t) 39 if err != nil { 40 return err 41 } 42 43 r := NewReader(data) 44 vv := reflext.Zero(t) 45 if err := decoder(r, vv); err != nil { 46 return err 47 } 48 49 c := r.nextToken() 50 if c != 0 { 51 return ErrInvalidJSON{ 52 callback: "Unmarshal", 53 message: fmt.Sprintf("invalid json string, extra char %q found", c), 54 } 55 } 56 v.Set(vv) 57 return nil 58 } 59 60 // UnmarshalValue : 61 func UnmarshalValue(data []byte, v reflect.Value) error { 62 if data == nil { 63 v.Set(reflect.Zero(v.Type())) 64 return nil 65 } 66 67 t := v.Type() 68 decoder, err := registry.LookupDecoder(reflext.Deref(t)) 69 if err != nil { 70 return err 71 } 72 73 r := NewReader(data) 74 vv := reflext.Zero(t) 75 76 vv = reflext.Indirect(vv) 77 if err := decoder(r, vv); err != nil { 78 return err 79 } 80 81 c := r.nextToken() 82 if c != 0 { 83 return ErrInvalidJSON{ 84 callback: "Unmarshal", 85 } 86 } 87 reflext.Indirect(v).Set(vv) 88 return nil 89 } 90 91 // unmarshalerDecoder 92 func unmarshalerDecoder() ValueDecoder { 93 return func(r *Reader, v reflect.Value) error { 94 if r.IsNull() { 95 v.Set(reflect.New(v.Type()).Elem()) 96 return r.skipNull() 97 } 98 99 r.pos = r.len 100 if v.Kind() != reflect.Ptr { 101 return v.Addr().Interface().(Unmarshaler).UnmarshalJSONB(r.Bytes()) 102 } 103 return reflext.Init(v).Interface().(Unmarshaler).UnmarshalJSONB(r.Bytes()) 104 } 105 } 106 107 // jsonUnmarshalerDecoder 108 func jsonUnmarshalerDecoder() ValueDecoder { 109 return func(r *Reader, v reflect.Value) error { 110 if r.IsNull() { 111 v.Set(reflect.New(v.Type()).Elem()) 112 return r.skipNull() 113 } 114 115 r.pos = r.len 116 if v.Kind() != reflect.Ptr { 117 return v.Addr().Interface().(json.Unmarshaler).UnmarshalJSON(r.Bytes()) 118 } 119 return reflext.Init(v).Interface().(json.Unmarshaler).UnmarshalJSON(r.Bytes()) 120 } 121 } 122 123 // textUnmarshalerDecoder 124 func textUnmarshalerDecoder() ValueDecoder { 125 return func(r *Reader, v reflect.Value) error { 126 if r.IsNull() { 127 v.Set(reflect.New(v.Type()).Elem()) 128 return r.skipNull() 129 } 130 131 r.pos = r.len 132 b := r.Bytes() 133 b = bytes.Trim(b, `"`) 134 if v.Kind() != reflect.Ptr { 135 return v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText(b) 136 } 137 return reflext.Init(v).Interface().(encoding.TextUnmarshaler).UnmarshalText(b) 138 } 139 }