Custom CopierFuncs via CopyConfig not working
terrabitz opened this issue · comments
Environment
- Go Version: 1.14.2
- copystructure version: v1.0.0
- OS: Linux x64
The Problem
In order to support some complex structs with private members, I need to use a custom copier to copy the values over. Attempting to do this by setting Config.Copiers
doesn't appear to work. For example, take the following test:
package cmp
import (
"reflect"
"testing"
"github.com/mitchellh/copystructure"
)
type MyStruct struct {
S string
}
func CopyMyStruct(i interface{}) (interface{}, error) {
return MyStruct{
S: "FOO",
}, nil
}
// This doesn't work
func Test_CustomCopierConfig(t *testing.T) {
copyConfig := copystructure.Config{
Copiers: map[reflect.Type]copystructure.CopierFunc{
reflect.TypeOf(MyStruct{}): CopyMyStruct,
},
}
o1 := MyStruct{
S: "BAR",
}
cp, _ := copyConfig.Copy(o1)
o2 := cp.(MyStruct)
if o2.S != "FOO" {
t.Errorf("CopyMyStruct() expected 'FOO', got '%s'", o2.S)
}
}
// This works
func Test_CustomCopierGlobal(t *testing.T) {
copystructure.Copiers[reflect.TypeOf(MyStruct{})] = CopyMyStruct
o1 := MyStruct{
S: "BAR",
}
cp, _ := copystructure.Copy(o1)
o2 := cp.(MyStruct)
if o2.S != "FOO" {
t.Errorf("CopyMyStruct() expected 'FOO', got '%s'", o2.S)
}
}
While the test which sets the global Copiers
variable works just fine, the one which uses a specific Config
does not.
Recommended Solution
My best guess is that the problem resides here: https://github.com/mitchellh/copystructure/blob/master/copystructure.go#L359. It appears that the global Copiers
variable is getting used regardless of the value of Config.Copiers
. The walker.Struct
function signature should probably be updated to accept a Copiers
object, and then the correct Copiers
can be passed down.
It might also be helpful to document the expected workflow for creating custom copier functions. If the expectation is that the global will always be used, then it would be helpful to document that.