Skip to content

Commit 6d853e3

Browse files
authored
[collection] Added a helper ForAll to iterate over a whole collection but return an aggregated error (#759)
<!-- Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Apache-2.0 --> ### Description - Added a helper `ForAll` to iterate over a whole collection but returned an aggregated error ### Test Coverage <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update).
1 parent f98de59 commit 6d853e3

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

changes/20251209161427.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:sparkles: `[collection]` Introduced a new `ForAll` helper function that iterates through the entire collection and returns a single aggregated error containing any individual errors encountered during iteration
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,33 @@ func ForEach[S ~[]E, E any](s S, f func(E)) {
167167
})
168168
}
169169

170+
// ForAll iterates over every element in the provided sequence and invokes f
171+
// on each item in order. If f returns an error for one or more elements,
172+
// ForAll continues processing the remaining elements and returns a single
173+
// aggregated error containing all collected errors. If no errors occur, the returned error is nil.
174+
func ForAll[S ~[]E, E any](s S, f func(E) error) error {
175+
return ForAllSequence[E](slices.Values(s), f)
176+
}
177+
178+
// ForAllSequence iterates over every element in the provided sequence and invokes f
179+
// on each item in order. If f returns an error for one or more elements,
180+
// ForAllSequence continues processing the remaining elements and returns a single
181+
// aggregated error containing all collected errors. If no errors occur, the returned error is nil.
182+
func ForAllSequence[T any](s iter.Seq[T], f func(T) error) error {
183+
var err error
184+
err = commonerrors.Join(err, Each[T](s, func(e T) error {
185+
subErr := f(e)
186+
if commonerrors.Any(subErr, commonerrors.ErrEOF) {
187+
return subErr
188+
}
189+
if subErr != nil {
190+
err = commonerrors.Join(err, commonerrors.Newf(subErr, "error during iteration over value [%v]", e))
191+
}
192+
return nil
193+
}))
194+
return err
195+
}
196+
170197
// Each iterates over a sequence and executes the passed function against each element.
171198
// If passed func returns an error, the iteration stops and the error is returned, unless it is EOF.
172199
func Each[T any](s iter.Seq[T], f func(T) error) error {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,28 @@ func TestForEachSequence(t *testing.T) {
276276
}))
277277
assert.ElementsMatch(t, visited, []int{9, 22, 35, 48, 61, 74, 87, 100, 113, 126, 139})
278278
}
279+
280+
func TestForAll(t *testing.T) {
281+
var visited []int
282+
list := Range(9, 1000, field.ToOptionalInt(13))
283+
errortest.AssertError(t, ForAll(list, func(i int) error {
284+
visited = append(visited, i)
285+
if i > 150 {
286+
return commonerrors.ErrUnsupported
287+
}
288+
return nil
289+
}), commonerrors.ErrUnsupported)
290+
assert.ElementsMatch(t, visited, []int{9, 22, 35, 48, 61, 74, 87, 100, 113, 126, 139, 152, 165, 178, 191, 204, 217, 230, 243, 256, 269, 282, 295, 308, 321, 334, 347, 360, 373, 386, 399, 412, 425, 438, 451, 464, 477, 490, 503, 516, 529, 542, 555, 568, 581, 594, 607, 620, 633, 646, 659, 672, 685, 698, 711, 724, 737, 750, 763, 776, 789, 802, 815, 828, 841, 854, 867, 880, 893, 906, 919, 932, 945, 958, 971, 984, 997})
291+
visited = []int{}
292+
assert.NoError(t, ForAll(list, func(i int) error {
293+
visited = append(visited, i)
294+
if i > 150 {
295+
return commonerrors.ErrEOF
296+
}
297+
return nil
298+
}))
299+
assert.ElementsMatch(t, visited, []int{9, 22, 35, 48, 61, 74, 87, 100, 113, 126, 139, 152})
300+
assert.NoError(t, ForAll(list, func(i int) error {
301+
return nil
302+
}))
303+
}

0 commit comments

Comments
 (0)