in pkg/cloud/api/copy.go [141:187]
func (c *copier) doStruct(p Path, dest, src reflect.Value) error {
if dest.Kind() != reflect.Struct || src.Kind() != reflect.Struct {
return fmt.Errorf("copyStruct: invalid type (dest: %T, src: %T)", dest.Interface(), src.Interface())
}
// Copy over fields that are present in both src and dest. Fields in dest
// that don't exist in src are left alone.
for i := 0; i < src.Type().NumField(); i++ {
srcFieldT := src.Type().Field(i)
fieldName := srcFieldT.Name
destField := dest.FieldByName(fieldName)
_, ok := dest.Type().FieldByName(fieldName)
if !ok {
// Only non-zero fields are counted towards
// the missing fields. Fields explicitly named
// in NullFields or ForceSendFields are
// handled by copyMetaFields() below.
if !src.Field(i).IsZero() {
c.missing = append(c.missing, missingFieldOnCopy{
Path: p.Field(fieldName),
Value: src.Field(i).Interface(),
})
c.logS("copyStruct missing field", "path", p, "fieldName", fieldName)
}
continue
}
// ServerResponse should be skipped.
if (p.Equal(Path{}) || p.Equal(Path{}.Pointer())) && fieldName == "ServerResponse" {
continue
}
if fieldName == "NullFields" || fieldName == "ForceSendFields" {
err := c.doMetaFields(p.Field(fieldName), destField, src.Field(i), dest, src)
if err != nil {
return err
}
continue
}
c.logS("copyStruct", "path", p, "fieldName", fieldName)
if err := c.doValues(p.Field(fieldName), destField, src.Field(i)); err != nil {
return err
}
}
return nil
}