88// Merge deeply merges two objects
99func Merge (object interface {}, overwriteObject interface {}) {
1010 objectPointerUnsafe := unsafe .Pointer (& object )
11- overwriteObjectPointerUnsafe := unsafe .Pointer ( & overwriteObject )
11+ overwriteObjectPointerUnsafe := * ( * unsafe .Pointer )( unsafe . Pointer ( & overwriteObject ) )
1212
13- merge (object , overwriteObject , objectPointerUnsafe , overwriteObjectPointerUnsafe )
13+ merge (& object , overwriteObject , objectPointerUnsafe , overwriteObjectPointerUnsafe )
1414}
1515
1616func merge (objectPointer interface {}, overwriteObjectPointer interface {}, objectPointerUnsafe unsafe.Pointer , overwriteObjectPointerUnsafe unsafe.Pointer ) {
@@ -20,14 +20,15 @@ func merge(objectPointer interface{}, overwriteObjectPointer interface{}, object
2020 if overwriteObjectRef .Kind () == reflect .Ptr {
2121 overwriteObjectRef = overwriteObjectRef .Elem ()
2222 }
23+ objectPointerReal := reflect .ValueOf (objectPointer ).Elem ().Interface ()
2324 overwriteObject := overwriteObjectRef .Interface ()
2425 overwriteObjectType := reflect .TypeOf (overwriteObject )
2526 overwriteObjectKind := overwriteObjectType .Kind ()
26- objectPointerRef := reflect .ValueOf (objectPointer )
27+ objectPointerRef := reflect .ValueOf (objectPointerReal )
2728 var objectRef reflect.Value
2829
2930 if ! objectPointerRef .IsNil () {
30- objectRef = reflect .ValueOf (objectPointer ).Elem ()
31+ objectRef = reflect .ValueOf (objectPointerReal ).Elem ()
3132 }
3233
3334 switch overwriteObjectKind {
@@ -52,10 +53,10 @@ func merge(objectPointer interface{}, overwriteObjectPointer interface{}, object
5253 overwriteValue := getMapValue (overwriteObject , key , genericPointerType )
5354 valuePointerRef := objectRef .MapIndex (keyRef )
5455
55- if isZero (valuePointerRef ) == false {
56+ if isZero (valuePointerRef ) == false && isTrivialDataType ( valuePointerRef ) {
5657 valuePointer := valuePointerRef .Interface ()
5758
58- merge (valuePointer , overwriteValue , unsafe .Pointer (& valuePointer ), unsafe .Pointer ( & overwriteValue ))
59+ merge (& valuePointer , overwriteValue , unsafe .Pointer (& valuePointer ), * ( * unsafe .Pointer )( unsafe . Pointer ( & overwriteValue ) ))
5960 } else {
6061 keyRef := reflect .ValueOf (key )
6162 overwriteValueRef := reflect .ValueOf (overwriteValue )
@@ -66,25 +67,40 @@ func merge(objectPointer interface{}, overwriteObjectPointer interface{}, object
6667 }
6768 case reflect .Struct :
6869 for i := 0 ; i < overwriteObjectRef .NumField (); i ++ {
69- //fieldName := objectRef.Type().Field(i).Name
7070 overwriteValueRef := overwriteObjectRef .Field (i )
7171 overwriteValuePointerRef := reflect .ValueOf (overwriteValueRef .Interface ())
7272
7373 if ! overwriteValuePointerRef .IsNil () {
7474 overwriteValue := overwriteValueRef .Interface ()
7575 valuePointerRef := objectRef .Field (i )
7676
77- if valuePointerRef .IsNil () {
78- objectRef . Field ( i ) .Set (reflect .ValueOf (overwriteValue ))
77+ if valuePointerRef .IsNil () || isTrivialDataType ( valuePointerRef ) {
78+ valuePointerRef .Set (reflect .ValueOf (overwriteValue ))
7979 } else {
80- valuePointer := objectRef . Field ( i ) .Interface ()
80+ valuePointer := valuePointerRef .Interface ()
8181
82- merge (valuePointer , overwriteValue , unsafe .Pointer (& valuePointer ), unsafe .Pointer ( & overwriteValue ))
82+ merge (& valuePointer , overwriteValue , unsafe .Pointer (& valuePointer ), * ( * unsafe .Pointer )( unsafe . Pointer ( & overwriteValue ) ))
8383 }
8484 }
8585 }
8686 default :
87- * ( * unsafe . Pointer )( objectPointerUnsafe ) = overwriteObjectPointerUnsafe
87+ panic ( "Unable to merge trivial data types" )
8888 }
8989 }
9090}
91+
92+ func isTrivialDataType (value reflect.Value ) bool {
93+ if value .Type ().Kind () == reflect .Ptr {
94+ value = value .Elem ()
95+ }
96+
97+ switch reflect .TypeOf (value ).Kind () {
98+ case reflect .Slice :
99+ return false
100+ case reflect .Map :
101+ return false
102+ case reflect .Struct :
103+ return false
104+ }
105+ return true
106+ }
0 commit comments