diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go index 88371c7a..32871616 100644 --- a/core/mapping/unmarshaler.go +++ b/core/mapping/unmarshaler.go @@ -457,6 +457,10 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value, map } else { conv.Index(i).Set(target.Elem()) } + case reflect.Slice: + if err := u.fillSlice(dereffedBaseType, conv.Index(i), ithValue); err != nil { + return err + } default: if err := u.fillSliceValue(conv, i, dereffedBaseKind, ithValue); err != nil { return err @@ -498,12 +502,24 @@ func (u *Unmarshaler) fillSliceValue(slice reflect.Value, index int, baseKind re default: // don't need to consider the difference between int, int8, int16, int32, int64, // uint, uint8, uint16, uint32, uint64, because they're handled as json.Number. - if slice.Index(index).Kind() != reflect.TypeOf(value).Kind() { - return errTypeMismatch - } - slice.Index(index).Set(reflect.ValueOf(value)) - return nil + if slice.Index(index).Kind() == reflect.Ptr { + baseType := Deref(slice.Index(index).Type()) + if baseType.Kind() != reflect.TypeOf(value).Kind() { + return errTypeMismatch + } + target := reflect.New(baseType).Elem() + target.Set(reflect.ValueOf(value)) + slice.Index(index).Set(target.Addr()) + return nil + } else { + if slice.Index(index).Kind() != reflect.TypeOf(value).Kind() { + return errTypeMismatch + } + + slice.Index(index).Set(reflect.ValueOf(value)) + return nil + } } } diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go index 94d80e56..143333a0 100644 --- a/core/mapping/unmarshaler_test.go +++ b/core/mapping/unmarshaler_test.go @@ -3,6 +3,7 @@ package mapping import ( "encoding/json" "strconv" + "strings" "testing" "time" @@ -2480,3 +2481,40 @@ func BenchmarkUnmarshal(b *testing.B) { UnmarshalKey(data, &an) } } + +func TestUnmarshalJsonReaderMultiArray(t *testing.T) { + payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}` + var res struct { + A string `json:"a"` + B [][]string `json:"b"` + } + reader := strings.NewReader(payload) + err := UnmarshalJsonReader(reader, &res) + assert.Nil(t, err) + assert.Equal(t, 2, len(res.B)) +} + +func TestUnmarshalJsonReaderPtrMultiArray(t *testing.T) { + payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}` + var res struct { + A string `json:"a"` + B [][]*string `json:"b"` + } + reader := strings.NewReader(payload) + err := UnmarshalJsonReader(reader, &res) + assert.Nil(t, err) + assert.Equal(t, 2, len(res.B)) + assert.Equal(t, 2, len(res.B[0])) +} + +func TestUnmarshalJsonReaderPtrArray(t *testing.T) { + payload := `{"a": "133", "b": ["add", "cccd", "eeee"]}` + var res struct { + A string `json:"a"` + B []*string `json:"b"` + } + reader := strings.NewReader(payload) + err := UnmarshalJsonReader(reader, &res) + assert.Nil(t, err) + assert.Equal(t, 3, len(res.B)) +}