in utils/json.go [70:149]
func UpdateObject(old interface{}, new interface{}, option UpdateJsonOption) interface{} {
if reflect.DeepEqual(old, new) {
return old
}
switch oldValue := old.(type) {
case map[string]interface{}:
if newMap, ok := new.(map[string]interface{}); ok {
res := make(map[string]interface{})
for key, value := range oldValue {
switch {
case newMap[key] != nil:
res[key] = UpdateObject(value, newMap[key], option)
case option.IgnoreMissingProperty || isZeroValue(value):
res[key] = value
}
}
return res
}
case []interface{}:
if newArr, ok := new.([]interface{}); ok {
if len(oldValue) == 0 {
return new
}
hasIdentifier := identifierOfArrayItem(oldValue[0]) != ""
if !hasIdentifier {
if len(oldValue) != len(newArr) {
return newArr
}
res := make([]interface{}, 0)
for index := range oldValue {
res = append(res, UpdateObject(oldValue[index], newArr[index], option))
}
return res
}
res := make([]interface{}, 0)
used := make([]bool, len(newArr))
for _, oldItem := range oldValue {
found := false
for index, newItem := range newArr {
if reflect.DeepEqual(oldItem, newItem) && !used[index] {
res = append(res, UpdateObject(oldItem, newItem, option))
used[index] = true
found = true
break
}
}
if found {
continue
}
for index, newItem := range newArr {
if areSameArrayItems(oldItem, newItem) && !used[index] {
res = append(res, UpdateObject(oldItem, newItem, option))
used[index] = true
break
}
}
}
for index, newItem := range newArr {
if !used[index] {
res = append(res, newItem)
}
}
return res
}
case string:
if newStr, ok := new.(string); ok {
if option.IgnoreCasing && strings.EqualFold(oldValue, newStr) {
return oldValue
}
if option.IgnoreMissingProperty && (regexp.MustCompile(`^\*+$`).MatchString(newStr) || "<redacted>" == newStr || "" == newStr) {
return oldValue
}
}
}
return new
}