diff --git a/feature_reflect_extension.go b/feature_reflect_extension.go index 573adfc..8cb0f5a 100644 --- a/feature_reflect_extension.go +++ b/feature_reflect_extension.go @@ -248,17 +248,6 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err Decoder: decoder, Encoder: encoder, } - shouldOmitEmpty := false - for _, tagPart := range tagParts[1:] { - if tagPart == "omitempty" { - shouldOmitEmpty = true - } else if tagPart == "string" { - binding.Decoder = &stringModeDecoder{binding.Decoder} - binding.Encoder = &stringModeEncoder{binding.Encoder} - } - } - binding.Decoder = &structFieldDecoder{&field, binding.Decoder} - binding.Encoder = &structFieldEncoder{&field, binding.Encoder, shouldOmitEmpty} bindings = append(bindings, binding) } } @@ -269,6 +258,20 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err for _, extension := range extensions { extension.UpdateStructDescriptor(structDescriptor) } + for _, binding := range structDescriptor.Fields { + shouldOmitEmpty := false + tagParts := strings.Split(binding.Field.Tag.Get("json"), ",") + for _, tagPart := range tagParts[1:] { + if tagPart == "omitempty" { + shouldOmitEmpty = true + } else if tagPart == "string" { + binding.Decoder = &stringModeDecoder{binding.Decoder} + binding.Encoder = &stringModeEncoder{binding.Encoder} + } + } + binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder} + binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty} + } return structDescriptor, nil } diff --git a/jsoniter_customize_test.go b/jsoniter_customize_test.go index 35d0a6e..5984313 100644 --- a/jsoniter_customize_test.go +++ b/jsoniter_customize_test.go @@ -137,41 +137,42 @@ func Test_customize_field_by_extension(t *testing.T) { // should.Contains(str, `"field-2":"abc"`) //} -type ObjectImplementedMarshaler int +type timeImplementedMarshaler time.Time -func (obj *ObjectImplementedMarshaler) MarshalJSON() ([]byte, error) { - return []byte(`"hello"`), nil +func (obj *timeImplementedMarshaler) MarshalJSON() ([]byte, error) { + seconds := time.Time(*obj).Unix() + return []byte(strconv.FormatInt(seconds, 10)), nil } func Test_marshaler(t *testing.T) { type TestObject struct { - Field *ObjectImplementedMarshaler + Field *timeImplementedMarshaler } should := require.New(t) - val := ObjectImplementedMarshaler(100) + val := timeImplementedMarshaler(time.Unix(123, 0)) obj := TestObject{&val} bytes, err := json.Marshal(obj) should.Nil(err) - should.Equal(`{"Field":"hello"}`, string(bytes)) + should.Equal(`{"Field":123}`, string(bytes)) str, err := MarshalToString(obj) should.Nil(err) - should.Equal(`{"Field":"hello"}`, str) + should.Equal(`{"Field":123}`, str) } func Test_marshaler_and_encoder(t *testing.T) { type TestObject struct { - Field *ObjectImplementedMarshaler + Field *timeImplementedMarshaler } ConfigDefault.cleanEncoders() should := require.New(t) - RegisterTypeEncoderFunc("jsoniter.ObjectImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) { + RegisterTypeEncoderFunc("jsoniter.timeImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) { stream.WriteString("hello from encoder") }, nil) - val := ObjectImplementedMarshaler(100) + val := timeImplementedMarshaler(time.Unix(123, 0)) obj := TestObject{&val} bytes, err := json.Marshal(obj) should.Nil(err) - should.Equal(`{"Field":"hello"}`, string(bytes)) + should.Equal(`{"Field":123}`, string(bytes)) str, err := MarshalToString(obj) should.Nil(err) should.Equal(`{"Field":"hello from encoder"}`, str)