Przeglądaj źródła

#79 fix string tag on string field

Tao Wen 8 lat temu
rodzic
commit
faaa59222a
2 zmienionych plików z 49 dodań i 11 usunięć
  1. 7 2
      feature_reflect_extension.go
  2. 42 9
      feature_reflect_native.go

+ 7 - 2
feature_reflect_extension.go

@@ -277,8 +277,13 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
 			if tagPart == "omitempty" {
 				shouldOmitEmpty = true
 			} else if tagPart == "string" {
-				binding.Decoder = &stringModeDecoder{binding.Decoder}
-				binding.Encoder = &stringModeEncoder{binding.Encoder}
+				if binding.Field.Type.Kind() == reflect.String {
+					binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}
+					binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}
+				} else {
+					binding.Decoder = &stringModeNumberDecoder{binding.Decoder}
+					binding.Encoder = &stringModeNumberEncoder{binding.Encoder}
+				}
 			}
 		}
 		binding.Decoder = &structFieldDecoder{binding.Field, binding.Decoder}

+ 42 - 9
feature_reflect_native.go

@@ -418,7 +418,7 @@ func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	}
 	encoding := base64.StdEncoding
 	src := iter.SkipAndReturnBytes()
-	src = src[1 : len(src)-1]
+	src = src[1: len(src)-1]
 	decodedLen := encoding.DecodedLen(len(src))
 	dst := make([]byte, decodedLen)
 	len, err := encoding.Decode(dst, src)
@@ -469,14 +469,14 @@ func (encoder *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
 	return len(*((*[]byte)(ptr))) == 0
 }
 
-type stringModeDecoder struct {
+type stringModeNumberDecoder struct {
 	elemDecoder ValDecoder
 }
 
-func (decoder *stringModeDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	c := iter.nextToken()
 	if c != '"' {
-		iter.ReportError("stringModeDecoder", `expect "`)
+		iter.ReportError("stringModeNumberDecoder", `expect "`)
 		return
 	}
 	decoder.elemDecoder.Decode(ptr, iter)
@@ -485,26 +485,59 @@ func (decoder *stringModeDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
 	}
 	c = iter.readByte()
 	if c != '"' {
-		iter.ReportError("stringModeDecoder", `expect "`)
+		iter.ReportError("stringModeNumberDecoder", `expect "`)
 		return
 	}
 }
 
-type stringModeEncoder struct {
+type stringModeStringDecoder struct {
+	elemDecoder ValDecoder
+	cfg *frozenConfig
+}
+
+func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	decoder.elemDecoder.Decode(ptr, iter)
+	str := *((*string)(ptr))
+	tempIter := decoder.cfg.BorrowIterator([]byte(str))
+	defer decoder.cfg.ReturnIterator(tempIter)
+	*((*string)(ptr)) = tempIter.ReadString()
+}
+
+type stringModeNumberEncoder struct {
 	elemEncoder ValEncoder
 }
 
-func (encoder *stringModeEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
 	stream.writeByte('"')
 	encoder.elemEncoder.Encode(ptr, stream)
 	stream.writeByte('"')
 }
 
-func (encoder *stringModeEncoder) EncodeInterface(val interface{}, stream *Stream) {
+func (encoder *stringModeNumberEncoder) EncodeInterface(val interface{}, stream *Stream) {
+	WriteToStream(val, stream, encoder)
+}
+
+func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+	return encoder.elemEncoder.IsEmpty(ptr)
+}
+
+type stringModeStringEncoder struct {
+	elemEncoder ValEncoder
+	cfg *frozenConfig
+}
+
+func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
+	tempStream := encoder.cfg.BorrowStream(nil)
+	defer encoder.cfg.ReturnStream(tempStream)
+	encoder.elemEncoder.Encode(ptr, tempStream)
+	stream.WriteString(string(tempStream.Buffer()))
+}
+
+func (encoder *stringModeStringEncoder) EncodeInterface(val interface{}, stream *Stream) {
 	WriteToStream(val, stream, encoder)
 }
 
-func (encoder *stringModeEncoder) IsEmpty(ptr unsafe.Pointer) bool {
+func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
 	return encoder.elemEncoder.IsEmpty(ptr)
 }