Skip to content

Commit

Permalink
Merge pull request #7 from kyleboyle/master
Browse files Browse the repository at this point in the history
support embedded structs in src/from struct
  • Loading branch information
jinzhu committed Mar 18, 2016
2 parents 5eabd51 + 1f8098d commit b0be9dc
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
18 changes: 16 additions & 2 deletions copier.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ func Copy(toValue interface{}, fromValue interface{}) (err error) {
dest = to
}

for i := 0; i < fromType.NumField(); i++ {
field := fromType.Field(i)
for _, field := range deepFields(fromType) {
if !field.Anonymous {
name := field.Name
fromField := source.FieldByName(name)
Expand Down Expand Up @@ -104,3 +103,18 @@ func Copy(toValue interface{}, fromValue interface{}) (err error) {
}
return
}

func deepFields(ifaceType reflect.Type) []reflect.StructField {
var fields []reflect.StructField

for i := 0; i < ifaceType.NumField(); i++ {
v := ifaceType.Field(i)
if v.Anonymous && v.Type.Kind() == reflect.Struct {
fields = append(fields, deepFields(v.Type)...)
} else {
fields = append(fields, v)
}
}

return fields
}
28 changes: 27 additions & 1 deletion copier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,43 @@ func (user *User) DoubleAge() int32 {
type Employee struct {
Name string
Age int32
EmployeId int64
EmployeID int64
DoubleAge int32
SuperRule string
Notes []string
flags []byte
}

type Base struct {
BaseField1 int
BaseField2 int
}

type HaveEmbed struct {
EmbedField1 int
EmbedField2 int
Base
}

func (employee *Employee) Role(role string) {
employee.SuperRule = "Super " + role
}

func TestEmbedded(t *testing.T) {
base := Base{}
embeded := HaveEmbed{}
embeded.BaseField1 = 1
embeded.BaseField2 = 2
embeded.EmbedField1 = 3
embeded.EmbedField2 = 4

Copy(&base, &embeded)

if base.BaseField1 != 1 {
t.Error("Embedded fields not copied")
}
}

func TestCopyStruct(t *testing.T) {
user := User{Name: "Jinzhu", Age: 18, Role: "Admin", Notes: []string{"hello world"}, flags: []byte{'x'}}
employee := Employee{}
Expand Down

0 comments on commit b0be9dc

Please sign in to comment.