Explorar o código

fix encoder/decoder cast issue

Tao Wen %!s(int64=8) %!d(string=hai) anos
pai
achega
ed79b1726e
Modificáronse 2 ficheiros con 26 adicións e 22 borrados
  1. 14 11
      feature_reflect_extension.go
  2. 12 11
      jsoniter_customize_test.go

+ 14 - 11
feature_reflect_extension.go

@@ -248,17 +248,6 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
 				Decoder:   decoder,
 				Encoder:   encoder,
 			}
-			shouldOmitEmpty := false
-			for _, tagPart := range tagParts[1:] {
-				if tagPart == "omitempty" {
-					shouldOmitEmpty = true
-				} else if tagPart == "string" {
-					binding.Decoder = &stringModeDecoder{binding.Decoder}
-					binding.Encoder = &stringModeEncoder{binding.Encoder}
-				}
-			}
-			binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
-			binding.Encoder = &structFieldEncoder{&field, binding.Encoder, shouldOmitEmpty}
 			bindings = append(bindings, binding)
 		}
 	}
@@ -269,6 +258,20 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
 	for _, extension := range extensions {
 		extension.UpdateStructDescriptor(structDescriptor)
 	}
+	for _, binding := range structDescriptor.Fields {
+		shouldOmitEmpty := false
+		tagParts := strings.Split(binding.Field.Tag.Get("json"), ",")
+		for _, tagPart := range tagParts[1:] {
+			if tagPart == "omitempty" {
+				shouldOmitEmpty = true
+			} else if tagPart == "string" {
+				binding.Decoder = &stringModeDecoder{binding.Decoder}
+				binding.Encoder = &stringModeEncoder{binding.Encoder}
+			}
+		}
+		binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder}
+		binding.Encoder = &structFieldEncoder{binding.Field, binding.Encoder, shouldOmitEmpty}
+	}
 	return structDescriptor, nil
 }
 

+ 12 - 11
jsoniter_customize_test.go

@@ -137,41 +137,42 @@ func Test_customize_field_by_extension(t *testing.T) {
 //	should.Contains(str, `"field-2":"abc"`)
 //}
 
-type ObjectImplementedMarshaler int
+type timeImplementedMarshaler time.Time
 
-func (obj *ObjectImplementedMarshaler) MarshalJSON() ([]byte, error) {
-	return []byte(`"hello"`), nil
+func (obj *timeImplementedMarshaler) MarshalJSON() ([]byte, error) {
+	seconds := time.Time(*obj).Unix()
+	return []byte(strconv.FormatInt(seconds, 10)), nil
 }
 
 func Test_marshaler(t *testing.T) {
 	type TestObject struct {
-		Field *ObjectImplementedMarshaler
+		Field *timeImplementedMarshaler
 	}
 	should := require.New(t)
-	val := ObjectImplementedMarshaler(100)
+	val := timeImplementedMarshaler(time.Unix(123, 0))
 	obj := TestObject{&val}
 	bytes, err := json.Marshal(obj)
 	should.Nil(err)
-	should.Equal(`{"Field":"hello"}`, string(bytes))
+	should.Equal(`{"Field":123}`, string(bytes))
 	str, err := MarshalToString(obj)
 	should.Nil(err)
-	should.Equal(`{"Field":"hello"}`, str)
+	should.Equal(`{"Field":123}`, str)
 }
 
 func Test_marshaler_and_encoder(t *testing.T) {
 	type TestObject struct {
-		Field *ObjectImplementedMarshaler
+		Field *timeImplementedMarshaler
 	}
 	ConfigDefault.cleanEncoders()
 	should := require.New(t)
-	RegisterTypeEncoderFunc("jsoniter.ObjectImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) {
+	RegisterTypeEncoderFunc("jsoniter.timeImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) {
 		stream.WriteString("hello from encoder")
 	}, nil)
-	val := ObjectImplementedMarshaler(100)
+	val := timeImplementedMarshaler(time.Unix(123, 0))
 	obj := TestObject{&val}
 	bytes, err := json.Marshal(obj)
 	should.Nil(err)
-	should.Equal(`{"Field":"hello"}`, string(bytes))
+	should.Equal(`{"Field":123}`, string(bytes))
 	str, err := MarshalToString(obj)
 	should.Nil(err)
 	should.Equal(`{"Field":"hello from encoder"}`, str)