Skip to content

Commit

Permalink
If 'from' is a struct and 'to' is an empty interface with a nil value…
Browse files Browse the repository at this point in the history
…, simply copy the value

This avoids a panic when attempting to examine the type of 'from'
  • Loading branch information
Morgan Pittkin committed Sep 5, 2024
1 parent 5d2ad4e commit c163d6c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
6 changes: 6 additions & 0 deletions copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand Down
32 changes: 32 additions & 0 deletions copier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit c163d6c

Please sign in to comment.