1
0
mirror of https://github.com/json-iterator/go.git synced 2025-01-23 18:54:21 +02:00

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

This commit is contained in:
Tao Wen 2017-08-05 07:22:53 +08:00
parent d249b05a85
commit 1cfa233923
4 changed files with 53 additions and 0 deletions

15
feature_json_number.go Normal file
View File

@ -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
}

View File

@ -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
}

View File

@ -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 {
}

View File

@ -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++ {