From 081bb96dd52549df9eff8b1b91c2d503fe52a465 Mon Sep 17 00:00:00 2001 From: pipi-lv <1447191636@qq.com> Date: Tue, 27 Sep 2022 10:56:10 +0800 Subject: [PATCH 1/3] chore: add string to map in httpx parse method --- core/mapping/unmarshaler.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go index 497a9db8130c..d8c71b7b3432 100644 --- a/core/mapping/unmarshaler.go +++ b/core/mapping/unmarshaler.go @@ -207,6 +207,8 @@ func (u *Unmarshaler) processFieldNotFromString(field reflect.StructField, value return u.fillMap(field, value, mapValue) case valueKind == reflect.String && typeKind == reflect.Slice: return u.fillSliceFromString(fieldType, value, mapValue) + case valueKind == reflect.String && typeKind == reflect.Map: + return u.fillMapFromString(value, mapValue) case valueKind == reflect.String && derefedFieldType == durationType: return fillDurationValue(fieldType.Kind(), value, mapValue.(string)) default: @@ -530,6 +532,23 @@ func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect. return nil } +func (u *Unmarshaler) fillMapFromString(value reflect.Value, mapValue interface{}) error { + switch v := mapValue.(type) { + case fmt.Stringer: + if err := jsonx.UnmarshalFromString(v.String(), value.Addr().Interface()); err != nil { + return err + } + case string: + if err := jsonx.UnmarshalFromString(v, value.Addr().Interface()); err != nil { + return err + } + default: + return errUnsupportedType + } + + return nil +} + func (u *Unmarshaler) fillSliceValue(slice reflect.Value, index int, baseKind reflect.Kind, value interface{}) error { ithVal := slice.Index(index) From 2f461d04d1c8b745b774fe53f4ff7b61a678c00b Mon Sep 17 00:00:00 2001 From: pipi-lv <1447191636@qq.com> Date: Wed, 28 Sep 2022 10:59:46 +0800 Subject: [PATCH 2/3] feat: add httpx parse stringToMap method test --- core/mapping/unmarshaler_test.go | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go index 2efed6259655..9e91432dc785 100644 --- a/core/mapping/unmarshaler_test.go +++ b/core/mapping/unmarshaler_test.go @@ -467,6 +467,39 @@ func TestUnmarshalIntSliceFromString(t *testing.T) { ast.Equal(2, v.Values[1]) } +func TestUnmarshalStringMapFromString(t *testing.T) { + var v struct { + Sort map[string]string `key:"sort"` + } + m := map[string]interface{}{ + "sort": `{"value":"ascend","emptyStr":""}`, + } + + ast := assert.New(t) + ast.Nil(UnmarshalKey(m, &v)) + ast.Equal(2, len(v.Sort)) + ast.Equal("ascend", v.Sort["value"]) + ast.Equal("", v.Sort["emptyStr"]) +} + +func TestUnmarshalStringSliceMapFromString(t *testing.T) { + var v struct { + Filter map[string][]string `key:"filter"` + } + m := map[string]interface{}{ + "filter": `{"assignType":null,"status":["process","comment"],"rate":[]}`, + } + + ast := assert.New(t) + ast.Nil(UnmarshalKey(m, &v)) + ast.Equal(3, len(v.Filter)) + ast.Equal([]string(nil), v.Filter["assignType"]) + ast.Equal(2, len(v.Filter["status"])) + ast.Equal("process", v.Filter["status"][0]) + ast.Equal("comment", v.Filter["status"][1]) + ast.Equal(0, len(v.Filter["rate"])) +} + func TestUnmarshalStruct(t *testing.T) { type address struct { City string `key:"city"` From 23e65b94f1cc79111f90b293c3ac6e4e6a657ab4 Mon Sep 17 00:00:00 2001 From: pipi-lv <1447191636@qq.com> Date: Fri, 30 Sep 2022 15:29:25 +0800 Subject: [PATCH 3/3] fix: add more test --- core/mapping/unmarshaler_test.go | 106 +++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go index 9e91432dc785..fe4c4375dc48 100644 --- a/core/mapping/unmarshaler_test.go +++ b/core/mapping/unmarshaler_test.go @@ -2,6 +2,7 @@ package mapping import ( "encoding/json" + "fmt" "strconv" "strings" "testing" @@ -467,6 +468,85 @@ func TestUnmarshalIntSliceFromString(t *testing.T) { ast.Equal(2, v.Values[1]) } +func TestUnmarshalIntMapFromString(t *testing.T) { + var v struct { + Sort map[string]int `key:"sort"` + } + m := map[string]interface{}{ + "sort": `{"value":12345,"zeroVal":0,"nullVal":null}`, + } + + ast := assert.New(t) + ast.Nil(UnmarshalKey(m, &v)) + ast.Equal(3, len(v.Sort)) + ast.Equal(12345, v.Sort["value"]) + ast.Equal(0, v.Sort["zeroVal"]) + ast.Equal(0, v.Sort["nullVal"]) +} + +func TestUnmarshalBoolMapFromString(t *testing.T) { + var v struct { + Sort map[string]bool `key:"sort"` + } + m := map[string]interface{}{ + "sort": `{"value":true,"zeroVal":false,"nullVal":null}`, + } + + ast := assert.New(t) + ast.Nil(UnmarshalKey(m, &v)) + ast.Equal(3, len(v.Sort)) + ast.Equal(true, v.Sort["value"]) + ast.Equal(false, v.Sort["zeroVal"]) + ast.Equal(false, v.Sort["nullVal"]) +} + +type CustomStringer string + +type UnsupportedStringer string + +func (c CustomStringer) String() string { + return fmt.Sprintf("{%s}", string(c)) +} + +func TestUnmarshalStringMapFromStringer(t *testing.T) { + var v struct { + Sort map[string]string `key:"sort"` + } + m := map[string]interface{}{ + "sort": CustomStringer(`"value":"ascend","emptyStr":""`), + } + + ast := assert.New(t) + ast.Nil(UnmarshalKey(m, &v)) + ast.Equal(2, len(v.Sort)) + ast.Equal("ascend", v.Sort["value"]) + ast.Equal("", v.Sort["emptyStr"]) +} + +func TestUnmarshalStringMapFromUnsupportedType(t *testing.T) { + var v struct { + Sort map[string]string `key:"sort"` + } + m := map[string]interface{}{ + "sort": UnsupportedStringer(`{"value":"ascend","emptyStr":""}`), + } + + ast := assert.New(t) + ast.NotNil(UnmarshalKey(m, &v)) +} + +func TestUnmarshalStringMapFromNotSettableValue(t *testing.T) { + var v struct { + sort map[string]string `key:"sort"` + } + m := map[string]interface{}{ + "sort": `{"value":"ascend","emptyStr":""}`, + } + + ast := assert.New(t) + ast.NotNil(UnmarshalKey(m, &v)) +} + func TestUnmarshalStringMapFromString(t *testing.T) { var v struct { Sort map[string]string `key:"sort"` @@ -482,6 +562,32 @@ func TestUnmarshalStringMapFromString(t *testing.T) { ast.Equal("", v.Sort["emptyStr"]) } +func TestUnmarshalStructMapFromString(t *testing.T) { + var v struct { + Filter map[string]struct { + Field1 bool `json:"field1"` + Field2 int64 `json:"field2,string"` + Field3 string `json:"field3"` + Field4 *string `json:"field4"` + Field5 []string `json:"field5"` + } `key:"filter"` + } + m := map[string]interface{}{ + "filter": `{"obj":{"field1":true,"field2":"1573570455447539712","field3":"this is a string", + "field4":"this is a string pointer","field5":["str1","str2"]}}`, + } + + ast := assert.New(t) + ast.Nil(UnmarshalKey(m, &v)) + ast.Equal(1, len(v.Filter)) + ast.NotNil(v.Filter["obj"]) + ast.Equal(true, v.Filter["obj"].Field1) + ast.Equal(int64(1573570455447539712), v.Filter["obj"].Field2) + ast.Equal("this is a string", v.Filter["obj"].Field3) + ast.Equal("this is a string pointer", *v.Filter["obj"].Field4) + ast.ElementsMatch([]string{"str1", "str2"}, v.Filter["obj"].Field5) +} + func TestUnmarshalStringSliceMapFromString(t *testing.T) { var v struct { Filter map[string][]string `key:"filter"`