mirror of
https://github.com/json-iterator/go.git
synced 2025-05-13 21:36:29 +02:00
use reflect2 to implement map decoder
This commit is contained in:
parent
d6f02cbd48
commit
08218647c3
@ -82,19 +82,22 @@ func (stream *Stream) WriteVal(val interface{}) {
|
|||||||
encoder.Encode(reflect2.PtrOf(val), stream)
|
encoder.Encode(reflect2.PtrOf(val), stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
func decoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
func (cfg *frozenConfig) DecoderOf(typ reflect.Type) ValDecoder {
|
||||||
cacheKey := typ
|
cacheKey := typ
|
||||||
decoder := cfg.getDecoderFromCache(cacheKey)
|
decoder := cfg.getDecoderFromCache(cacheKey)
|
||||||
if decoder != nil {
|
if decoder != nil {
|
||||||
return decoder
|
return decoder
|
||||||
}
|
}
|
||||||
decoder = getTypeDecoderFromExtension(cfg, typ)
|
decoder = decoderOfType(cfg, "", typ)
|
||||||
|
cfg.addDecoderToCache(cacheKey, decoder)
|
||||||
|
return decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func decoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
decoder := getTypeDecoderFromExtension(cfg, typ)
|
||||||
if decoder != nil {
|
if decoder != nil {
|
||||||
cfg.addDecoderToCache(cacheKey, decoder)
|
|
||||||
return decoder
|
return decoder
|
||||||
}
|
}
|
||||||
decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
|
|
||||||
cfg.addDecoderToCache(cacheKey, decoder)
|
|
||||||
decoder = createDecoderOfType(cfg, prefix, typ)
|
decoder = createDecoderOfType(cfg, prefix, typ)
|
||||||
for _, extension := range extensions {
|
for _, extension := range extensions {
|
||||||
decoder = extension.DecorateDecoder(typ, decoder)
|
decoder = extension.DecorateDecoder(typ, decoder)
|
||||||
@ -102,7 +105,6 @@ func decoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecode
|
|||||||
for _, extension := range cfg.extensions {
|
for _, extension := range cfg.extensions {
|
||||||
decoder = extension.DecorateDecoder(typ, decoder)
|
decoder = extension.DecorateDecoder(typ, decoder)
|
||||||
}
|
}
|
||||||
cfg.addDecoderToCache(cacheKey, decoder)
|
|
||||||
return decoder
|
return decoder
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,30 +122,8 @@ func createDecoderOfType(cfg *frozenConfig, prefix string, typ reflect.Type) Val
|
|||||||
if typ.AssignableTo(jsoniterNumberType) {
|
if typ.AssignableTo(jsoniterNumberType) {
|
||||||
return &jsoniterNumberCodec{}
|
return &jsoniterNumberCodec{}
|
||||||
}
|
}
|
||||||
if typ.Implements(unmarshalerType) {
|
decoder := createDecoderOfMarshaler(cfg, prefix, typ)
|
||||||
templateInterface := reflect.New(typ).Elem().Interface()
|
if decoder != nil {
|
||||||
var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
|
|
||||||
if typ.Kind() == reflect.Ptr {
|
|
||||||
decoder = &OptionalDecoder{typ.Elem(), decoder}
|
|
||||||
}
|
|
||||||
return decoder
|
|
||||||
}
|
|
||||||
if reflect.PtrTo(typ).Implements(unmarshalerType) {
|
|
||||||
templateInterface := reflect.New(typ).Interface()
|
|
||||||
var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
|
|
||||||
return decoder
|
|
||||||
}
|
|
||||||
if typ.Implements(textUnmarshalerType) {
|
|
||||||
templateInterface := reflect.New(typ).Elem().Interface()
|
|
||||||
var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
|
|
||||||
if typ.Kind() == reflect.Ptr {
|
|
||||||
decoder = &OptionalDecoder{typ.Elem(), decoder}
|
|
||||||
}
|
|
||||||
return decoder
|
|
||||||
}
|
|
||||||
if reflect.PtrTo(typ).Implements(textUnmarshalerType) {
|
|
||||||
templateInterface := reflect.New(typ).Interface()
|
|
||||||
var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
|
|
||||||
return decoder
|
return decoder
|
||||||
}
|
}
|
||||||
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
package jsoniter
|
package jsoniter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
"github.com/v2pro/plz/reflect2"
|
"github.com/v2pro/plz/reflect2"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
func decoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
decoder := decoderOfType(cfg, prefix+"[map]->", typ.Elem())
|
keyDecoder := decoderOfMapKey(cfg, prefix+" [mapKey]", typ.Key())
|
||||||
mapInterface := reflect.New(typ).Interface()
|
elemDecoder := decoderOfType(cfg, prefix+" [mapElem]", typ.Elem())
|
||||||
return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}
|
mapType := reflect2.Type2(typ).(*reflect2.UnsafeMapType)
|
||||||
|
return &mapDecoder{
|
||||||
|
mapType: mapType,
|
||||||
|
keyType: mapType.Key(),
|
||||||
|
elemType: mapType.Elem(),
|
||||||
|
keyDecoder: keyDecoder,
|
||||||
|
elemDecoder: elemDecoder,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
@ -31,6 +36,38 @@ func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decoderOfMapKey(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return decoderOfType(cfg, prefix, reflect2.DefaultTypeOfKind(reflect.String).Type1())
|
||||||
|
case reflect.Bool,
|
||||||
|
reflect.Uint8, reflect.Int8,
|
||||||
|
reflect.Uint16, reflect.Int16,
|
||||||
|
reflect.Uint32, reflect.Int32,
|
||||||
|
reflect.Uint64, reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Int,
|
||||||
|
reflect.Float32, reflect.Float64,
|
||||||
|
reflect.Uintptr:
|
||||||
|
typ = reflect2.DefaultTypeOfKind(typ.Kind()).Type1()
|
||||||
|
return &numericMapKeyDecoder{decoderOfType(cfg, prefix, typ)}
|
||||||
|
default:
|
||||||
|
ptrType := reflect.PtrTo(typ)
|
||||||
|
if ptrType.Implements(textMarshalerType) {
|
||||||
|
return &referenceDecoder{
|
||||||
|
&textUnmarshalerDecoder{
|
||||||
|
valType: reflect2.Type2(ptrType),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if typ.Implements(textMarshalerType) {
|
||||||
|
return &textUnmarshalerDecoder{
|
||||||
|
valType: reflect2.Type2(typ),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func encoderOfMapKey(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
func encoderOfMapKey(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
switch typ.Kind() {
|
switch typ.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
@ -53,7 +90,7 @@ func encoderOfMapKey(cfg *frozenConfig, prefix string, typ reflect.Type) ValEnco
|
|||||||
}
|
}
|
||||||
if typ.Implements(textMarshalerType) {
|
if typ.Implements(textMarshalerType) {
|
||||||
return &textMarshalerEncoder{
|
return &textMarshalerEncoder{
|
||||||
valType: reflect2.Type2(typ),
|
valType: reflect2.Type2(typ),
|
||||||
stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
|
stringEncoder: cfg.EncoderOf(reflect.TypeOf("")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,77 +99,81 @@ func encoderOfMapKey(cfg *frozenConfig, prefix string, typ reflect.Type) ValEnco
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mapDecoder struct {
|
type mapDecoder struct {
|
||||||
mapType reflect.Type
|
mapType *reflect2.UnsafeMapType
|
||||||
keyType reflect.Type
|
keyType reflect2.Type
|
||||||
elemType reflect.Type
|
elemType reflect2.Type
|
||||||
elemDecoder ValDecoder
|
keyDecoder ValDecoder
|
||||||
mapInterface emptyInterface
|
elemDecoder ValDecoder
|
||||||
}
|
}
|
||||||
|
|
||||||
func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
// dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
|
mapType := decoder.mapType
|
||||||
mapInterface := decoder.mapInterface
|
c := iter.nextToken()
|
||||||
mapInterface.word = ptr
|
if c == 'n' {
|
||||||
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
|
iter.skipThreeBytes('u', 'l', 'l')
|
||||||
realVal := reflect.ValueOf(*realInterface).Elem()
|
*(*unsafe.Pointer)(ptr) = nil
|
||||||
if iter.ReadNil() {
|
mapType.UnsafeSet(ptr, mapType.UnsafeNew())
|
||||||
realVal.Set(reflect.Zero(decoder.mapType))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if realVal.IsNil() {
|
if mapType.UnsafeIsNil(ptr) {
|
||||||
realVal.Set(reflect.MakeMap(realVal.Type()))
|
mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
|
||||||
}
|
}
|
||||||
iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
|
if c != '{' {
|
||||||
elem := reflect.New(decoder.elemType)
|
iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
|
||||||
decoder.elemDecoder.Decode(extractInterface(elem.Interface()).word, iter)
|
return
|
||||||
// to put into map, we have to use reflection
|
}
|
||||||
keyType := decoder.keyType
|
c = iter.nextToken()
|
||||||
// TODO: remove this from loop
|
if c == '}' {
|
||||||
switch {
|
return
|
||||||
case keyType.Kind() == reflect.String:
|
}
|
||||||
realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem())
|
if c != '"' {
|
||||||
return true
|
iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
|
||||||
case keyType.Implements(textUnmarshalerType):
|
return
|
||||||
textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
|
}
|
||||||
err := textUnmarshaler.UnmarshalText([]byte(keyStr))
|
iter.unreadByte()
|
||||||
if err != nil {
|
key := decoder.keyType.UnsafeNew()
|
||||||
iter.ReportError("read map key as TextUnmarshaler", err.Error())
|
decoder.keyDecoder.Decode(key, iter)
|
||||||
return false
|
c = iter.nextToken()
|
||||||
}
|
if c != ':' {
|
||||||
realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
|
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
|
||||||
return true
|
return
|
||||||
case reflect.PtrTo(keyType).Implements(textUnmarshalerType):
|
}
|
||||||
textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler)
|
elem := decoder.elemType.UnsafeNew()
|
||||||
err := textUnmarshaler.UnmarshalText([]byte(keyStr))
|
decoder.elemDecoder.Decode(elem, iter)
|
||||||
if err != nil {
|
decoder.mapType.UnsafeSetIndex(ptr, key, elem)
|
||||||
iter.ReportError("read map key as TextUnmarshaler", err.Error())
|
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
|
||||||
return false
|
key := decoder.keyType.UnsafeNew()
|
||||||
}
|
decoder.keyDecoder.Decode(key, iter)
|
||||||
realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem())
|
c = iter.nextToken()
|
||||||
return true
|
if c != ':' {
|
||||||
default:
|
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
|
||||||
switch keyType.Kind() {
|
return
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
n, err := strconv.ParseInt(keyStr, 10, 64)
|
|
||||||
if err != nil || reflect.Zero(keyType).OverflowInt(n) {
|
|
||||||
iter.ReportError("read map key as int64", "read int64 failed")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
|
|
||||||
return true
|
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
|
||||||
n, err := strconv.ParseUint(keyStr, 10, 64)
|
|
||||||
if err != nil || reflect.Zero(keyType).OverflowUint(n) {
|
|
||||||
iter.ReportError("read map key as uint64", "read uint64 failed")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
iter.ReportError("read map key", "unexpected map key type "+keyType.String())
|
elem := decoder.elemType.UnsafeNew()
|
||||||
return true
|
decoder.elemDecoder.Decode(elem, iter)
|
||||||
})
|
decoder.mapType.UnsafeSetIndex(ptr, key, elem)
|
||||||
|
}
|
||||||
|
if c != '}' {
|
||||||
|
iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type numericMapKeyDecoder struct {
|
||||||
|
decoder ValDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
c := iter.nextToken()
|
||||||
|
if c != '"' {
|
||||||
|
iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
decoder.decoder.Decode(ptr, iter)
|
||||||
|
c = iter.nextToken()
|
||||||
|
if c != '"' {
|
||||||
|
iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type numericMapKeyEncoder struct {
|
type numericMapKeyEncoder struct {
|
||||||
|
@ -8,6 +8,21 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func createDecoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
ptrType := reflect.PtrTo(typ)
|
||||||
|
if ptrType.Implements(unmarshalerType) {
|
||||||
|
return &referenceDecoder{
|
||||||
|
&unmarshalerDecoder{reflect2.Type2(ptrType)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ptrType.Implements(textUnmarshalerType) {
|
||||||
|
return &referenceDecoder{
|
||||||
|
&textUnmarshalerDecoder{reflect2.Type2(ptrType)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func createEncoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
func createEncoderOfMarshaler(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
if typ == marshalerType {
|
if typ == marshalerType {
|
||||||
checkIsEmpty := createCheckIsEmpty(cfg, typ)
|
checkIsEmpty := createCheckIsEmpty(cfg, typ)
|
||||||
@ -160,14 +175,13 @@ func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type unmarshalerDecoder struct {
|
type unmarshalerDecoder struct {
|
||||||
templateInterface emptyInterface
|
valType reflect2.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
templateInterface := decoder.templateInterface
|
valType := decoder.valType
|
||||||
templateInterface.word = ptr
|
obj := valType.UnsafeIndirect(ptr)
|
||||||
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
|
unmarshaler := obj.(json.Unmarshaler)
|
||||||
unmarshaler := (*realInterface).(json.Unmarshaler)
|
|
||||||
iter.nextToken()
|
iter.nextToken()
|
||||||
iter.unreadByte() // skip spaces
|
iter.unreadByte() // skip spaces
|
||||||
bytes := iter.SkipAndReturnBytes()
|
bytes := iter.SkipAndReturnBytes()
|
||||||
@ -178,14 +192,20 @@ func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type textUnmarshalerDecoder struct {
|
type textUnmarshalerDecoder struct {
|
||||||
templateInterface emptyInterface
|
valType reflect2.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
templateInterface := decoder.templateInterface
|
valType := decoder.valType
|
||||||
templateInterface.word = ptr
|
obj := valType.UnsafeIndirect(ptr)
|
||||||
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
|
if reflect2.IsNil(obj) {
|
||||||
unmarshaler := (*realInterface).(encoding.TextUnmarshaler)
|
ptrType := valType.(*reflect2.UnsafePtrType)
|
||||||
|
elemType := ptrType.Elem()
|
||||||
|
elem := elemType.UnsafeNew()
|
||||||
|
ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem))
|
||||||
|
obj = valType.UnsafeIndirect(ptr)
|
||||||
|
}
|
||||||
|
unmarshaler := (obj).(encoding.TextUnmarshaler)
|
||||||
str := iter.ReadString()
|
str := iter.ReadString()
|
||||||
err := unmarshaler.UnmarshalText([]byte(str))
|
err := unmarshaler.UnmarshalText([]byte(str))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -119,3 +119,11 @@ func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
|
return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type referenceDecoder struct {
|
||||||
|
decoder ValDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
decoder.decoder.Decode(unsafe.Pointer(&ptr), iter)
|
||||||
|
}
|
@ -6,61 +6,80 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
jsonMarshaler := json.Marshaler(fakeJsonMarshaler{})
|
jm := json.Marshaler(jmOfStruct{})
|
||||||
textMarshaler := encoding.TextMarshaler(fakeTextMarshaler{})
|
tm1 := encoding.TextMarshaler(tmOfStruct{})
|
||||||
textMarshaler2 := encoding.TextMarshaler(&fakeTextMarshaler2{})
|
tm2 := encoding.TextMarshaler(&tmOfStructInt{})
|
||||||
marshalCases = append(marshalCases,
|
marshalCases = append(marshalCases,
|
||||||
fakeJsonMarshaler{},
|
jmOfStruct{},
|
||||||
&jsonMarshaler,
|
&jm,
|
||||||
fakeTextMarshaler{},
|
tmOfStruct{},
|
||||||
&textMarshaler,
|
&tm1,
|
||||||
fakeTextMarshaler2{},
|
tmOfStructInt{},
|
||||||
&textMarshaler2,
|
&tm2,
|
||||||
map[fakeTextMarshaler]int{
|
map[tmOfStruct]int{
|
||||||
fakeTextMarshaler{}: 100,
|
tmOfStruct{}: 100,
|
||||||
},
|
},
|
||||||
map[*fakeTextMarshaler]int{
|
map[*tmOfStruct]int{
|
||||||
&fakeTextMarshaler{}: 100,
|
&tmOfStruct{}: 100,
|
||||||
},
|
},
|
||||||
map[encoding.TextMarshaler]int{
|
map[encoding.TextMarshaler]int{
|
||||||
textMarshaler: 100,
|
tm1: 100,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
unmarshalCases = append(unmarshalCases, unmarshalCase{
|
||||||
|
ptr: (*tmOfMap)(nil),
|
||||||
|
input: `"{1:2}"`,
|
||||||
|
}, unmarshalCase{
|
||||||
|
ptr: (*tmOfMapPtr)(nil),
|
||||||
|
input: `"{1:2}"`,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeJsonMarshaler struct {
|
type jmOfStruct struct {
|
||||||
F2 chan []byte
|
F2 chan []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q fakeJsonMarshaler) MarshalJSON() ([]byte, error) {
|
func (q jmOfStruct) MarshalJSON() ([]byte, error) {
|
||||||
return []byte(`""`), nil
|
return []byte(`""`), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *fakeJsonMarshaler) UnmarshalJSON(value []byte) error {
|
func (q *jmOfStruct) UnmarshalJSON(value []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type fakeTextMarshaler struct {
|
type tmOfStruct struct {
|
||||||
F2 chan []byte
|
F2 chan []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q fakeTextMarshaler) MarshalText() ([]byte, error) {
|
func (q tmOfStruct) MarshalText() ([]byte, error) {
|
||||||
return []byte(`""`), nil
|
return []byte(`""`), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *fakeTextMarshaler) UnmarshalText(value []byte) error {
|
func (q *tmOfStruct) UnmarshalText(value []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeTextMarshaler2 struct {
|
type tmOfStructInt struct {
|
||||||
Field2 int
|
Field2 int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *fakeTextMarshaler2) MarshalText() ([]byte, error) {
|
func (q *tmOfStructInt) MarshalText() ([]byte, error) {
|
||||||
return []byte(`"abc"`), nil
|
return []byte(`"abc"`), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *fakeTextMarshaler2) UnmarshalText(value []byte) error {
|
func (q *tmOfStructInt) UnmarshalText(value []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type tmOfMap map[int]int
|
||||||
|
|
||||||
|
func (q tmOfMap) UnmarshalText(value []byte) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type tmOfMapPtr map[int]int
|
||||||
|
|
||||||
|
func (q *tmOfMapPtr) UnmarshalText(value []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user