123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- package test
- import (
- "github.com/json-iterator/go"
- "github.com/modern-go/reflect2"
- "github.com/stretchr/testify/require"
- "reflect"
- "strconv"
- "testing"
- "unsafe"
- )
- type TestObject1 struct {
- Field1 string
- }
- type testExtension struct {
- jsoniter.DummyExtension
- }
- func (extension *testExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
- if structDescriptor.Type.String() != "test.TestObject1" {
- return
- }
- binding := structDescriptor.GetField("Field1")
- binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
- str := *((*string)(ptr))
- val, _ := strconv.Atoi(str)
- stream.WriteInt(val)
- }}
- binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
- *((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
- }}
- binding.ToNames = []string{"field-1"}
- binding.FromNames = []string{"field-1"}
- }
- func Test_customize_field_by_extension(t *testing.T) {
- should := require.New(t)
- cfg := jsoniter.Config{}.Froze()
- cfg.RegisterExtension(&testExtension{})
- obj := TestObject1{}
- err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj)
- should.Nil(err)
- should.Equal("100", obj.Field1)
- str, err := cfg.MarshalToString(obj)
- should.Nil(err)
- should.Equal(`{"field-1":100}`, str)
- }
- func Test_customize_map_key_encoder(t *testing.T) {
- should := require.New(t)
- cfg := jsoniter.Config{}.Froze()
- cfg.RegisterExtension(&testMapKeyExtension{})
- m := map[int]int{1: 2}
- output, err := cfg.MarshalToString(m)
- should.NoError(err)
- should.Equal(`{"2":2}`, output)
- m = map[int]int{}
- should.NoError(cfg.UnmarshalFromString(output, &m))
- should.Equal(map[int]int{1: 2}, m)
- }
- type testMapKeyExtension struct {
- jsoniter.DummyExtension
- }
- func (extension *testMapKeyExtension) CreateMapKeyEncoder(typ reflect2.Type) jsoniter.ValEncoder {
- if typ.Kind() == reflect.Int {
- return &funcEncoder{
- fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
- stream.WriteRaw(`"`)
- stream.WriteInt(*(*int)(ptr) + 1)
- stream.WriteRaw(`"`)
- },
- }
- }
- return nil
- }
- func (extension *testMapKeyExtension) CreateMapKeyDecoder(typ reflect2.Type) jsoniter.ValDecoder {
- if typ.Kind() == reflect.Int {
- return &funcDecoder{
- fun: func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
- i, err := strconv.Atoi(iter.ReadString())
- if err != nil {
- iter.ReportError("read map key", err.Error())
- return
- }
- i--
- *(*int)(ptr) = i
- },
- }
- }
- return nil
- }
- type funcDecoder struct {
- fun jsoniter.DecoderFunc
- }
- func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
- decoder.fun(ptr, iter)
- }
- type funcEncoder struct {
- fun jsoniter.EncoderFunc
- isEmptyFunc func(ptr unsafe.Pointer) bool
- }
- func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
- encoder.fun(ptr, stream)
- }
- func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
- if encoder.isEmptyFunc == nil {
- return false
- }
- return encoder.isEmptyFunc(ptr)
- }
|