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:
parent
d249b05a85
commit
1cfa233923
15
feature_json_number.go
Normal file
15
feature_json_number.go
Normal 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
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
||||
|
||||
|
@ -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++ {
|
||||
|
Loading…
x
Reference in New Issue
Block a user