You've already forked json-iterator
mirror of
https://github.com/json-iterator/go.git
synced 2025-06-24 23:16:47 +02:00
#102 create correct type when pointer to Marshaler/Unmarshaler is nil
This commit is contained in:
@ -288,8 +288,8 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
|
|||||||
if typ.Implements(unmarshalerType) {
|
if typ.Implements(unmarshalerType) {
|
||||||
templateInterface := reflect.New(typ).Elem().Interface()
|
templateInterface := reflect.New(typ).Elem().Interface()
|
||||||
var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
|
var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
|
||||||
if typ.Kind() != reflect.Struct {
|
if typ.Kind() == reflect.Ptr {
|
||||||
decoder = &optionalDecoder{typ, decoder}
|
decoder = &optionalDecoder{typ.Elem(), decoder}
|
||||||
}
|
}
|
||||||
return decoder, nil
|
return decoder, nil
|
||||||
}
|
}
|
||||||
@ -301,8 +301,8 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
|
|||||||
if typ.Implements(textUnmarshalerType) {
|
if typ.Implements(textUnmarshalerType) {
|
||||||
templateInterface := reflect.New(typ).Elem().Interface()
|
templateInterface := reflect.New(typ).Elem().Interface()
|
||||||
var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
|
var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
|
||||||
if typ.Kind() != reflect.Struct {
|
if typ.Kind() == reflect.Ptr {
|
||||||
decoder = &optionalDecoder{typ, decoder}
|
decoder = &optionalDecoder{typ.Elem(), decoder}
|
||||||
}
|
}
|
||||||
return decoder, nil
|
return decoder, nil
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ func (q *withChan) UnmarshalJSON(value []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_with_chan(t *testing.T) {
|
func Test_marshal_json_with_chan(t *testing.T) {
|
||||||
type TestObject struct {
|
type TestObject struct {
|
||||||
F1 withChan
|
F1 withChan
|
||||||
}
|
}
|
||||||
@ -240,4 +240,48 @@ func Test_with_chan(t *testing.T) {
|
|||||||
output, err := MarshalToString(TestObject{})
|
output, err := MarshalToString(TestObject{})
|
||||||
should.Nil(err)
|
should.Nil(err)
|
||||||
should.Equal(`{"F1":""}`, output)
|
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)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user