mirror of
https://github.com/json-iterator/go.git
synced 2025-04-23 11:37:32 +02:00
fix #207 delay unsupported type error reporting
This commit is contained in:
parent
e0df39fda2
commit
a9b9c73b4d
1022
feature_reflect.go
1022
feature_reflect.go
File diff suppressed because it is too large
Load Diff
@ -7,23 +7,17 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
|
func decoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
decoder, err := decoderOfType(cfg, typ.Elem())
|
decoder := decoderOfType(cfg, prefix+"[array]->", typ.Elem())
|
||||||
if err != nil {
|
return &arrayDecoder{typ, typ.Elem(), decoder}
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &arrayDecoder{typ, typ.Elem(), decoder}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
func encoderOfArray(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
encoder, err := encoderOfType(cfg, typ.Elem())
|
encoder := encoderOfType(cfg, prefix+"[array]->", typ.Elem())
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typ.Elem().Kind() == reflect.Map {
|
if typ.Elem().Kind() == reflect.Map {
|
||||||
encoder = &OptionalEncoder{encoder}
|
encoder = &OptionalEncoder{encoder}
|
||||||
}
|
}
|
||||||
return &arrayEncoder{typ, typ.Elem(), encoder}, nil
|
return &arrayEncoder{typ, typ.Elem(), encoder}
|
||||||
}
|
}
|
||||||
|
|
||||||
type arrayEncoder struct {
|
type arrayEncoder struct {
|
||||||
|
@ -240,7 +240,7 @@ func _getTypeEncoderFromExtension(cfg *frozenConfig, typ reflect.Type) ValEncode
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) {
|
func describeStruct(cfg *frozenConfig, prefix string, typ reflect.Type) *StructDescriptor {
|
||||||
embeddedBindings := []*Binding{}
|
embeddedBindings := []*Binding{}
|
||||||
bindings := []*Binding{}
|
bindings := []*Binding{}
|
||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
@ -252,10 +252,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
|
|||||||
}
|
}
|
||||||
if field.Anonymous && (tag == "" || tagParts[0] == "") {
|
if field.Anonymous && (tag == "" || tagParts[0] == "") {
|
||||||
if field.Type.Kind() == reflect.Struct {
|
if field.Type.Kind() == reflect.Struct {
|
||||||
structDescriptor, err := describeStruct(cfg, field.Type)
|
structDescriptor := describeStruct(cfg, prefix, field.Type)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, binding := range structDescriptor.Fields {
|
for _, binding := range structDescriptor.Fields {
|
||||||
binding.levels = append([]int{i}, binding.levels...)
|
binding.levels = append([]int{i}, binding.levels...)
|
||||||
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||||
@ -265,10 +262,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
|
} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
|
||||||
structDescriptor, err := describeStruct(cfg, field.Type.Elem())
|
structDescriptor := describeStruct(cfg, prefix, field.Type.Elem())
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, binding := range structDescriptor.Fields {
|
for _, binding := range structDescriptor.Fields {
|
||||||
binding.levels = append([]int{i}, binding.levels...)
|
binding.levels = append([]int{i}, binding.levels...)
|
||||||
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
|
||||||
@ -285,19 +279,11 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
|
|||||||
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
|
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
|
||||||
decoder := fieldDecoders[fieldCacheKey]
|
decoder := fieldDecoders[fieldCacheKey]
|
||||||
if decoder == nil {
|
if decoder == nil {
|
||||||
var err error
|
decoder = decoderOfType(cfg, prefix+typ.String()+"."+field.Name+"->", field.Type)
|
||||||
decoder, err = decoderOfType(cfg, field.Type)
|
|
||||||
if len(fieldNames) > 0 && err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
encoder := fieldEncoders[fieldCacheKey]
|
encoder := fieldEncoders[fieldCacheKey]
|
||||||
if encoder == nil {
|
if encoder == nil {
|
||||||
var err error
|
encoder = encoderOfType(cfg, prefix+typ.String()+"."+field.Name+"->", field.Type)
|
||||||
encoder, err = encoderOfType(cfg, field.Type)
|
|
||||||
if len(fieldNames) > 0 && err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// map is stored as pointer in the struct,
|
// map is stored as pointer in the struct,
|
||||||
// and treat nil or empty map as empty field
|
// and treat nil or empty map as empty field
|
||||||
if encoder != nil && field.Type.Kind() == reflect.Map {
|
if encoder != nil && field.Type.Kind() == reflect.Map {
|
||||||
@ -314,7 +300,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
|
|||||||
binding.levels = []int{i}
|
binding.levels = []int{i}
|
||||||
bindings = append(bindings, binding)
|
bindings = append(bindings, binding)
|
||||||
}
|
}
|
||||||
return createStructDescriptor(cfg, typ, bindings, embeddedBindings), nil
|
return createStructDescriptor(cfg, typ, bindings, embeddedBindings)
|
||||||
}
|
}
|
||||||
func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
|
||||||
onePtrEmbedded := false
|
onePtrEmbedded := false
|
||||||
|
@ -9,6 +9,22 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func decoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
decoder := decoderOfType(cfg, prefix+"[map]->", typ.Elem())
|
||||||
|
mapInterface := reflect.New(typ).Interface()
|
||||||
|
return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfMap(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
|
elemType := typ.Elem()
|
||||||
|
encoder := encoderOfType(cfg, prefix+"[map]->", elemType)
|
||||||
|
mapInterface := reflect.New(typ).Elem().Interface()
|
||||||
|
if cfg.sortMapKeys {
|
||||||
|
return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
|
||||||
|
}
|
||||||
|
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}
|
||||||
|
}
|
||||||
|
|
||||||
type mapDecoder struct {
|
type mapDecoder struct {
|
||||||
mapType reflect.Type
|
mapType reflect.Type
|
||||||
keyType reflect.Type
|
keyType reflect.Type
|
||||||
|
@ -8,17 +8,14 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
func encoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
type bindingTo struct {
|
type bindingTo struct {
|
||||||
binding *Binding
|
binding *Binding
|
||||||
toName string
|
toName string
|
||||||
ignored bool
|
ignored bool
|
||||||
}
|
}
|
||||||
orderedBindings := []*bindingTo{}
|
orderedBindings := []*bindingTo{}
|
||||||
structDescriptor, err := describeStruct(cfg, typ)
|
structDescriptor := describeStruct(cfg, prefix, typ)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, binding := range structDescriptor.Fields {
|
for _, binding := range structDescriptor.Fields {
|
||||||
for _, toName := range binding.ToNames {
|
for _, toName := range binding.ToNames {
|
||||||
new := &bindingTo{
|
new := &bindingTo{
|
||||||
@ -35,7 +32,7 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(orderedBindings) == 0 {
|
if len(orderedBindings) == 0 {
|
||||||
return &emptyStructEncoder{}, nil
|
return &emptyStructEncoder{}
|
||||||
}
|
}
|
||||||
finalOrderedFields := []structFieldTo{}
|
finalOrderedFields := []structFieldTo{}
|
||||||
for _, bindingTo := range orderedBindings {
|
for _, bindingTo := range orderedBindings {
|
||||||
@ -46,7 +43,8 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil
|
return &structEncoder{typ, structDescriptor.onePtrEmbedded,
|
||||||
|
structDescriptor.onePtrOptimization, finalOrderedFields}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
|
func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
|
||||||
@ -78,12 +76,9 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
|
func decoderOfStruct(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
bindings := map[string]*Binding{}
|
bindings := map[string]*Binding{}
|
||||||
structDescriptor, err := describeStruct(cfg, typ)
|
structDescriptor := describeStruct(cfg, prefix, typ)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, binding := range structDescriptor.Fields {
|
for _, binding := range structDescriptor.Fields {
|
||||||
for _, fromName := range binding.FromNames {
|
for _, fromName := range binding.FromNames {
|
||||||
old := bindings[fromName]
|
old := bindings[fromName]
|
||||||
@ -131,6 +126,7 @@ func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type structEncoder struct {
|
type structEncoder struct {
|
||||||
|
typ reflect.Type
|
||||||
onePtrEmbedded bool
|
onePtrEmbedded bool
|
||||||
onePtrOptimization bool
|
onePtrOptimization bool
|
||||||
fields []structFieldTo
|
fields []structFieldTo
|
||||||
@ -156,6 +152,9 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
|||||||
isNotFirst = true
|
isNotFirst = true
|
||||||
}
|
}
|
||||||
stream.WriteObjectEnd()
|
stream.WriteObjectEnd()
|
||||||
|
if stream.Error != nil && stream.Error != io.EOF {
|
||||||
|
stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
|
func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
|
||||||
|
104
feature_reflect_optional.go
Normal file
104
feature_reflect_optional.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package jsoniter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
|
elemType := typ.Elem()
|
||||||
|
decoder := decoderOfType(cfg, prefix, elemType)
|
||||||
|
return &OptionalDecoder{elemType, decoder}
|
||||||
|
}
|
||||||
|
|
||||||
|
func encoderOfOptional(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
|
elemType := typ.Elem()
|
||||||
|
elemEncoder := encoderOfType(cfg, prefix, elemType)
|
||||||
|
encoder := &OptionalEncoder{elemEncoder}
|
||||||
|
if elemType.Kind() == reflect.Map {
|
||||||
|
encoder = &OptionalEncoder{encoder}
|
||||||
|
}
|
||||||
|
return encoder
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionalDecoder struct {
|
||||||
|
ValueType reflect.Type
|
||||||
|
ValueDecoder ValDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
if iter.ReadNil() {
|
||||||
|
*((*unsafe.Pointer)(ptr)) = nil
|
||||||
|
} else {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
//pointer to null, we have to allocate memory to hold the value
|
||||||
|
value := reflect.New(decoder.ValueType)
|
||||||
|
newPtr := extractInterface(value.Interface()).word
|
||||||
|
decoder.ValueDecoder.Decode(newPtr, iter)
|
||||||
|
*((*uintptr)(ptr)) = uintptr(newPtr)
|
||||||
|
} else {
|
||||||
|
//reuse existing instance
|
||||||
|
decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type deferenceDecoder struct {
|
||||||
|
// only to deference a pointer
|
||||||
|
valueType reflect.Type
|
||||||
|
valueDecoder ValDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
//pointer to null, we have to allocate memory to hold the value
|
||||||
|
value := reflect.New(decoder.valueType)
|
||||||
|
newPtr := extractInterface(value.Interface()).word
|
||||||
|
decoder.valueDecoder.Decode(newPtr, iter)
|
||||||
|
*((*uintptr)(ptr)) = uintptr(newPtr)
|
||||||
|
} else {
|
||||||
|
//reuse existing instance
|
||||||
|
decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type OptionalEncoder struct {
|
||||||
|
ValueEncoder ValEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
} else {
|
||||||
|
encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *OptionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
return *((*unsafe.Pointer)(ptr)) == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type optionalMapEncoder struct {
|
||||||
|
valueEncoder ValEncoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *optionalMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
|
||||||
|
if *((*unsafe.Pointer)(ptr)) == nil {
|
||||||
|
stream.WriteNil()
|
||||||
|
} else {
|
||||||
|
encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *optionalMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
|
||||||
|
WriteToStream(val, stream, encoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (encoder *optionalMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
|
||||||
|
p := *((*unsafe.Pointer)(ptr))
|
||||||
|
return p == nil || encoder.valueEncoder.IsEmpty(p)
|
||||||
|
}
|
@ -7,23 +7,17 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func decoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
|
func decoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValDecoder {
|
||||||
decoder, err := decoderOfType(cfg, typ.Elem())
|
decoder := decoderOfType(cfg, prefix+"[slice]->", typ.Elem())
|
||||||
if err != nil {
|
return &sliceDecoder{typ, typ.Elem(), decoder}
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &sliceDecoder{typ, typ.Elem(), decoder}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
|
func encoderOfSlice(cfg *frozenConfig, prefix string, typ reflect.Type) ValEncoder {
|
||||||
encoder, err := encoderOfType(cfg, typ.Elem())
|
encoder := encoderOfType(cfg, prefix+"[slice]->", typ.Elem())
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if typ.Elem().Kind() == reflect.Map {
|
if typ.Elem().Kind() == reflect.Map {
|
||||||
encoder = &OptionalEncoder{encoder}
|
encoder = &OptionalEncoder{encoder}
|
||||||
}
|
}
|
||||||
return &sliceEncoder{typ, typ.Elem(), encoder}, nil
|
return &sliceEncoder{typ, typ.Elem(), encoder}
|
||||||
}
|
}
|
||||||
|
|
||||||
type sliceEncoder struct {
|
type sliceEncoder struct {
|
||||||
|
@ -8,22 +8,22 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) {
|
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) ValDecoder {
|
||||||
knownHash := map[int32]struct{}{
|
knownHash := map[int32]struct{}{
|
||||||
0: {},
|
0: {},
|
||||||
}
|
}
|
||||||
switch len(fields) {
|
switch len(fields) {
|
||||||
case 0:
|
case 0:
|
||||||
return &skipObjectDecoder{typ}, nil
|
return &skipObjectDecoder{typ}
|
||||||
case 1:
|
case 1:
|
||||||
for fieldName, fieldDecoder := range fields {
|
for fieldName, fieldDecoder := range fields {
|
||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}, nil
|
return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
var fieldHash1 int32
|
var fieldHash1 int32
|
||||||
@ -34,7 +34,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldHash1 == 0 {
|
if fieldHash1 == 0 {
|
||||||
@ -45,7 +45,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldDecoder2 = fieldDecoder
|
fieldDecoder2 = fieldDecoder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}, nil
|
return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}
|
||||||
case 3:
|
case 3:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -57,7 +57,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -72,7 +72,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &threeFieldsStructDecoder{typ,
|
return &threeFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
|
fieldName1, fieldDecoder1,
|
||||||
|
fieldName2, fieldDecoder2,
|
||||||
|
fieldName3, fieldDecoder3}
|
||||||
case 4:
|
case 4:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -86,7 +88,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -104,8 +106,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &fourFieldsStructDecoder{typ,
|
return &fourFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4}, nil
|
fieldName2, fieldDecoder2,
|
||||||
|
fieldName3, fieldDecoder3,
|
||||||
|
fieldName4, fieldDecoder4}
|
||||||
case 5:
|
case 5:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -121,7 +125,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -142,8 +146,11 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &fiveFieldsStructDecoder{typ,
|
return &fiveFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
|
fieldName2, fieldDecoder2,
|
||||||
|
fieldName3, fieldDecoder3,
|
||||||
|
fieldName4, fieldDecoder4,
|
||||||
|
fieldName5, fieldDecoder5}
|
||||||
case 6:
|
case 6:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -161,7 +168,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -185,8 +192,12 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &sixFieldsStructDecoder{typ,
|
return &sixFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
|
fieldName2, fieldDecoder2,
|
||||||
|
fieldName3, fieldDecoder3,
|
||||||
|
fieldName4, fieldDecoder4,
|
||||||
|
fieldName5, fieldDecoder5,
|
||||||
|
fieldName6, fieldDecoder6}
|
||||||
case 7:
|
case 7:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -206,7 +217,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -233,9 +244,13 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &sevenFieldsStructDecoder{typ,
|
return &sevenFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
fieldName2, fieldDecoder2,
|
||||||
fieldName7, fieldDecoder7}, nil
|
fieldName3, fieldDecoder3,
|
||||||
|
fieldName4, fieldDecoder4,
|
||||||
|
fieldName5, fieldDecoder5,
|
||||||
|
fieldName6, fieldDecoder6,
|
||||||
|
fieldName7, fieldDecoder7}
|
||||||
case 8:
|
case 8:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -257,7 +272,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -287,9 +302,14 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &eightFieldsStructDecoder{typ,
|
return &eightFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
fieldName2, fieldDecoder2,
|
||||||
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
|
fieldName3, fieldDecoder3,
|
||||||
|
fieldName4, fieldDecoder4,
|
||||||
|
fieldName5, fieldDecoder5,
|
||||||
|
fieldName6, fieldDecoder6,
|
||||||
|
fieldName7, fieldDecoder7,
|
||||||
|
fieldName8, fieldDecoder8}
|
||||||
case 9:
|
case 9:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -313,7 +333,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -346,9 +366,15 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &nineFieldsStructDecoder{typ,
|
return &nineFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
fieldName2, fieldDecoder2,
|
||||||
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
|
fieldName3, fieldDecoder3,
|
||||||
|
fieldName4, fieldDecoder4,
|
||||||
|
fieldName5, fieldDecoder5,
|
||||||
|
fieldName6, fieldDecoder6,
|
||||||
|
fieldName7, fieldDecoder7,
|
||||||
|
fieldName8, fieldDecoder8,
|
||||||
|
fieldName9, fieldDecoder9}
|
||||||
case 10:
|
case 10:
|
||||||
var fieldName1 int32
|
var fieldName1 int32
|
||||||
var fieldName2 int32
|
var fieldName2 int32
|
||||||
@ -374,7 +400,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
fieldHash := calcHash(fieldName)
|
fieldHash := calcHash(fieldName)
|
||||||
_, known := knownHash[fieldHash]
|
_, known := knownHash[fieldHash]
|
||||||
if known {
|
if known {
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
knownHash[fieldHash] = struct{}{}
|
knownHash[fieldHash] = struct{}{}
|
||||||
if fieldName1 == 0 {
|
if fieldName1 == 0 {
|
||||||
@ -410,12 +436,18 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &tenFieldsStructDecoder{typ,
|
return &tenFieldsStructDecoder{typ,
|
||||||
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
|
fieldName1, fieldDecoder1,
|
||||||
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
|
fieldName2, fieldDecoder2,
|
||||||
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9,
|
fieldName3, fieldDecoder3,
|
||||||
fieldName10, fieldDecoder10}, nil
|
fieldName4, fieldDecoder4,
|
||||||
|
fieldName5, fieldDecoder5,
|
||||||
|
fieldName6, fieldDecoder6,
|
||||||
|
fieldName7, fieldDecoder7,
|
||||||
|
fieldName8, fieldDecoder8,
|
||||||
|
fieldName9, fieldDecoder9,
|
||||||
|
fieldName10, fieldDecoder10}
|
||||||
}
|
}
|
||||||
return &generalStructDecoder{typ, fields}, nil
|
return &generalStructDecoder{typ, fields}
|
||||||
}
|
}
|
||||||
|
|
||||||
type generalStructDecoder struct {
|
type generalStructDecoder struct {
|
||||||
@ -464,7 +496,7 @@ func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,7 +534,7 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,7 +564,7 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +598,7 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +636,7 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +678,7 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,7 +724,7 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,7 +774,7 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -796,7 +828,7 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,7 +886,7 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,7 +948,7 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if iter.Error != nil && iter.Error != io.EOF {
|
if iter.Error != nil && iter.Error != io.EOF {
|
||||||
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
|
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,12 +109,13 @@ func (extension *testExtension) UpdateStructDescriptor(structDescriptor *StructD
|
|||||||
|
|
||||||
func Test_customize_field_by_extension(t *testing.T) {
|
func Test_customize_field_by_extension(t *testing.T) {
|
||||||
should := require.New(t)
|
should := require.New(t)
|
||||||
RegisterExtension(&testExtension{})
|
cfg := Config{}.Froze()
|
||||||
|
cfg.RegisterExtension(&testExtension{})
|
||||||
obj := TestObject1{}
|
obj := TestObject1{}
|
||||||
err := UnmarshalFromString(`{"field-1": 100}`, &obj)
|
err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal("100", obj.Field1)
|
should.Equal("100", obj.Field1)
|
||||||
str, err := MarshalToString(obj)
|
str, err := cfg.MarshalToString(obj)
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal(`{"field-1":100}`, str)
|
should.Equal(`{"field-1":100}`, str)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ func Test_write_empty_interface_via_placeholder(t *testing.T) {
|
|||||||
cacheKey: reflect.TypeOf(m).Elem(),
|
cacheKey: reflect.TypeOf(m).Elem(),
|
||||||
}
|
}
|
||||||
stream := ConfigFastest.BorrowStream(nil)
|
stream := ConfigFastest.BorrowStream(nil)
|
||||||
encoderOfType(ConfigFastest.(*frozenConfig), reflect.TypeOf(m).Elem())
|
encoderOfType(ConfigFastest.(*frozenConfig), "", reflect.TypeOf(m).Elem())
|
||||||
encoder.EncodeInterface(inf, stream)
|
encoder.EncodeInterface(inf, stream)
|
||||||
should.Equal(`"hello"`, string(stream.Buffer()))
|
should.Equal(`"hello"`, string(stream.Buffer()))
|
||||||
}
|
}
|
||||||
|
@ -147,3 +147,40 @@ func Test_nil_pointer(t *testing.T) {
|
|||||||
err := Unmarshal(data, obj)
|
err := Unmarshal(data, obj)
|
||||||
should.NotNil(err)
|
should.NotNil(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_func_pointer_type(t *testing.T) {
|
||||||
|
type TestObject2 struct {
|
||||||
|
F func()
|
||||||
|
}
|
||||||
|
type TestObject1 struct {
|
||||||
|
Obj *TestObject2
|
||||||
|
}
|
||||||
|
t.Run("encode null is valid", func(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
output, err := json.Marshal(TestObject1{})
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(`{"Obj":null}`, string(output))
|
||||||
|
output, err = Marshal(TestObject1{})
|
||||||
|
should.Nil(err)
|
||||||
|
should.Equal(`{"Obj":null}`, string(output))
|
||||||
|
})
|
||||||
|
t.Run("encode not null is invalid", func(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
_, err := json.Marshal(TestObject1{Obj: &TestObject2{}})
|
||||||
|
should.NotNil(err)
|
||||||
|
_, err = Marshal(TestObject1{Obj: &TestObject2{}})
|
||||||
|
should.NotNil(err)
|
||||||
|
})
|
||||||
|
t.Run("decode null is valid", func(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
var obj TestObject1
|
||||||
|
should.Nil(json.Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
|
||||||
|
should.Nil(Unmarshal([]byte(`{"Obj":{"F": null}}`), &obj))
|
||||||
|
})
|
||||||
|
t.Run("decode not null is invalid", func(t *testing.T) {
|
||||||
|
should := require.New(t)
|
||||||
|
var obj TestObject1
|
||||||
|
should.NotNil(json.Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
|
||||||
|
should.NotNil(Unmarshal([]byte(`{"Obj":{"F": "hello"}}`), &obj))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user