You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	Always skip unexported fields when encoding
Skip creating encoders for unexported fields. They are not participating in JSON marshaling anyway. This allows using unexported fields of non-marshalable types in structs. As a side-effect of this change it's no longer possible to marshal unexported JSON fields by adding a custom type extenstion. It seems this is desired behavior since it matches standard library and jsoniter already disallows `json:"-"` fields from participating in custom extensions. Fixes #174.
This commit is contained in:
		| @@ -227,6 +227,9 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err | ||||
| 	bindings := []*Binding{} | ||||
| 	for i := 0; i < typ.NumField(); i++ { | ||||
| 		field := typ.Field(i) | ||||
| 		if unicode.IsLower([]rune(field.Name)[0]) { | ||||
| 			continue | ||||
| 		} | ||||
| 		tag := field.Tag.Get(cfg.getTagKey()) | ||||
| 		tagParts := strings.Split(tag, ",") | ||||
| 		if tag == "-" { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
							
								
								
									
										52
									
								
								jsoniter_struct_encoder_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								jsoniter_struct_encoder_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user