gojay

high performance JSON encoder/decoder with stream API for Golang
git clone git://git.lair.cx/gojay
Log | Files | Refs | README | LICENSE

commit dc6a3b6c7a636104a5dc118dd848a2812a5fa8ff
parent bf5c9d91c10918ce5ef0762a113ca076611f7281
Author: francoispqt <francois@parquet.ninja>
Date:   Sat, 23 Mar 2019 00:43:38 +0800

add decode slices built ins

Diffstat:
Adecode_slices.go | 133+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adecode_slices_test.go | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 258 insertions(+), 0 deletions(-)

diff --git a/decode_slices.go b/decode_slices.go @@ -0,0 +1,133 @@ +package gojay + +// SliceString is a *[]string implementing gojay.UnmarshalerJSONArray interface +type SliceString []string + +// UnmarshalJSONArray implements gojay.UnmarshalerJSONArray +func (s *SliceString) UnmarshalJSONArray(dec *Decoder) error { + var str string + if err := dec.String(&str); err != nil { + return err + } + *s = append(*s, str) + return nil +} + +// IsNil implements gojay.UnmarshalerJSONArray +func (s *SliceString) IsNil() bool { + return s == nil || len(*s) == 0 +} + +// AddSliceString unmarshals the next JSON array of strings to the given *[]string s +func (dec *Decoder) AddSliceString(s *[]string) error { + return dec.SliceString(s) +} + +// SliceString unmarshals the next JSON array of strings to the given *[]string s +func (dec *Decoder) SliceString(s *[]string) error { + var st = SliceString(*s) + if err := dec.Array(&st); err != nil { + return err + } + *s = st + return nil +} + +// SliceInt is a *[]int implementing gojay.UnmarshalerJSONArray interface +type SliceInt []int + +// UnmarshalJSONArray implements gojay.UnmarshalerJSONArray +func (s *SliceInt) UnmarshalJSONArray(dec *Decoder) error { + var i int + if err := dec.Int(&i); err != nil { + return err + } + *s = append(*s, i) + return nil +} + +// IsNil implements gojay.UnmarshalerJSONArray +func (s *SliceInt) IsNil() bool { + return s == nil || len(*s) == 0 +} + +// AddInt unmarshals the next JSON array of integers to the given *[]int s +func (dec *Decoder) AddSliceInt(s *[]int) error { + return dec.SliceInt(s) +} + +// SliceInt unmarshals the next JSON array of integers to the given *[]int s +func (dec *Decoder) SliceInt(s *[]int) error { + var st = SliceInt(*s) + if err := dec.Array(&st); err != nil { + return err + } + *s = st + return nil +} + +// SliceFloat64 is a *[]float64 implementing gojay.UnmarshalerJSONArray interface +type SliceFloat64 []float64 + +// UnmarshalJSONArray implements gojay.UnmarshalerJSONArray +func (s *SliceFloat64) UnmarshalJSONArray(dec *Decoder) error { + var i float64 + if err := dec.Float64(&i); err != nil { + return err + } + *s = append(*s, i) + return nil +} + +// IsNil implements gojay.UnmarshalerJSONArray +func (s *SliceFloat64) IsNil() bool { + return s == nil || len(*s) == 0 +} + +// AddFloat64 unmarshals the next JSON array of floats to the given *[]float64 s +func (dec *Decoder) AddSliceFloat64(s *[]float64) error { + return dec.SliceFloat64(s) +} + +// SliceFloat64 unmarshals the next JSON array of floats to the given *[]float64 s +func (dec *Decoder) SliceFloat64(s *[]float64) error { + var st = SliceFloat64(*s) + if err := dec.Array(&st); err != nil { + return err + } + *s = st + return nil +} + +// SliceBool is a *[]bool implementing gojay.UnmarshalerJSONArray boolerface +type SliceBool []bool + +// UnmarshalJSONArray implements gojay.UnmarshalerJSONArray +func (s *SliceBool) UnmarshalJSONArray(dec *Decoder) error { + var i bool + if err := dec.Bool(&i); err != nil { + return err + } + *s = append(*s, i) + return nil +} + +// IsNil implements gojay.UnmarshalerJSONArray +func (s *SliceBool) IsNil() bool { + return s == nil || len(*s) == 0 +} + +// AddBool unmarshals the next JSON array of boolegers to the given *[]bool s +func (dec *Decoder) AddSliceBool(s *[]bool) error { + return dec.SliceBool(s) +} + +// SliceBool unmarshals the next JSON array of boolegers to the given *[]bool s +func (dec *Decoder) SliceBool(s *[]bool) error { + var st = SliceBool(*s) + if err := dec.Array(&st); err != nil { + return err + } + *s = st + return nil +} diff --git a/decode_slices_test.go b/decode_slices_test.go @@ -0,0 +1,125 @@ +package gojay + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +type slicesTestObject struct { + sliceString []string + sliceInt []int + sliceFloat64 []float64 + sliceBool []bool +} + +func (s *slicesTestObject) UnmarshalJSONObject(dec *Decoder, k string) error { + switch k { + case "sliceString": + return dec.AddSliceString(&s.sliceString) + case "sliceInt": + return dec.AddSliceInt(&s.sliceInt) + case "sliceFloat64": + return dec.AddSliceFloat64(&s.sliceFloat64) + case "sliceBool": + return dec.AddSliceBool(&s.sliceBool) + } + return nil +} + +func (s *slicesTestObject) NKeys() int { + return 4 +} + +func TestDecodeSlices(t *testing.T) { + testCases := []struct { + name string + json string + expectedResult slicesTestObject + err bool + }{ + { + name: "basic slice string", + json: `{ + "sliceString": ["foo","bar"] + }`, + expectedResult: slicesTestObject{ + sliceString: []string{"foo", "bar"}, + }, + }, + { + name: "basic slice bool", + json: `{ + "sliceBool": [true,false] + }`, + expectedResult: slicesTestObject{ + sliceBool: []bool{true, false}, + }, + }, + { + name: "basic slice int", + json: `{ + "sliceInt": [1,2,3] + }`, + expectedResult: slicesTestObject{ + sliceInt: []int{1, 2, 3}, + }, + }, + { + name: "basic slice float64", + json: `{ + "sliceFloat64": [1.3,2.4,3.1] + }`, + expectedResult: slicesTestObject{ + sliceFloat64: []float64{1.3, 2.4, 3.1}, + }, + }, + { + name: "err slice float64", + json: `{ + "sliceFloat64": ["",2.4,3.1] + }`, + err: true, + }, + { + name: "err slice str", + json: `{ + "sliceString": [1,2.4,3.1] + }`, + err: true, + }, + { + name: "err slice int", + json: `{ + "sliceInt": [true,2.4,3.1] + }`, + err: true, + }, + { + name: "err slice bool", + json: `{ + "sliceBool": [1,2.4,3.1] + }`, + err: true, + }, + } + + for _, testCase := range testCases { + t.Run( + testCase.name, + func(t *testing.T) { + dec := BorrowDecoder(strings.NewReader(testCase.json)) + var o slicesTestObject + err := dec.Decode(&o) + + if testCase.err { + require.NotNil(t, err, "err should not be nil") + return + } + require.Nil(t, err, "err should be nil") + require.Equal(t, testCase.expectedResult, o) + }, + ) + } +}