pub fn fail_all<I, T, E1, E2, F>(
results: I,
f: F,
) -> Result<impl Iterator<Item = T>, impl Iterator<Item = E2>>where
I: IntoIterator<Item = Result<T, E1>>,
for<'a> &'a I: IntoIterator<Item = &'a Result<T, E1>>,
F: FnMut(Result<T, E1>) -> E2,
Expand description
If at least one Result
is an error, turn all of them into errors. Else, unwrap the Result
s.
See fail_all_vec for an easier-to-understand version specialized for Vec
.
fail_all is its lower-level implementation. You probably want to create a similar wrapper function instead of using fail_all directly.
ยงExamples
// Manually:
let Ok(ok) = fail_all([Ok(A), Ok(A)], |_: Result<_, ErrA>| ErrC) else {
panic!();
};
assert_eq!(ok.collect::<Vec<_>>(), vec![A, A]);
// Or using a helper function for your container:
pub fn fail_all_3<T, E1, E2, F>(results: [Result<T, E1>; 3], f: F) -> Result<[T; 3], [E2; 3]>
where
F: FnMut(Result<T, E1>) -> E2,
{
fn collect_3<T>(mut iter: impl Iterator<Item = T>) -> [T; 3] {
core::array::from_fn(|_| iter.next().expect("the iterator should have 3 elements"))
}
fail_all(results, f).map(collect_3).map_err(collect_3)
}
let err = fail_all_3(
[Ok(A), Err(ErrA), Ok(A)],
|res| res.err().map(HighLevelErr::from).unwrap_or(HighLevelErr::B(ErrB))
);
// Each element turned into an error.
assert_eq!(err, Err([ErrB.into(), ErrA.into(), ErrB.into()]));