diff --git a/feature_reflect_extension.go b/feature_reflect_extension.go index 3dd3829..74f4b8b 100644 --- a/feature_reflect_extension.go +++ b/feature_reflect_extension.go @@ -269,7 +269,7 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err if decoder == nil { var err error decoder, err = decoderOfType(cfg, field.Type) - if err != nil { + if len(fieldNames) > 0 && err != nil { return nil, err } } @@ -277,11 +277,11 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err if encoder == nil { var err error encoder, err = encoderOfType(cfg, field.Type) - if err != nil { + if len(fieldNames) > 0 && err != nil { return nil, err } // map is stored as pointer in the struct - if field.Type.Kind() == reflect.Map { + if encoder != nil && field.Type.Kind() == reflect.Map { encoder = &optionalEncoder{encoder} } } diff --git a/jsoniter_customize_test.go b/jsoniter_customize_test.go index b4bf529..628f89e 100644 --- a/jsoniter_customize_test.go +++ b/jsoniter_customize_test.go @@ -2,11 +2,12 @@ package jsoniter import ( "encoding/json" - "github.com/stretchr/testify/require" "strconv" "testing" "time" "unsafe" + + "github.com/stretchr/testify/require" ) func Test_customize_type_decoder(t *testing.T) { @@ -82,7 +83,7 @@ func Test_customize_field_decoder(t *testing.T) { } type TestObject1 struct { - field1 string + Field1 string } type testExtension struct { @@ -93,7 +94,7 @@ func (extension *testExtension) UpdateStructDescriptor(structDescriptor *StructD if structDescriptor.Type.String() != "jsoniter.TestObject1" { return } - binding := structDescriptor.GetField("field1") + binding := structDescriptor.GetField("Field1") binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *Stream) { str := *((*string)(ptr)) val, _ := strconv.Atoi(str) @@ -112,7 +113,7 @@ func Test_customize_field_by_extension(t *testing.T) { obj := TestObject1{} err := UnmarshalFromString(`{"field-1": 100}`, &obj) should.Nil(err) - should.Equal("100", obj.field1) + should.Equal("100", obj.Field1) str, err := MarshalToString(obj) should.Nil(err) should.Equal(`{"field-1":100}`, str) diff --git a/jsoniter_struct_encoder_test.go b/jsoniter_struct_encoder_test.go new file mode 100644 index 0000000..0e3e541 --- /dev/null +++ b/jsoniter_struct_encoder_test.go @@ -0,0 +1,52 @@ +package jsoniter + +import ( + "encoding/json" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func Test_encode_unexported_field(t *testing.T) { + type TestData struct { + a int + b <-chan int + C int + d *time.Timer + } + + should := require.New(t) + + testChan := make(<-chan int, 10) + testTimer := time.NewTimer(10 * time.Second) + + obj := &TestData{ + a: 42, + b: testChan, + C: 21, + d: testTimer, + } + + jb, err := json.Marshal(obj) + should.NoError(err) + should.Equal([]byte(`{"C":21}`), jb) + + err = json.Unmarshal([]byte(`{"a": 444, "b":"bad", "C":55, "d":{"not": "a timer"}}`), obj) + should.NoError(err) + should.Equal(42, obj.a) + should.Equal(testChan, obj.b) + should.Equal(55, obj.C) + should.Equal(testTimer, obj.d) + + jb, err = Marshal(obj) + should.NoError(err) + should.Equal(jb, []byte(`{"C":55}`)) + + err = Unmarshal([]byte(`{"a": 444, "b":"bad", "C":256, "d":{"not":"a timer"}}`), obj) + should.NoError(err) + should.Equal(42, obj.a) + should.Equal(testChan, obj.b) + should.Equal(256, obj.C) + should.Equal(testTimer, obj.d) +}