From 51d5881f6b28cb27b8afaca722b7a9134a7da0c8 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Thu, 8 Apr 2021 13:12:50 +0100 Subject: [PATCH] Use custom copiers declared in Config --- copystructure.go | 4 +++- copystructure_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/copystructure.go b/copystructure.go index f2b925e..89540e4 100644 --- a/copystructure.go +++ b/copystructure.go @@ -88,6 +88,7 @@ func (c Config) Copy(v interface{}) (interface{}, error) { if c.Copiers == nil { c.Copiers = Copiers } + w.copiers = c.Copiers err := reflectwalk.Walk(v, w) if err != nil { @@ -116,6 +117,7 @@ func ifaceKey(pointers, depth int) uint64 { type walker struct { Result interface{} + copiers map[reflect.Type]CopierFunc depth int ignoreDepth int vals []reflect.Value @@ -379,7 +381,7 @@ func (w *walker) Struct(s reflect.Value) error { w.lock(s) var v reflect.Value - if c, ok := Copiers[s.Type()]; ok { + if c, ok := w.copiers[s.Type()]; ok { // We have a Copier for this struct, so we use that copier to // get the copy, and we ignore anything deeper than this. w.ignoreDepth = w.depth diff --git a/copystructure_test.go b/copystructure_test.go index f661654..c1b77e3 100644 --- a/copystructure_test.go +++ b/copystructure_test.go @@ -1153,3 +1153,37 @@ func TestCopy_timeDoublePointer(t *testing.T) { t.Fatalf("\n%#v\n\n%#v", v, result) } } + +type nestedValue struct { + v string +} + +func TestCopy_customCopierConfig(t *testing.T) { + type T struct { + Val *nestedValue + } + + v := &T{ + Val: &nestedValue{v: "original"}, + } + + cfg := Config{ + Copiers: map[reflect.Type]CopierFunc{ + reflect.TypeOf(nestedValue{}): customCopier, + }, + } + result, err := cfg.Copy(v) + if err != nil { + t.Fatal(err) + } + + copiedVal := result.(*T) + + if !reflect.DeepEqual(v.Val.v, copiedVal.Val.v) { + t.Fatalf("\nexpected: %#v\ngiven: %#v", v.Val.v, copiedVal.Val.v) + } +} + +func customCopier(v interface{}) (interface{}, error) { + return v.(nestedValue), nil +}