Skip to content

Commit c163d6c

Browse files
author
Morgan Pittkin
committed
If 'from' is a struct and 'to' is an empty interface with a nil value, simply copy the value
This avoids a panic when attempting to examine the type of 'from'
1 parent 5d2ad4e commit c163d6c

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

copier.go

+6
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ func copier(toValue interface{}, fromValue interface{}, opt Option) (err error)
139139
return ErrInvalidCopyFrom
140140
}
141141

142+
// If the target is an empty interface with value nil, simply copy the value
143+
if from.Kind() == reflect.Struct && from.Type().AssignableTo(to.Type()) && reflect.TypeOf(to.Interface()) == nil {
144+
to.Set(from)
145+
return
146+
}
147+
142148
fromType, isPtrFrom := indirectType(from.Type())
143149
toType, _ := indirectType(to.Type())
144150

copier_test.go

+32
Original file line numberDiff line numberDiff line change
@@ -1774,3 +1774,35 @@ func TestNestedNilPointerStruct(t *testing.T) {
17741774
t.Errorf("to (%v) value should equal from (%v) value", to.Title, from.Title)
17751775
}
17761776
}
1777+
1778+
type testStruct struct {
1779+
Prop string
1780+
}
1781+
1782+
type testHolder struct {
1783+
Data interface{}
1784+
}
1785+
1786+
func newHolder(data interface{}) testHolder {
1787+
h := testHolder{}
1788+
copier.Copy(&(h.Data), data)
1789+
return h
1790+
}
1791+
1792+
func getDataFromHolder(holder testHolder, data interface{}) {
1793+
copier.Copy(data, holder.Data)
1794+
}
1795+
1796+
func TestCopyToNilEmptyInterface(t *testing.T) {
1797+
expected := testStruct{Prop: "expected"}
1798+
1799+
holder := newHolder(&expected)
1800+
1801+
actual := testStruct{}
1802+
1803+
getDataFromHolder(holder, &actual)
1804+
1805+
if expected.Prop != actual.Prop {
1806+
t.Fatalf("wanted %s got %s", expected.Prop, actual.Prop)
1807+
}
1808+
}

0 commit comments

Comments
 (0)