Ver código fonte

#143 make jsoniter.Number same meaning as json.Number, however UseNumber still returns json.Number. 1.9 alias support should be added later

Tao Wen 8 anos atrás
pai
commit
1cfa233923
4 arquivos alterados com 53 adições e 0 exclusões
  1. 15 0
      feature_json_number.go
  2. 8 0
      feature_reflect.go
  3. 19 0
      feature_reflect_native.go
  4. 11 0
      jsoniter_int_test.go

+ 15 - 0
feature_json_number.go

@@ -0,0 +1,15 @@
+package jsoniter
+
+import "encoding/json"
+
+type Number string
+
+func CastJsonNumber(val interface{}) (string, bool) {
+	switch typedVal := val.(type) {
+	case json.Number:
+		return string(typedVal), true
+	case Number:
+		return string(typedVal), true
+	}
+	return "", false
+}

+ 8 - 0
feature_reflect.go

@@ -51,6 +51,7 @@ func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
 }
 
 var jsonNumberType reflect.Type
+var jsoniterNumberType reflect.Type
 var jsonRawMessageType reflect.Type
 var jsoniterRawMessageType reflect.Type
 var anyType reflect.Type
@@ -61,6 +62,7 @@ var textUnmarshalerType reflect.Type
 
 func init() {
 	jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
+	jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
 	jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
 	jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
 	anyType = reflect.TypeOf((*Any)(nil)).Elem()
@@ -280,6 +282,9 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
 	if typ.AssignableTo(jsonNumberType) {
 		return &jsonNumberCodec{}, nil
 	}
+	if typ.AssignableTo(jsoniterNumberType) {
+		return &jsoniterNumberCodec{}, nil
+	}
 	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
 		sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
 		if err != nil {
@@ -443,6 +448,9 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
 	if typ.AssignableTo(jsonNumberType) {
 		return &jsonNumberCodec{}, nil
 	}
+	if typ.AssignableTo(jsoniterNumberType) {
+		return &jsoniterNumberCodec{}, nil
+	}
 	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
 		return &base64Codec{}, nil
 	}

+ 19 - 0
feature_reflect_native.go

@@ -385,6 +385,25 @@ func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
 	return len(*((*json.Number)(ptr))) == 0
 }
 
+type jsoniterNumberCodec struct {
+}
+
+func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
+	*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
+}
+
+func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
+	stream.WriteRaw(string(*((*Number)(ptr))))
+}
+
+func (codec *jsoniterNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
+	stream.WriteRaw(string(val.(Number)))
+}
+
+func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
+	return len(*((*Number)(ptr))) == 0
+}
+
 type jsonRawMessageCodec struct {
 }
 

+ 11 - 0
jsoniter_int_test.go

@@ -457,6 +457,17 @@ func Test_json_number(t *testing.T) {
 	should.Equal(`[1]`, str)
 }
 
+func Test_jsoniter_number(t *testing.T) {
+	should := require.New(t)
+	var arr []Number
+	err := Unmarshal([]byte(`[1]`), &arr)
+	should.Nil(err)
+	should.Equal(Number("1"), arr[0])
+	str, isNumber := CastJsonNumber(arr[0])
+	should.True(isNumber)
+	should.Equal("1", str)
+}
+
 func Benchmark_jsoniter_encode_int(b *testing.B) {
 	stream := NewStream(ConfigDefault, ioutil.Discard, 64)
 	for n := 0; n < b.N; n++ {