From df0700a1e899196d8020767981b82623c8738932 Mon Sep 17 00:00:00 2001 From: Mike Lundy Date: Tue, 8 May 2018 14:59:37 -0700 Subject: [PATCH] Look through interfaces and pointers when determining emptiness When dealing with map[string]interface{}, the common case for loading arbitrary data from yaml/json, empty strings are not overwritten because they appear as a non-empty interface containing an empty string. This change causes non-nil interfaces to be examined for emptiness. --- mergo.go | 7 ++++++- pr80_test.go | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 pr80_test.go diff --git a/mergo.go b/mergo.go index 785618c..a82fea2 100644 --- a/mergo.go +++ b/mergo.go @@ -45,7 +45,12 @@ func isEmptyValue(v reflect.Value) bool { return v.Uint() == 0 case reflect.Float32, reflect.Float64: return v.Float() == 0 - case reflect.Interface, reflect.Ptr, reflect.Func: + case reflect.Interface, reflect.Ptr: + if v.IsNil() { + return true + } + return isEmptyValue(v.Elem()) + case reflect.Func: return v.IsNil() case reflect.Invalid: return true diff --git a/pr80_test.go b/pr80_test.go new file mode 100644 index 0000000..0b3220f --- /dev/null +++ b/pr80_test.go @@ -0,0 +1,18 @@ +package mergo + +import ( + "testing" +) + +type mapInterface map[string]interface{} + +func TestMergeMapsEmptyString(t *testing.T) { + a := mapInterface{"s": ""} + b := mapInterface{"s": "foo"} + if err := Merge(&a, b); err != nil { + t.Fatal(err) + } + if a["s"] != "foo" { + t.Fatalf("b not merged in properly: a.s.Value(%s) != expected(%s)", a["s"], "foo") + } +}