diff --git a/util/reflect/reflect.go b/util/reflect/reflect.go index c38003ef..185a192e 100644 --- a/util/reflect/reflect.go +++ b/util/reflect/reflect.go @@ -81,3 +81,41 @@ func StructFields(src interface{}) ([]reflect.StructField, error) { return fields, nil } + +// CopyDefaults for a from b +// a and b should be pointers to the same kind of struct +func CopyDefaults(a, b interface{}) { + pt := reflect.TypeOf(a) + t := pt.Elem() + va := reflect.ValueOf(a).Elem() + vb := reflect.ValueOf(b).Elem() + for i := 0; i < t.NumField(); i++ { + aField := va.Field(i) + if aField.CanSet() { + bField := vb.Field(i) + aField.Set(bField) + } + } +} + +// CopyFrom sets the public members of a from b +// a and b should be pointers to structs +// a can be a different type from b +// Only the Fields which have the same name and assignable type on a +// and b will be set. +func CopyFrom(a, b interface{}) { + ta := reflect.TypeOf(a).Elem() + tb := reflect.TypeOf(b).Elem() + va := reflect.ValueOf(a).Elem() + vb := reflect.ValueOf(b).Elem() + for i := 0; i < tb.NumField(); i++ { + bField := vb.Field(i) + tbField := tb.Field(i) + name := tbField.Name + aField := va.FieldByName(name) + taField, found := ta.FieldByName(name) + if found && aField.IsValid() && bField.IsValid() && aField.CanSet() && tbField.Type.AssignableTo(taField.Type) { + aField.Set(bField) + } + } +}