Skip to content
This repository was archived by the owner on Dec 15, 2025. It is now read-only.

Commit 1cfa233

Browse files
committed
#143 make jsoniter.Number same meaning as json.Number, however UseNumber still returns json.Number. 1.9 alias support should be added later
1 parent d249b05 commit 1cfa233

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

feature_json_number.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package jsoniter
2+
3+
import "encoding/json"
4+
5+
type Number string
6+
7+
func CastJsonNumber(val interface{}) (string, bool) {
8+
switch typedVal := val.(type) {
9+
case json.Number:
10+
return string(typedVal), true
11+
case Number:
12+
return string(typedVal), true
13+
}
14+
return "", false
15+
}

feature_reflect.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
5151
}
5252

5353
var jsonNumberType reflect.Type
54+
var jsoniterNumberType reflect.Type
5455
var jsonRawMessageType reflect.Type
5556
var jsoniterRawMessageType reflect.Type
5657
var anyType reflect.Type
@@ -61,6 +62,7 @@ var textUnmarshalerType reflect.Type
6162

6263
func init() {
6364
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
65+
jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
6466
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
6567
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
6668
anyType = reflect.TypeOf((*Any)(nil)).Elem()
@@ -280,6 +282,9 @@ func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error
280282
if typ.AssignableTo(jsonNumberType) {
281283
return &jsonNumberCodec{}, nil
282284
}
285+
if typ.AssignableTo(jsoniterNumberType) {
286+
return &jsoniterNumberCodec{}, nil
287+
}
283288
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
284289
sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
285290
if err != nil {
@@ -443,6 +448,9 @@ func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error
443448
if typ.AssignableTo(jsonNumberType) {
444449
return &jsonNumberCodec{}, nil
445450
}
451+
if typ.AssignableTo(jsoniterNumberType) {
452+
return &jsoniterNumberCodec{}, nil
453+
}
446454
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
447455
return &base64Codec{}, nil
448456
}

feature_reflect_native.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,25 @@ func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
385385
return len(*((*json.Number)(ptr))) == 0
386386
}
387387

388+
type jsoniterNumberCodec struct {
389+
}
390+
391+
func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
392+
*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
393+
}
394+
395+
func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
396+
stream.WriteRaw(string(*((*Number)(ptr))))
397+
}
398+
399+
func (codec *jsoniterNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
400+
stream.WriteRaw(string(val.(Number)))
401+
}
402+
403+
func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
404+
return len(*((*Number)(ptr))) == 0
405+
}
406+
388407
type jsonRawMessageCodec struct {
389408
}
390409

jsoniter_int_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,17 @@ func Test_json_number(t *testing.T) {
457457
should.Equal(`[1]`, str)
458458
}
459459

460+
func Test_jsoniter_number(t *testing.T) {
461+
should := require.New(t)
462+
var arr []Number
463+
err := Unmarshal([]byte(`[1]`), &arr)
464+
should.Nil(err)
465+
should.Equal(Number("1"), arr[0])
466+
str, isNumber := CastJsonNumber(arr[0])
467+
should.True(isNumber)
468+
should.Equal("1", str)
469+
}
470+
460471
func Benchmark_jsoniter_encode_int(b *testing.B) {
461472
stream := NewStream(ConfigDefault, ioutil.Discard, 64)
462473
for n := 0; n < b.N; n++ {

0 commit comments

Comments
 (0)