There is a bug in how jsonToStruct parses maps and slices.
jefferyjob opened this issue · 1 comments
jefferyjob commented
There is a bug in how jsonToStruct parses maps and slices.
- Does not support parsing map type
- Parse the slice type, if the data type is inconsistent, panic error
type Target struct {
Followed map[string]bool `json:"followed"`
Fids []string `json:"fids"`
}
func TestJsonToStruct(t *testing.T) {
data := `
{
"followed": {
"43015653": true,
"43015666": false
},
"fids": ["43015653",43015666]
}
`
var event Target
err := JsonToStruct(data, &event)
fmt.Printf("%+v, err:%s \n", event, err)
}
The specific error description is as follows
panic: reflect.Set: value of type float64 is not assignable to type string [recovered]
panic: reflect.Set: value of type float64 is not assignable to type string
jefferyjob commented
已修复该问题,单元测试验证代码如下:
验证内容包括:
- 验证string的数字转义为int
- 验证int转义为string
- 验证切片中存在多种数据类型,和数据类型不一致的转义
- 验证map数据类型是否解析正确,和数据类型不一致的转义
- 验证切片中包含结构体,和数据类型不一致的转义
- 验证map中包含结构体,和数据类型不一致的转义
func TestJsonToStructMoreNest2(t *testing.T) {
var jsonData = `
{
"uid": 666,
"use_id": ["hello", 5, 9],
"age": "20",
"equip": {
"keyMike": true,
"keyTom": false
},
"happy": {
"k1": [1, 2, 3],
"k2": [4, 5, 6]
},
"slices": [{
"nickname": "ABC",
"money": "20"
}, {
"nickname": "EFG",
"money": "22"
}],
"maps": {
"m1": {
"name": "alis",
"age": "20"
},
"m2": {
"name": "jom",
"age": "22"
}
}
}
`
type SliceVal struct {
Nickname string `json:"nickname"`
Money int `json:"money"`
}
type MapVal struct {
Name string `json:"name"`
Age int `json:"age"`
}
type Target struct {
Uid int `json:"uid"`
UseId []string `json:"use_id"`
Age int `json:"age"`
Equip map[string]bool `json:"equip"`
Happy map[string][]int `json:"happy"`
Slices []SliceVal `json:"slices"`
Maps map[string]MapVal `json:"maps"`
}
var res Target
err := JsonToStruct(jsonData, &res)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
//jsonRes, _ := json.Marshal(res)
//fmt.Printf("%+v \n", res)
//fmt.Println(string(jsonRes))
expected := Target{
Uid: 666,
UseId: []string{"hello", "5", "9"},
Age: 20,
Equip: map[string]bool{
"keyMike": true,
"keyTom": false,
},
Happy: map[string][]int{
"k1": {1, 2, 3},
"k2": {4, 5, 6},
},
Slices: []SliceVal{
{
Nickname: "ABC",
Money: 20,
},
{
Nickname: "EFG",
Money: 22,
},
},
Maps: map[string]MapVal{
"m1": {
Name: "alis",
Age: 20,
},
"m2": {
Name: "jom",
Age: 22,
},
},
}
if !reflect.DeepEqual(res, expected) {
t.Errorf("Result not as expected.\nExpected: %+v\nActual: %+v\n", expected, res)
}
}