mirror of
https://github.com/json-iterator/go.git
synced 2025-04-23 11:37:32 +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 jsonNumberType reflect.Type
|
||||||
|
var jsoniterNumberType reflect.Type
|
||||||
var jsonRawMessageType reflect.Type
|
var jsonRawMessageType reflect.Type
|
||||||
var jsoniterRawMessageType reflect.Type
|
var jsoniterRawMessageType reflect.Type
|
||||||
var anyType reflect.Type
|
var anyType reflect.Type
|
||||||
@ -61,6 +62,7 @@ var textUnmarshalerType reflect.Type
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
|
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
|
||||||
|
jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
|
||||||
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
|
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
|
||||||
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
|
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
|
||||||
anyType = reflect.TypeOf((*Any)(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) {
|
if typ.AssignableTo(jsonNumberType) {
|
||||||
return &jsonNumberCodec{}, nil
|
return &jsonNumberCodec{}, nil
|
||||||
}
|
}
|
||||||
|
if typ.AssignableTo(jsoniterNumberType) {
|
||||||
|
return &jsoniterNumberCodec{}, nil
|
||||||
|
}
|
||||||
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
||||||
sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
|
sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -443,6 +448,9 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
|
|||||||
if typ.AssignableTo(jsonNumberType) {
|
if typ.AssignableTo(jsonNumberType) {
|
||||||
return &jsonNumberCodec{}, nil
|
return &jsonNumberCodec{}, nil
|
||||||
}
|
}
|
||||||
|
if typ.AssignableTo(jsoniterNumberType) {
|
||||||
|
return &jsoniterNumberCodec{}, nil
|
||||||
|
}
|
||||||
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
|
||||||
return &base64Codec{}, nil
|
return &base64Codec{}, nil
|
||||||
}
|
}
|
||||||
|
@ -385,6 +385,25 @@ func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
|
|||||||
return len(*((*json.Number)(ptr))) == 0
|
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 {
|
type jsonRawMessageCodec struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,6 +457,17 @@ func Test_json_number(t *testing.T) {
|
|||||||
should.Equal(`[1]`, str)
|
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) {
|
func Benchmark_jsoniter_encode_int(b *testing.B) {
|
||||||
stream := NewStream(ConfigDefault, ioutil.Discard, 64)
|
stream := NewStream(ConfigDefault, ioutil.Discard, 64)
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user