diff --git a/feature_reflect.go b/feature_reflect.go index 4c06897..211f50a 100644 --- a/feature_reflect.go +++ b/feature_reflect.go @@ -288,8 +288,8 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error if typ.Implements(unmarshalerType) { templateInterface := reflect.New(typ).Elem().Interface() var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)} - if typ.Kind() != reflect.Struct { - decoder = &optionalDecoder{typ, decoder} + if typ.Kind() == reflect.Ptr { + decoder = &optionalDecoder{typ.Elem(), decoder} } return decoder, nil } @@ -301,8 +301,8 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error if typ.Implements(textUnmarshalerType) { templateInterface := reflect.New(typ).Elem().Interface() var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)} - if typ.Kind() != reflect.Struct { - decoder = &optionalDecoder{typ, decoder} + if typ.Kind() == reflect.Ptr { + decoder = &optionalDecoder{typ.Elem(), decoder} } return decoder, nil } diff --git a/jsoniter_customize_test.go b/jsoniter_customize_test.go index 416afcc..ca51180 100644 --- a/jsoniter_customize_test.go +++ b/jsoniter_customize_test.go @@ -232,7 +232,7 @@ func (q *withChan) UnmarshalJSON(value []byte) error { return nil } -func Test_with_chan(t *testing.T) { +func Test_marshal_json_with_chan(t *testing.T) { type TestObject struct { F1 withChan } @@ -240,4 +240,48 @@ func Test_with_chan(t *testing.T) { output, err := MarshalToString(TestObject{}) should.Nil(err) should.Equal(`{"F1":""}`, output) -} \ No newline at end of file +} + +type withTime struct { + time.Time +} + +func (t *withTime) UnmarshalJSON(b []byte) error { + return nil +} +func (t withTime) MarshalJSON() ([]byte, error) { + return []byte(`"fake"`), nil +} + +func Test_marshal_json_with_time(t *testing.T) { + type S1 struct { + F1 withTime + F2 *withTime + } + type TestObject struct { + TF1 S1 + } + should := require.New(t) + obj := TestObject{ + S1{ + F1: withTime{ + time.Unix(0, 0), + }, + F2: &withTime{ + time.Unix(0, 0), + }, + }, + } + output, err := json.Marshal(obj) + should.Nil(err) + should.Equal(`{"TF1":{"F1":"fake","F2":"fake"}}`, string(output)) + output, err = Marshal(obj) + should.Nil(err) + should.Equal(`{"TF1":{"F1":"fake","F2":"fake"}}`, string(output)) + obj = TestObject{} + should.Nil(json.Unmarshal([]byte(`{"TF1":{"F1":"fake","F2":"fake"}}`), &obj)) + should.NotNil(obj.TF1.F2) + obj = TestObject{} + should.Nil(Unmarshal([]byte(`{"TF1":{"F1":"fake","F2":"fake"}}`), &obj)) + should.NotNil(obj.TF1.F2) +}