// ExtractList returns obj's Items element as an array of runtime.Objects. // Returns an error if obj is not a List type (does not have an Items member). // TODO: move me to pkg/api/meta func ExtractList(obj interface{}) ([]interface{}, error) { itemsPtr, err := GetItemsPtr(obj) if err != nil { return nil, err } items, err := conversion.EnforcePtr(itemsPtr) if err != nil { return nil, err } list := make([]interface{}, items.Len()) for i := range list { raw := items.Index(i) var found bool switch raw.Kind() { case reflect.Interface, reflect.Ptr: list[i], found = raw.Interface().(interface{}) default: list[i], found = raw.Addr().Interface().(interface{}) } if !found { return nil, fmt.Errorf("item[%v]: Expected object, got %#v(%s)", i, raw.Interface(), raw.Kind()) } } return list, nil }
func GetItemsPtr(list interface{}) (interface{}, error) { v, err := conversion.EnforcePtr(list) if err != nil { return nil, err } items := v.FieldByName("Items") if !items.IsValid() { return nil, fmt.Errorf("no Items field in %#v", list) } switch items.Kind() { case reflect.Interface, reflect.Ptr: target := reflect.TypeOf(items.Interface()).Elem() if target.Kind() != reflect.Slice { return nil, fmt.Errorf("items: Expected slice, got %s", target.Kind()) } return items.Interface(), nil case reflect.Slice: return items.Addr().Interface(), nil default: return nil, fmt.Errorf("items: Expected slice, got %s", items.Kind()) } }