Where Ts: FromIterator<T>
and Es: FromIterator<E>
Sometimes I find myself with an iterator that yields results. Rust lets me collect this iterator into a Result<Vec<T>, E>
, where the Err
variant would hold the first encountered error, but sometimes I want to collect all errors, and not stop iteration after the first one.
By symmetry, I already expected some implementation like the one proposed to exist, but it doesn't, and I am forced to manually build those collections
compare
results.collect::<Result<Vec<_>, Vec<_>>()
to
let (oks, errs) = results.fold((Vec::new(), Vec::new()), |(mut oks, mut errs), res| {
match res {
Ok(t) => oks.push(t),
Err(e) => errs.push(e),
}
(oks, errs)
);
if errs.is_empty() {
Ok(oks)
} else {
Err(errs)
}
or even
results.fold(Ok(Vec::new()), |mut acc, res| {
match (&mut acc, res) {
(Ok(v), Ok(t)) => v.push(t),
(Ok(_), Err(e)) => return Err(Vec::from([e])),
(Err(v), Err(e)) => v.push(e),
(Err(_), Ok(_)) => (),
}
acc
})