Function fail_all

Source
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 Results.

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()]));