func()

in pkg/cloud/api/copy.go [271:318]


func (c *copier) doMetaFields(p Path, destField, srcField, destStruct, srcStruct reflect.Value) error {
	if !isSliceOfStringV(destField) || !isSliceOfStringV(srcField) {
		return fmt.Errorf("copyMetaFields: invalid type (destField: %T, srcField: %T)", destField.Interface(), srcField.Interface())
	}

	destMetaFields := destField.Interface().([]string)

	// MetaFields already present in the destination list.
	exists := map[string]bool{}
	for _, v := range destMetaFields {
		exists[v] = true
	}

	c.logS("copyMetaFields dest", "path", p, "destFields", exists)

	for _, fn := range srcField.Interface().([]string) {
		if _, ok := srcStruct.Type().FieldByName(fn); !ok {
			return fmt.Errorf("copyMetaFields: %s refers to field %q that doesn't exist (type %T)", p, fn, srcStruct.Interface())
		}
		_, destHasField := destStruct.Type().FieldByName(fn)
		// We only need to add to destMetaFields if it exists
		// in the dest struct and hasn't already been added to
		// the list.
		if destHasField && !exists[fn] {
			destMetaFields = append(destMetaFields, fn)
			c.logS("copyMetaFields add", "path", p, "fieldName", fn)
		} else if !destHasField {
			// Record that the metafield referenced a
			// field that didn't exist on the dest
			// version.
			c.missing = append(c.missing, missingFieldOnCopy{
				Path:  p.Field(fn),
				Value: srcField.Interface(),
			})
			c.logS("copyMetaFields missing field", "path", p, "fieldName", fn)
		}
	}

	if !destField.CanSet() {
		return fmt.Errorf("cannot set destField (%s)", p)

	}

	sort.Strings(destMetaFields)
	destField.Set(reflect.ValueOf(destMetaFields))

	return nil
}