Skip to content

Commit

Permalink
fix #84
Browse files Browse the repository at this point in the history
Allow to overwrite struct field with empty value in case corresponding source map's key exists and indicated to zero-value
  • Loading branch information
requilence committed Jun 15, 2018
1 parent 9316a62 commit d581347
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
1 change: 1 addition & 0 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, conf
case reflect.Struct:
srcMap := src.Interface().(map[string]interface{})
for key := range srcMap {
config.overwriteWithEmptyValue = true
srcValue := srcMap[key]
fieldName := changeInitialCase(key, unicode.ToUpper)
dstElement := dst.FieldByName(fieldName)
Expand Down
17 changes: 10 additions & 7 deletions merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ func hasExportedField(dst reflect.Value) (exported bool) {
}

type Config struct {
Overwrite bool
AppendSlice bool
Transformers Transformers
Overwrite bool
AppendSlice bool
Transformers Transformers
overwriteWithEmptyValue bool
}

type Transformers interface {
Expand All @@ -39,6 +40,8 @@ type Transformers interface {
// short circuiting on recursive types.
func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
overwrite := config.Overwrite
overwriteWithEmptySrc := config.overwriteWithEmptyValue
config.overwriteWithEmptyValue = false

if !src.IsValid() {
return
Expand Down Expand Up @@ -73,7 +76,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
}
}
} else {
if dst.CanSet() && !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) {
if dst.CanSet() && (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) {
dst.Set(src)
}
}
Expand Down Expand Up @@ -124,7 +127,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
dstSlice = reflect.ValueOf(dstElement.Interface())
}

if !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice {
if (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice {
dstSlice = srcSlice
} else if config.AppendSlice {
dstSlice = reflect.AppendSlice(dstSlice, srcSlice)
Expand All @@ -147,7 +150,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
if !dst.CanSet() {
break
}
if !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice {
if (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice {
dst.Set(src)
} else if config.AppendSlice {
dst.Set(reflect.AppendSlice(dst, src))
Expand Down Expand Up @@ -184,7 +187,7 @@ func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, co
return
}
default:
if dst.CanSet() && !isEmptyValue(src) && (overwrite || isEmptyValue(dst)) {
if dst.CanSet() && (!isEmptyValue(src) || overwriteWithEmptySrc) && (overwrite || isEmptyValue(dst)) {
dst.Set(src)
}
}
Expand Down

0 comments on commit d581347

Please sign in to comment.