When working with iterators in Rust, especially in a functional style using methods like map
, filter
, or filter_map
, you might end up with an iterator of Result types, i.e., Iterator<Item = Result<T, E>>
.
However, you may often want to check if there were any errors and, if none, iterate over the underlying Ok
values.
Fortunately, calling .collect()
on such an iterator with a Result<_, _>
as the target type will do exactly that: it collects the Ok
values or returns the first encountered error.
fn main() {
// Vectors witout and with errors.
let without_errs = vec![Ok(1), Ok(2), Ok(4)];
let with_errs = vec![Ok(1), Ok(2), Err("this is error"), Ok(4)];
// Convert iterator of Resultsi into a Result of iterators.
let without_errs: Result<Vec<_>, &'static str> = without_errs.into_iter().collect();
let with_errs: Result<Vec<_>, &'static str> = with_errs.into_iter().collect();
println!("Without: {without_errs:?}");
println!("With : {with_errs:?}");
// The output:
// Without: Ok([1, 2, 4])
// With : Err("this is error")
}
In this example, we have two vectors of type Result<u32, &'static str>
.
The first vector contains no error values, while the second vector includes an error value.
When we collect these into a Result<Vec<_>, &'static str>
, the first vector collects all values successfully, whereas in the second case, we receive the first error encountered.
You can experiment with variations, such as having multiple errors or working with an empty iterator, to see what happens in those scenarios.
Note that this approach also works with other collections besides vectors, such as HashMap
, HashSet
, or any other collection that implements the FromIterator
trait.
If you want to access the iterator without using collect, you can use the process_results
function from the itertools crate.
This function allows you to work with the values directly as an iterator of Ok
values.
However, keep in mind that the entire iterator must still be iterated through to ensure there are no errors, as process_results
will stop and return the first error it encounters.