From 59e71bacc8304cf5111bc81be29fba118a0c455c Mon Sep 17 00:00:00 2001 From: Tao Wen Date: Fri, 2 Jun 2017 16:52:20 +0800 Subject: [PATCH] #36 handle anonymous --- feature_reflect_object.go | 29 ++++++++++++++++++++++------- jsoniter_demo_test.go | 2 +- jsoniter_reflect_struct_test.go | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/feature_reflect_object.go b/feature_reflect_object.go index cd7da3c..807a03f 100644 --- a/feature_reflect_object.go +++ b/feature_reflect_object.go @@ -11,12 +11,12 @@ import ( func encoderOfStruct(typ reflect.Type) (Encoder, error) { structEncoder_ := &structEncoder{} - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) + fields := map[string]*structFieldEncoder{} + for _, field := range listStructFields(typ) { fieldEncoderKey := fmt.Sprintf("%s/%s", typ.String(), field.Name) var extensionProvidedFieldNames []string for _, extension := range extensions { - alternativeFieldNames, fun, _ := extension(typ, &field) + alternativeFieldNames, fun, _ := extension(typ, field) if alternativeFieldNames != nil { extensionProvidedFieldNames = alternativeFieldNames } @@ -46,16 +46,31 @@ func encoderOfStruct(typ reflect.Type) (Encoder, error) { } } for _, fieldName := range fieldNames { - structEncoder_.fields = append(structEncoder_.fields, - &structFieldEncoder{&field, fieldName, encoder, omitempty}) - } + fields[fieldName] = &structFieldEncoder{field, fieldName, encoder, omitempty} + } } - if len(structEncoder_.fields) == 0 { + if len(fields) == 0 { return &emptyStructEncoder{}, nil } + for _, field := range fields { + structEncoder_.fields = append(structEncoder_.fields, field) + } return structEncoder_, nil } +func listStructFields(typ reflect.Type) []*reflect.StructField { + fields := []*reflect.StructField{} + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + if field.Anonymous { + fields = append(fields, listStructFields(field.Type)...) + } else { + fields = append(fields, &field) + } + } + return fields +} + func decoderOfStruct(typ reflect.Type) (Decoder, error) { fields := map[string]*structFieldDecoder{} for i := 0; i < typ.NumField(); i++ { diff --git a/jsoniter_demo_test.go b/jsoniter_demo_test.go index b94e1b1..e90502c 100644 --- a/jsoniter_demo_test.go +++ b/jsoniter_demo_test.go @@ -21,4 +21,4 @@ func Test_iterator_api_demo(t *testing.T) { total += iter.ReadInt() } fmt.Println(total) -} \ No newline at end of file +} diff --git a/jsoniter_reflect_struct_test.go b/jsoniter_reflect_struct_test.go index 27a6c0e..04f8328 100644 --- a/jsoniter_reflect_struct_test.go +++ b/jsoniter_reflect_struct_test.go @@ -223,3 +223,18 @@ func Test_one_field_struct(t *testing.T) { should.Nil(err) should.Equal(`{"Me":{"Field":{"Field":{"Field":"abc"}}}}`, str) } + +func Test_anonymous_struct_marshal(t *testing.T) { + should := require.New(t) + type TestObject struct { + Field string + } + str, err := MarshalToString(struct{ + TestObject + Field int + }{ + Field: 100, + }) + should.Nil(err) + should.Equal(`{"Field":100}`, str) +} \ No newline at end of file