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
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface).Elem()
if realVal.IsNil() {
realVal.Set(reflect.MakeMap(realVal.Type()))
}
for field := iter.ReadObject(); field != ""; field = iter.ReadObject() {
elem := reflect.New(decoder.elemType)
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]}
}
}
encoder, err := encoderOfType(field.Type)
if err != nil {
return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
}
// map is stored as pointer in the struct
// but if struct only has one map, it is inlined
if field.Type.Kind() == reflect.Map && typ.NumField() > 1 {
encoder = &optionalEncoder{field.Type, encoder}
var encoder Encoder
if len(fieldNames) > 0 {
encoder, err := encoderOfType(field.Type)
if err != nil {
return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
}
// map is stored as pointer in the struct
// 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 {
if structEncoder_.firstField == nil {
@ -85,7 +88,7 @@ func decoderOfStruct(typ reflect.Type) (Decoder, error) {
fieldNames = []string{tagParts[0]}
}
}
if decoder == nil {
if decoder == nil && len(fieldNames) > 0 {
var err error
decoder, err = decoderOfType(field.Type)
if err != nil {

View File

@ -3,6 +3,7 @@ package jsoniter
import (
"testing"
"github.com/json-iterator/go/require"
"bytes"
)
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) {
should := require.New(t)
type TestObject struct {
field1 string
field2 string
field3 string
field4 string
field5 string
field6 string
field7 string
field8 string
field9 string
field1 string
field2 string
field3 string
field4 string
field5 string
field6 string
field7 string
field8 string
field9 string
field10 string
}
obj := TestObject{}
@ -144,3 +145,17 @@ func Test_write_val_one_field_struct(t *testing.T) {
should.Nil(err)
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"])
}