Implement WithAlloc variants for EachListItem and ExtractList

This commit is contained in:
scott 2023-05-27 19:14:13 -04:00 committed by Jordan Liggitt
parent efc601302a
commit 12e3d9fcc4
No known key found for this signature in database
2 changed files with 28 additions and 2 deletions

View File

@ -160,8 +160,19 @@ func eachListItem(obj runtime.Object, fn func(runtime.Object) error, allocNew bo
for i := 0; i < len; i++ {
raw := items.Index(i)
if takeAddr {
raw = raw.Addr()
if allocNew {
// shallow copy to avoid retaining a reference to the original list item
itemCopy := reflect.New(raw.Type())
// assign to itemCopy and type-assert
itemCopy.Elem().Set(raw)
// reflect.New will guarantee that itemCopy must be a pointer.
raw = itemCopy
} else {
raw = raw.Addr()
}
}
// raw must be a pointer or an interface
// allocate a pointer is cheap
switch item := raw.Interface().(type) {
case *runtime.RawExtension:
if err := fn(item.Object); err != nil {
@ -228,6 +239,16 @@ func extractList(obj runtime.Object, allocNew bool) ([]runtime.Object, error) {
}
case raw.Type().Implements(objectType):
list[i] = raw.Interface().(runtime.Object)
case allocNew:
// shallow copy to avoid retaining a reference to the original list item
itemCopy := reflect.New(raw.Type())
// assign to itemCopy and type-assert
itemCopy.Elem().Set(raw)
var ok bool
// reflect.New will guarantee that itemCopy must be a pointer.
if list[i], ok = itemCopy.Interface().(runtime.Object); !ok {
return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
}
default:
var found bool
if list[i], found = raw.Addr().Interface().(runtime.Object); !found {

View File

@ -53,7 +53,12 @@ func (u *UnstructuredList) EachListItem(fn func(runtime.Object) error) error {
}
func (u *UnstructuredList) EachListItemWithAlloc(fn func(runtime.Object) error) error {
return u.EachListItem(fn)
for i := range u.Items {
if err := fn(&Unstructured{Object: u.Items[i].Object}); err != nil {
return err
}
}
return nil
}
// NewEmptyInstance returns a new instance of the concrete type containing only kind/apiVersion and no other data.