Skip to content

Commit

Permalink
Merge pull request #105 from svyotov/fix-panic-on-merge
Browse files Browse the repository at this point in the history
add support for Struct in Map
  • Loading branch information
darccio authored Mar 24, 2020
2 parents 4c8d33a + 8eabc02 commit 66f88b4
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 117 deletions.
2 changes: 1 addition & 1 deletion issue66_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestPrivateSlice(t *testing.T) {
t.Fatalf("Error during the merge: %v", err)
}
if len(p1.PublicStrings) != 3 {
t.Error("5 elements should be in 'PublicStrings' field")
t.Error("3 elements should be in 'PublicStrings' field, when no append")
}
if len(p1.privateStrings) != 2 {
t.Error("2 elements should be in 'privateStrings' field")
Expand Down
50 changes: 50 additions & 0 deletions issue90_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package mergo

import (
"reflect"
"testing"
)

type CustomStruct struct {
SomeMap map[string]string
}

func TestMergoStructMap(t *testing.T) {
var testData = []struct {
name string
src map[string]CustomStruct
dst map[string]CustomStruct
exp map[string]CustomStruct
}{
{name: "Normal",
dst: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "loosethis", "key2": "keepthis"}}},
src: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}},
exp: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10", "key2": "keepthis"}}},
},
{name: "Init of struct key", dst: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{}}},
src: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}},
exp: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}},
},
{name: "Not Init of struct key", dst: map[string]CustomStruct{},
src: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}},
exp: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}},
},
{name: "Nil struct key", dst: map[string]CustomStruct{"a": CustomStruct{SomeMap: nil}},
src: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}},
exp: map[string]CustomStruct{"a": CustomStruct{SomeMap: map[string]string{"key1": "key10"}}}},
}

for _, data := range testData {
dst := data.dst
src := data.src
exp := data.exp

err := Merge(&dst, src, WithAppendSlice, WithOverride)
if err != nil {
t.Errorf("mergo error was not nil, %v", err)
}
if !reflect.DeepEqual(dst, exp) {
t.Errorf("Actual: %#v did not match \nExpected: %#v", dst, exp)
}
}
}
7 changes: 4 additions & 3 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf
continue
}
if srcKind == dstKind {
if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
if _, err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
return
}
} else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {
if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
if _, err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
return
}
} else if srcKind == reflect.Map {
Expand Down Expand Up @@ -157,7 +157,8 @@ func _map(dst, src interface{}, opts ...func(*Config)) error {
// To be friction-less, we redirect equal-type arguments
// to deepMerge. Only because arguments can be anything.
if vSrc.Kind() == vDst.Kind() {
return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
_, err := deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
return err
}
switch vSrc.Kind() {
case reflect.Struct:
Expand Down
Loading

0 comments on commit 66f88b4

Please sign in to comment.