1
0
mirror of https://github.com/json-iterator/go.git synced 2025-01-17 18:44:50 +02:00

#102 create correct type when pointer to Marshaler/Unmarshaler is nil

This commit is contained in:
Tao Wen 2017-07-02 11:35:30 +08:00
parent 815aa331a8
commit bf002a02be
2 changed files with 50 additions and 6 deletions

View File

@ -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
}

View File

@ -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)
}
}
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)
}