Skip to content

Commit

Permalink
Fix empty map or struct convert to another map will return error. (#2863
Browse files Browse the repository at this point in the history
)
  • Loading branch information
joy999 authored Aug 17, 2023
1 parent ed4d155 commit 24ee534
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
10 changes: 6 additions & 4 deletions util/gconv/gconv_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,22 @@ const (
// tags that will be detected, otherwise it detects the tags in order of:
// gconv, json, field name.
func Map(value interface{}, tags ...string) map[string]interface{} {
return doMapConvert(value, recursiveTypeAuto, tags...)
return doMapConvert(value, recursiveTypeAuto, false, tags...)
}

// MapDeep does Map function recursively, which means if the attribute of `value`
// is also a struct/*struct, calls Map function on this attribute converting it to
// a map[string]interface{} type variable.
// Also see Map.
func MapDeep(value interface{}, tags ...string) map[string]interface{} {
return doMapConvert(value, recursiveTypeTrue, tags...)
return doMapConvert(value, recursiveTypeTrue, false, tags...)
}

// doMapConvert implements the map converting.
// It automatically checks and converts json string to map if `value` is string/[]byte.
//
// TODO completely implement the recursive converting for all types, especially the map.
func doMapConvert(value interface{}, recursive recursiveType, tags ...string) map[string]interface{} {
func doMapConvert(value interface{}, recursive recursiveType, mustMapReturn bool, tags ...string) map[string]interface{} {
if value == nil {
return nil
}
Expand Down Expand Up @@ -209,6 +209,7 @@ func doMapConvert(value interface{}, recursive recursiveType, tags ...string) ma
RecursiveType: recursive,
RecursiveOption: recursive == recursiveTypeTrue,
Tags: newTags,
MustMapReturn: mustMapReturn,
},
)
if m, ok := convertedValue.(map[string]interface{}); ok {
Expand All @@ -228,6 +229,7 @@ type doMapConvertForMapOrStructValueInput struct {
RecursiveType recursiveType // The type from top function entry.
RecursiveOption bool // Whether convert recursively for `current` operation.
Tags []string // Map key mapping.
MustMapReturn bool // Must return map instead of Value when empty.
}

func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) interface{} {
Expand Down Expand Up @@ -468,7 +470,7 @@ func doMapConvertForMapOrStructValue(in doMapConvertForMapOrStructValueInput) in
}
}
}
if len(dataMap) == 0 {
if !in.MustMapReturn && len(dataMap) == 0 {
return in.Value
}
return dataMap
Expand Down
2 changes: 1 addition & 1 deletion util/gconv/gconv_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func doStruct(params interface{}, pointer interface{}, mapping map[string]string

// paramsMap is the map[string]interface{} type variable for params.
// DO NOT use MapDeep here.
paramsMap := Map(paramsInterface)
paramsMap := doMapConvert(paramsInterface, recursiveTypeAuto, true)
if paramsMap == nil {
return gerror.NewCodef(
gcode.CodeInvalidParameter,
Expand Down
50 changes: 50 additions & 0 deletions util/gconv/gconv_z_unit_struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1349,3 +1349,53 @@ func Test_Struct_WithCustomType(t *testing.T) {
t.Assert(*req2.PayMode, 1000)
})
}

func Test_Struct_EmptyStruct(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var err error

type StructA struct {
}

type StructB struct {
}

var s1 StructA
var s2 *StructB

err = gconv.Scan(s1, &s2)
t.AssertNil(err)

err = gconv.Scan(&s1, &s2)
t.AssertNil(err)

type StructC struct {
Val int `json:"val,omitempty"`
}

type StructD struct {
Val int
}

var s3 StructC
var s4 *StructD

err = gconv.Scan(s3, &s4)
t.AssertNil(err)
t.Assert(s4.Val, 0)

err = gconv.Scan(&s3, &s4)
t.AssertNil(err)
t.Assert(s4.Val, 0)

s3.Val = 123
err = gconv.Scan(s3, &s4)
t.AssertNil(err)
t.Assert(s4.Val, 123)

err = gconv.Scan(&s3, &s4)
t.AssertNil(err)
t.Assert(s4.Val, 123)

})
}

0 comments on commit 24ee534

Please sign in to comment.