@@ -34,7 +34,7 @@ func getJsonUnmarshaler(opts ...UnmarshalOption) *Unmarshaler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalJsonBytes(content []byte, v interface{}, unmarshaler *Unmarshaler) error {
|
func unmarshalJsonBytes(content []byte, v interface{}, unmarshaler *Unmarshaler) error {
|
||||||
var m map[string]interface{}
|
var m interface{}
|
||||||
if err := jsonx.Unmarshal(content, &m); err != nil {
|
if err := jsonx.Unmarshal(content, &m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ func unmarshalJsonBytes(content []byte, v interface{}, unmarshaler *Unmarshaler)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalJsonReader(reader io.Reader, v interface{}, unmarshaler *Unmarshaler) error {
|
func unmarshalJsonReader(reader io.Reader, v interface{}, unmarshaler *Unmarshaler) error {
|
||||||
var m map[string]interface{}
|
var m interface{}
|
||||||
if err := jsonx.UnmarshalFromReader(reader, &m); err != nil {
|
if err := jsonx.UnmarshalFromReader(reader, &m); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -856,8 +856,7 @@ func TestUnmarshalBytesError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err := UnmarshalJsonBytes([]byte(payload), &v)
|
err := UnmarshalJsonBytes([]byte(payload), &v)
|
||||||
assert.NotNil(t, err)
|
assert.Equal(t, errTypeMismatch, err)
|
||||||
assert.True(t, strings.Contains(err.Error(), payload))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmarshalReaderError(t *testing.T) {
|
func TestUnmarshalReaderError(t *testing.T) {
|
||||||
@@ -867,9 +866,7 @@ func TestUnmarshalReaderError(t *testing.T) {
|
|||||||
Any string
|
Any string
|
||||||
}
|
}
|
||||||
|
|
||||||
err := UnmarshalJsonReader(reader, &v)
|
assert.Equal(t, errTypeMismatch, UnmarshalJsonReader(reader, &v))
|
||||||
assert.NotNil(t, err)
|
|
||||||
assert.True(t, strings.Contains(err.Error(), payload))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmarshalMap(t *testing.T) {
|
func TestUnmarshalMap(t *testing.T) {
|
||||||
@@ -920,3 +917,16 @@ func TestUnmarshalMap(t *testing.T) {
|
|||||||
assert.Equal(t, "foo", v.Any)
|
assert.Equal(t, "foo", v.Any)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalJsonArray(t *testing.T) {
|
||||||
|
var v []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
}
|
||||||
|
|
||||||
|
body := `[{"name":"kevin", "age": 18}]`
|
||||||
|
assert.NoError(t, UnmarshalJsonBytes([]byte(body), &v))
|
||||||
|
assert.Equal(t, 1, len(v))
|
||||||
|
assert.Equal(t, "kevin", v[0].Name)
|
||||||
|
assert.Equal(t, 18, v[0].Age)
|
||||||
|
}
|
||||||
|
|||||||
@@ -71,8 +71,29 @@ func UnmarshalKey(m map[string]interface{}, v interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal unmarshals m into v.
|
// Unmarshal unmarshals m into v.
|
||||||
func (u *Unmarshaler) Unmarshal(m map[string]interface{}, v interface{}) error {
|
func (u *Unmarshaler) Unmarshal(i interface{}, v interface{}) error {
|
||||||
return u.UnmarshalValuer(mapValuer(m), v)
|
valueType := reflect.TypeOf(v)
|
||||||
|
if valueType.Kind() != reflect.Ptr {
|
||||||
|
return errValueNotSettable
|
||||||
|
}
|
||||||
|
|
||||||
|
elemType := valueType.Elem()
|
||||||
|
switch iv := i.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
if elemType.Kind() != reflect.Struct {
|
||||||
|
return errTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.UnmarshalValuer(mapValuer(iv), v)
|
||||||
|
case []interface{}:
|
||||||
|
if elemType.Kind() != reflect.Slice {
|
||||||
|
return errTypeMismatch
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.fillSlice(elemType, reflect.ValueOf(v).Elem(), iv)
|
||||||
|
default:
|
||||||
|
return errUnsupportedType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalValuer unmarshals m into v.
|
// UnmarshalValuer unmarshals m into v.
|
||||||
|
|||||||
@@ -23,7 +23,14 @@ func TestUnmarshalWithFullNameNotStruct(t *testing.T) {
|
|||||||
var s map[string]interface{}
|
var s map[string]interface{}
|
||||||
content := []byte(`{"name":"xiaoming"}`)
|
content := []byte(`{"name":"xiaoming"}`)
|
||||||
err := UnmarshalJsonBytes(content, &s)
|
err := UnmarshalJsonBytes(content, &s)
|
||||||
assert.Equal(t, errValueNotStruct, err)
|
assert.Equal(t, errTypeMismatch, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalValueNotSettable(t *testing.T) {
|
||||||
|
var s map[string]interface{}
|
||||||
|
content := []byte(`{"name":"xiaoming"}`)
|
||||||
|
err := UnmarshalJsonBytes(content, s)
|
||||||
|
assert.Equal(t, errValueNotSettable, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnmarshalWithoutTagName(t *testing.T) {
|
func TestUnmarshalWithoutTagName(t *testing.T) {
|
||||||
|
|||||||
@@ -223,6 +223,22 @@ func TestParseJsonBody(t *testing.T) {
|
|||||||
assert.Equal(t, "", v.Name)
|
assert.Equal(t, "", v.Name)
|
||||||
assert.Equal(t, 0, v.Age)
|
assert.Equal(t, 0, v.Age)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("array body", func(t *testing.T) {
|
||||||
|
var v []struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
}
|
||||||
|
|
||||||
|
body := `[{"name":"kevin", "age": 18}]`
|
||||||
|
r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body))
|
||||||
|
r.Header.Set(ContentType, header.JsonContentType)
|
||||||
|
|
||||||
|
assert.NoError(t, ParseJsonBody(r, &v))
|
||||||
|
assert.Equal(t, 1, len(v))
|
||||||
|
assert.Equal(t, "kevin", v[0].Name)
|
||||||
|
assert.Equal(t, 18, v[0].Age)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseRequired(t *testing.T) {
|
func TestParseRequired(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user