diff --git a/copier.go b/copier.go index 175ad82..7fb2116 100644 --- a/copier.go +++ b/copier.go @@ -139,6 +139,12 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error) return ErrInvalidCopyFrom } + // If the target is an empty interface with value nil, simply copy the value + if from.Kind() == reflect.Struct && from.Type().AssignableTo(to.Type()) && reflect.TypeOf(to.Interface()) == nil { + to.Set(from) + return + } + fromType, isPtrFrom := indirectType(from.Type()) toType, _ := indirectType(to.Type()) diff --git a/copier_test.go b/copier_test.go index 1441df5..1d9e712 100644 --- a/copier_test.go +++ b/copier_test.go @@ -1774,3 +1774,35 @@ func TestNestedNilPointerStruct(t *testing.T) { t.Errorf("to (%v) value should equal from (%v) value", to.Title, from.Title) } } + +type testStruct struct { + Prop string +} + +type testHolder struct { + Data interface{} +} + +func newHolder(data interface{}) testHolder { + h := testHolder{} + copier.Copy(&(h.Data), data) + return h +} + +func getDataFromHolder(holder testHolder, data interface{}) { + copier.Copy(data, holder.Data) +} + +func TestCopyToNilEmptyInterface(t *testing.T) { + expected := testStruct{Prop: "expected"} + + holder := newHolder(&expected) + + actual := testStruct{} + + getDataFromHolder(holder, &actual) + + if expected.Prop != actual.Prop { + t.Fatalf("wanted %s got %s", expected.Prop, actual.Prop) + } +}