1
0
mirror of https://github.com/json-iterator/go.git synced 2025-04-23 11:37:32 +02:00

create map if nil

This commit is contained in:
Tao Wen 2017-03-07 18:36:58 -08:00
parent 62028f1ede
commit ceb8c8a733
3 changed files with 39 additions and 19 deletions

View File

@ -200,7 +200,9 @@ func (decoder *mapDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
mapInterface.word = ptr mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface)) realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface).Elem() realVal := reflect.ValueOf(*realInterface).Elem()
if realVal.IsNil() {
realVal.Set(reflect.MakeMap(realVal.Type()))
}
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() { for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
elem := reflect.New(decoder.elemType) elem := reflect.New(decoder.elemType)
decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter) decoder.elemDecoder.decode(unsafe.Pointer(elem.Pointer()), iter)

View File

@ -33,14 +33,17 @@ func encoderOfStruct(typ reflect.Type) (Encoder, error) {
fieldNames = []string{tagParts[0]} fieldNames = []string{tagParts[0]}
} }
} }
encoder, err := encoderOfType(field.Type) var encoder Encoder
if err != nil { if len(fieldNames) > 0 {
return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err) encoder, err := encoderOfType(field.Type)
} if err != nil {
// map is stored as pointer in the struct return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
// but if struct only has one map, it is inlined }
if field.Type.Kind() == reflect.Map && typ.NumField() > 1 { // map is stored as pointer in the struct
encoder = &optionalEncoder{field.Type, encoder} // but if struct only has one map, it is inlined
if field.Type.Kind() == reflect.Map && typ.NumField() > 1 {
encoder = &optionalEncoder{field.Type, encoder}
}
} }
for _, fieldName := range fieldNames { for _, fieldName := range fieldNames {
if structEncoder_.firstField == nil { if structEncoder_.firstField == nil {
@ -85,7 +88,7 @@ func decoderOfStruct(typ reflect.Type) (Decoder, error) {
fieldNames = []string{tagParts[0]} fieldNames = []string{tagParts[0]}
} }
} }
if decoder == nil { if decoder == nil && len(fieldNames) > 0 {
var err error var err error
decoder, err = decoderOfType(field.Type) decoder, err = decoderOfType(field.Type)
if err != nil { if err != nil {

View File

@ -3,6 +3,7 @@ package jsoniter
import ( import (
"testing" "testing"
"github.com/json-iterator/go/require" "github.com/json-iterator/go/require"
"bytes"
) )
func Test_decode_one_field_struct(t *testing.T) { func Test_decode_one_field_struct(t *testing.T) {
@ -88,15 +89,15 @@ func Test_decode_five_fields_struct(t *testing.T) {
func Test_decode_ten_fields_struct(t *testing.T) { func Test_decode_ten_fields_struct(t *testing.T) {
should := require.New(t) should := require.New(t)
type TestObject struct { type TestObject struct {
field1 string field1 string
field2 string field2 string
field3 string field3 string
field4 string field4 string
field5 string field5 string
field6 string field6 string
field7 string field7 string
field8 string field8 string
field9 string field9 string
field10 string field10 string
} }
obj := TestObject{} obj := TestObject{}
@ -144,3 +145,17 @@ func Test_write_val_one_field_struct(t *testing.T) {
should.Nil(err) should.Nil(err)
should.Equal(`{"field-1":"hello"}`, str) should.Equal(`{"field-1":"hello"}`, str)
} }
func Test_mixed(t *testing.T) {
should := require.New(t)
type AA struct {
ID int `json:"id"`
Payload map[string]interface{} `json:"payload"`
buf *bytes.Buffer `json:"-"`
}
aa := AA{}
err := UnmarshalFromString(` {"id":1, "payload":{"account":"123","password":"456"}}`, &aa)
should.Nil(err)
should.Equal(1, aa.ID)
should.Equal("123", aa.Payload["account"])
}