extension_test.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package test
  2. import (
  3. "unsafe"
  4. "strconv"
  5. "testing"
  6. "github.com/stretchr/testify/require"
  7. "github.com/json-iterator/go"
  8. )
  9. type TestObject1 struct {
  10. Field1 string
  11. }
  12. type testExtension struct {
  13. jsoniter.DummyExtension
  14. }
  15. func (extension *testExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
  16. if structDescriptor.Type.String() != "test.TestObject1" {
  17. return
  18. }
  19. binding := structDescriptor.GetField("Field1")
  20. binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
  21. str := *((*string)(ptr))
  22. val, _ := strconv.Atoi(str)
  23. stream.WriteInt(val)
  24. }}
  25. binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  26. *((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
  27. }}
  28. binding.ToNames = []string{"field-1"}
  29. binding.FromNames = []string{"field-1"}
  30. }
  31. func Test_customize_field_by_extension(t *testing.T) {
  32. should := require.New(t)
  33. cfg := jsoniter.Config{}.Froze()
  34. cfg.RegisterExtension(&testExtension{})
  35. obj := TestObject1{}
  36. err := cfg.UnmarshalFromString(`{"field-1": 100}`, &obj)
  37. should.Nil(err)
  38. should.Equal("100", obj.Field1)
  39. str, err := cfg.MarshalToString(obj)
  40. should.Nil(err)
  41. should.Equal(`{"field-1":100}`, str)
  42. }
  43. type funcDecoder struct {
  44. fun jsoniter.DecoderFunc
  45. }
  46. func (decoder *funcDecoder) Decode(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
  47. decoder.fun(ptr, iter)
  48. }
  49. type funcEncoder struct {
  50. fun jsoniter.EncoderFunc
  51. isEmptyFunc func(ptr unsafe.Pointer) bool
  52. }
  53. func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
  54. encoder.fun(ptr, stream)
  55. }
  56. func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *jsoniter.Stream) {
  57. jsoniter.WriteToStream(val, stream, encoder)
  58. }
  59. func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
  60. if encoder.isEmptyFunc == nil {
  61. return false
  62. }
  63. return encoder.isEmptyFunc(ptr)
  64. }