merge.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. // Copyright 2013 Dario Castañé. All rights reserved.
  2. // Copyright 2009 The Go Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style
  4. // license that can be found in the LICENSE file.
  5. // Based on src/pkg/reflect/deepequal.go from official
  6. // golang's stdlib.
  7. package mergo
  8. import (
  9. "fmt"
  10. "reflect"
  11. )
  12. func hasMergeableFields(dst reflect.Value) (exported bool) {
  13. for i, n := 0, dst.NumField(); i < n; i++ {
  14. field := dst.Type().Field(i)
  15. if field.Anonymous && dst.Field(i).Kind() == reflect.Struct {
  16. exported = exported || hasMergeableFields(dst.Field(i))
  17. } else if isExportedComponent(&field) {
  18. exported = exported || len(field.PkgPath) == 0
  19. }
  20. }
  21. return
  22. }
  23. func isExportedComponent(field *reflect.StructField) bool {
  24. pkgPath := field.PkgPath
  25. if len(pkgPath) > 0 {
  26. return false
  27. }
  28. c := field.Name[0]
  29. if 'a' <= c && c <= 'z' || c == '_' {
  30. return false
  31. }
  32. return true
  33. }
  34. type Config struct {
  35. Overwrite bool
  36. AppendSlice bool
  37. TypeCheck bool
  38. Transformers Transformers
  39. overwriteWithEmptyValue bool
  40. overwriteSliceWithEmptyValue bool
  41. sliceDeepCopy bool
  42. debug bool
  43. }
  44. type Transformers interface {
  45. Transformer(reflect.Type) func(dst, src reflect.Value) error
  46. }
  47. // Traverses recursively both values, assigning src's fields values to dst.
  48. // The map argument tracks comparisons that have already been seen, which allows
  49. // short circuiting on recursive types.
  50. func deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {
  51. overwrite := config.Overwrite
  52. typeCheck := config.TypeCheck
  53. overwriteWithEmptySrc := config.overwriteWithEmptyValue
  54. overwriteSliceWithEmptySrc := config.overwriteSliceWithEmptyValue
  55. sliceDeepCopy := config.sliceDeepCopy
  56. if !src.IsValid() {
  57. return
  58. }
  59. if dst.CanAddr() {
  60. addr := dst.UnsafeAddr()
  61. h := 17 * addr
  62. seen := visited[h]
  63. typ := dst.Type()
  64. for p := seen; p != nil; p = p.next {
  65. if p.ptr == addr && p.typ == typ {
  66. return nil
  67. }
  68. }
  69. // Remember, remember...
  70. visited[h] = &visit{addr, typ, seen}
  71. }
  72. if config.Transformers != nil && !isEmptyValue(dst) {
  73. if fn := config.Transformers.Transformer(dst.Type()); fn != nil {
  74. err = fn(dst, src)
  75. return
  76. }
  77. }
  78. switch dst.Kind() {
  79. case reflect.Struct:
  80. if hasMergeableFields(dst) {
  81. for i, n := 0, dst.NumField(); i < n; i++ {
  82. if err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, config); err != nil {
  83. return
  84. }
  85. }
  86. } else {
  87. if (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {
  88. dst.Set(src)
  89. }
  90. }
  91. case reflect.Map:
  92. if dst.IsNil() && !src.IsNil() {
  93. dst.Set(reflect.MakeMap(dst.Type()))
  94. }
  95. if src.Kind() != reflect.Map {
  96. if overwrite {
  97. dst.Set(src)
  98. }
  99. return
  100. }
  101. for _, key := range src.MapKeys() {
  102. srcElement := src.MapIndex(key)
  103. if !srcElement.IsValid() {
  104. continue
  105. }
  106. dstElement := dst.MapIndex(key)
  107. switch srcElement.Kind() {
  108. case reflect.Chan, reflect.Func, reflect.Map, reflect.Interface, reflect.Slice:
  109. if srcElement.IsNil() {
  110. if overwrite {
  111. dst.SetMapIndex(key, srcElement)
  112. }
  113. continue
  114. }
  115. fallthrough
  116. default:
  117. if !srcElement.CanInterface() {
  118. continue
  119. }
  120. switch reflect.TypeOf(srcElement.Interface()).Kind() {
  121. case reflect.Struct:
  122. fallthrough
  123. case reflect.Ptr:
  124. fallthrough
  125. case reflect.Map:
  126. srcMapElm := srcElement
  127. dstMapElm := dstElement
  128. if srcMapElm.CanInterface() {
  129. srcMapElm = reflect.ValueOf(srcMapElm.Interface())
  130. if dstMapElm.IsValid() {
  131. dstMapElm = reflect.ValueOf(dstMapElm.Interface())
  132. }
  133. }
  134. if err = deepMerge(dstMapElm, srcMapElm, visited, depth+1, config); err != nil {
  135. return
  136. }
  137. case reflect.Slice:
  138. srcSlice := reflect.ValueOf(srcElement.Interface())
  139. var dstSlice reflect.Value
  140. if !dstElement.IsValid() || dstElement.IsNil() {
  141. dstSlice = reflect.MakeSlice(srcSlice.Type(), 0, srcSlice.Len())
  142. } else {
  143. dstSlice = reflect.ValueOf(dstElement.Interface())
  144. }
  145. if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy {
  146. if typeCheck && srcSlice.Type() != dstSlice.Type() {
  147. return fmt.Errorf("cannot override two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type())
  148. }
  149. dstSlice = srcSlice
  150. } else if config.AppendSlice {
  151. if srcSlice.Type() != dstSlice.Type() {
  152. return fmt.Errorf("cannot append two slices with different type (%s, %s)", srcSlice.Type(), dstSlice.Type())
  153. }
  154. dstSlice = reflect.AppendSlice(dstSlice, srcSlice)
  155. } else if sliceDeepCopy {
  156. i := 0
  157. for ; i < srcSlice.Len() && i < dstSlice.Len(); i++ {
  158. srcElement := srcSlice.Index(i)
  159. dstElement := dstSlice.Index(i)
  160. if srcElement.CanInterface() {
  161. srcElement = reflect.ValueOf(srcElement.Interface())
  162. }
  163. if dstElement.CanInterface() {
  164. dstElement = reflect.ValueOf(dstElement.Interface())
  165. }
  166. if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
  167. return
  168. }
  169. }
  170. }
  171. dst.SetMapIndex(key, dstSlice)
  172. }
  173. }
  174. if dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) {
  175. continue
  176. }
  177. if srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement)) {
  178. if dst.IsNil() {
  179. dst.Set(reflect.MakeMap(dst.Type()))
  180. }
  181. dst.SetMapIndex(key, srcElement)
  182. }
  183. }
  184. case reflect.Slice:
  185. if !dst.CanSet() {
  186. break
  187. }
  188. if (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy {
  189. dst.Set(src)
  190. } else if config.AppendSlice {
  191. if src.Type() != dst.Type() {
  192. return fmt.Errorf("cannot append two slice with different type (%s, %s)", src.Type(), dst.Type())
  193. }
  194. dst.Set(reflect.AppendSlice(dst, src))
  195. } else if sliceDeepCopy {
  196. for i := 0; i < src.Len() && i < dst.Len(); i++ {
  197. srcElement := src.Index(i)
  198. dstElement := dst.Index(i)
  199. if srcElement.CanInterface() {
  200. srcElement = reflect.ValueOf(srcElement.Interface())
  201. }
  202. if dstElement.CanInterface() {
  203. dstElement = reflect.ValueOf(dstElement.Interface())
  204. }
  205. if err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {
  206. return
  207. }
  208. }
  209. }
  210. case reflect.Ptr:
  211. fallthrough
  212. case reflect.Interface:
  213. if isReflectNil(src) {
  214. if overwriteWithEmptySrc && dst.CanSet() && src.Type().AssignableTo(dst.Type()) {
  215. dst.Set(src)
  216. }
  217. break
  218. }
  219. if src.Kind() != reflect.Interface {
  220. if dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) {
  221. if dst.CanSet() && (overwrite || isEmptyValue(dst)) {
  222. dst.Set(src)
  223. }
  224. } else if src.Kind() == reflect.Ptr {
  225. if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
  226. return
  227. }
  228. } else if dst.Elem().Type() == src.Type() {
  229. if err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil {
  230. return
  231. }
  232. } else {
  233. return ErrDifferentArgumentsTypes
  234. }
  235. break
  236. }
  237. if dst.IsNil() || overwrite {
  238. if dst.CanSet() && (overwrite || isEmptyValue(dst)) {
  239. dst.Set(src)
  240. }
  241. break
  242. }
  243. if dst.Elem().Kind() == src.Elem().Kind() {
  244. if err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {
  245. return
  246. }
  247. break
  248. }
  249. default:
  250. mustSet := (isEmptyValue(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc)
  251. if mustSet {
  252. if dst.CanSet() {
  253. dst.Set(src)
  254. } else {
  255. dst = src
  256. }
  257. }
  258. }
  259. return
  260. }
  261. // Merge will fill any empty for value type attributes on the dst struct using corresponding
  262. // src attributes if they themselves are not empty. dst and src must be valid same-type structs
  263. // and dst must be a pointer to struct.
  264. // It won't merge unexported (private) fields and will do recursively any exported field.
  265. func Merge(dst, src interface{}, opts ...func(*Config)) error {
  266. return merge(dst, src, opts...)
  267. }
  268. // MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overridden by
  269. // non-empty src attribute values.
  270. // Deprecated: use Merge(…) with WithOverride
  271. func MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {
  272. return merge(dst, src, append(opts, WithOverride)...)
  273. }
  274. // WithTransformers adds transformers to merge, allowing to customize the merging of some types.
  275. func WithTransformers(transformers Transformers) func(*Config) {
  276. return func(config *Config) {
  277. config.Transformers = transformers
  278. }
  279. }
  280. // WithOverride will make merge override non-empty dst attributes with non-empty src attributes values.
  281. func WithOverride(config *Config) {
  282. config.Overwrite = true
  283. }
  284. // WithOverwriteWithEmptyValue will make merge override non empty dst attributes with empty src attributes values.
  285. func WithOverwriteWithEmptyValue(config *Config) {
  286. config.Overwrite = true
  287. config.overwriteWithEmptyValue = true
  288. }
  289. // WithOverrideEmptySlice will make merge override empty dst slice with empty src slice.
  290. func WithOverrideEmptySlice(config *Config) {
  291. config.overwriteSliceWithEmptyValue = true
  292. }
  293. // WithAppendSlice will make merge append slices instead of overwriting it.
  294. func WithAppendSlice(config *Config) {
  295. config.AppendSlice = true
  296. }
  297. // WithTypeCheck will make merge check types while overwriting it (must be used with WithOverride).
  298. func WithTypeCheck(config *Config) {
  299. config.TypeCheck = true
  300. }
  301. // WithSliceDeepCopy will merge slice element one by one with Overwrite flag.
  302. func WithSliceDeepCopy(config *Config) {
  303. config.sliceDeepCopy = true
  304. config.Overwrite = true
  305. }
  306. func merge(dst, src interface{}, opts ...func(*Config)) error {
  307. if dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {
  308. return ErrNonPointerAgument
  309. }
  310. var (
  311. vDst, vSrc reflect.Value
  312. err error
  313. )
  314. config := &Config{}
  315. for _, opt := range opts {
  316. opt(config)
  317. }
  318. if vDst, vSrc, err = resolveValues(dst, src); err != nil {
  319. return err
  320. }
  321. if vDst.Type() != vSrc.Type() {
  322. return ErrDifferentArgumentsTypes
  323. }
  324. return deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)
  325. }
  326. // IsReflectNil is the reflect value provided nil
  327. func isReflectNil(v reflect.Value) bool {
  328. k := v.Kind()
  329. switch k {
  330. case reflect.Interface, reflect.Slice, reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr:
  331. // Both interface and slice are nil if first word is 0.
  332. // Both are always bigger than a word; assume flagIndir.
  333. return v.IsNil()
  334. default:
  335. return false
  336. }
  337. }