You've already forked json-iterator
							
							
				mirror of
				https://github.com/json-iterator/go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	#101 checkIsEmpty can not reuse createEncoderOfSimpleType, otherwise it will fail when struct member is not serializable
This commit is contained in:
		| @@ -446,7 +446,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error | |||||||
| 		return &base64Codec{typ}, nil | 		return &base64Codec{typ}, nil | ||||||
| 	} | 	} | ||||||
| 	if typ.Implements(marshalerType) { | 	if typ.Implements(marshalerType) { | ||||||
| 		checkIsEmpty, err := createEncoderOfSimpleType(cfg, typ) | 		checkIsEmpty, err := createCheckIsEmpty(typ) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| @@ -461,7 +461,7 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error | |||||||
| 		return encoder, nil | 		return encoder, nil | ||||||
| 	} | 	} | ||||||
| 	if typ.Implements(textMarshalerType) { | 	if typ.Implements(textMarshalerType) { | ||||||
| 		checkIsEmpty, err := createEncoderOfSimpleType(cfg, typ) | 		checkIsEmpty, err := createCheckIsEmpty(typ) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| @@ -481,6 +481,60 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error | |||||||
| 	return createEncoderOfSimpleType(cfg, typ) | 	return createEncoderOfSimpleType(cfg, typ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) { | ||||||
|  | 	kind := typ.Kind() | ||||||
|  | 	switch kind { | ||||||
|  | 	case reflect.String: | ||||||
|  | 		return &stringCodec{}, nil | ||||||
|  | 	case reflect.Int: | ||||||
|  | 		return &intCodec{}, nil | ||||||
|  | 	case reflect.Int8: | ||||||
|  | 		return &int8Codec{}, nil | ||||||
|  | 	case reflect.Int16: | ||||||
|  | 		return &int16Codec{}, nil | ||||||
|  | 	case reflect.Int32: | ||||||
|  | 		return &int32Codec{}, nil | ||||||
|  | 	case reflect.Int64: | ||||||
|  | 		return &int64Codec{}, nil | ||||||
|  | 	case reflect.Uint: | ||||||
|  | 		return &uintCodec{}, nil | ||||||
|  | 	case reflect.Uint8: | ||||||
|  | 		return &uint8Codec{}, nil | ||||||
|  | 	case reflect.Uint16: | ||||||
|  | 		return &uint16Codec{}, nil | ||||||
|  | 	case reflect.Uint32: | ||||||
|  | 		return &uint32Codec{}, nil | ||||||
|  | 	case reflect.Uintptr: | ||||||
|  | 		return &uintptrCodec{}, nil | ||||||
|  | 	case reflect.Uint64: | ||||||
|  | 		return &uint64Codec{}, nil | ||||||
|  | 	case reflect.Float32: | ||||||
|  | 		return &float32Codec{}, nil | ||||||
|  | 	case reflect.Float64: | ||||||
|  | 		return &float64Codec{}, nil | ||||||
|  | 	case reflect.Bool: | ||||||
|  | 		return &boolCodec{}, nil | ||||||
|  | 	case reflect.Interface: | ||||||
|  | 		if typ.NumMethod() == 0 { | ||||||
|  | 			return &emptyInterfaceCodec{}, nil | ||||||
|  | 		} else { | ||||||
|  | 			return &nonEmptyInterfaceCodec{}, nil | ||||||
|  | 		} | ||||||
|  | 	case reflect.Struct: | ||||||
|  | 		return &structEncoder{}, nil | ||||||
|  | 	case reflect.Array: | ||||||
|  | 		return &arrayEncoder{}, nil | ||||||
|  | 	case reflect.Slice: | ||||||
|  | 		return &sliceEncoder{}, nil | ||||||
|  | 	case reflect.Map: | ||||||
|  | 		return &mapEncoder{}, nil | ||||||
|  | 	case reflect.Ptr: | ||||||
|  | 		return &optionalEncoder{}, nil | ||||||
|  | 	default: | ||||||
|  | 		return nil, fmt.Errorf("unsupported type: %v", typ) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { | func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) { | ||||||
| 	typeName := typ.String() | 	typeName := typ.String() | ||||||
| 	kind := typ.Kind() | 	kind := typ.Kind() | ||||||
|   | |||||||
| @@ -118,25 +118,6 @@ func Test_customize_field_by_extension(t *testing.T) { | |||||||
| 	should.Equal(`{"field-1":100}`, str) | 	should.Equal(`{"field-1":100}`, str) | ||||||
| } | } | ||||||
|  |  | ||||||
| //func Test_unexported_fields(t *testing.T) { |  | ||||||
| //	jsoniter := Config{SupportUnexportedStructFields: true}.Froze() |  | ||||||
| //	should := require.New(t) |  | ||||||
| //	type TestObject struct { |  | ||||||
| //		field1 string |  | ||||||
| //		field2 string `json:"field-2"` |  | ||||||
| //	} |  | ||||||
| //	obj := TestObject{} |  | ||||||
| //	obj.field1 = "hello" |  | ||||||
| //	should.Nil(jsoniter.UnmarshalFromString(`{}`, &obj)) |  | ||||||
| //	should.Equal("hello", obj.field1) |  | ||||||
| //	should.Nil(jsoniter.UnmarshalFromString(`{"field1": "world", "field-2": "abc"}`, &obj)) |  | ||||||
| //	should.Equal("world", obj.field1) |  | ||||||
| //	should.Equal("abc", obj.field2) |  | ||||||
| //	str, err := jsoniter.MarshalToString(obj) |  | ||||||
| //	should.Nil(err) |  | ||||||
| //	should.Contains(str, `"field-2":"abc"`) |  | ||||||
| //} |  | ||||||
|  |  | ||||||
| type timeImplementedMarshaler time.Time | type timeImplementedMarshaler time.Time | ||||||
|  |  | ||||||
| func (obj timeImplementedMarshaler) MarshalJSON() ([]byte, error) { | func (obj timeImplementedMarshaler) MarshalJSON() ([]byte, error) { | ||||||
| @@ -238,3 +219,25 @@ func Test_marshaler_on_struct(t *testing.T) { | |||||||
| 	//json.Marshal(fixed) | 	//json.Marshal(fixed) | ||||||
| 	Marshal(fixed) | 	Marshal(fixed) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type withChan struct { | ||||||
|  | 	F2 chan []byte | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (q withChan) MarshalJSON() ([]byte, error) { | ||||||
|  | 	return []byte(`""`), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (q *withChan) UnmarshalJSON(value []byte) error { | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func Test_with_chan(t *testing.T) { | ||||||
|  | 	type TestObject struct { | ||||||
|  | 		F1 withChan | ||||||
|  | 	} | ||||||
|  | 	should := require.New(t) | ||||||
|  | 	output, err := MarshalToString(TestObject{}) | ||||||
|  | 	should.Nil(err) | ||||||
|  | 	should.Equal(`{"F1":""}`, output) | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user