Crates.io | resultit |
lib.rs | resultit |
version | 0.1.0 |
source | src |
created_at | 2019-11-22 15:45:40.571927 |
updated_at | 2019-11-22 15:45:40.571927 |
description | Iterator adapters for iterators over results. |
homepage | |
repository | https://github.com/benkay86/resultit |
max_upload_size | |
id | 183502 |
size | 23,896 |
Rust iterators return Option<Item>
, but what happens if Item
is a Result
that could possibly be Err
? This crate supplies iterator adapters to simplify working with so-called "fallible" iterators. The supplied adapters are independent of each other; you can use the whole crate with use resultit::*;
or just the iterator adapter traits you want with (for instance) use resultit::FlattenResults
. You are also free to take individual files (e.g. flatten_results.rs) and use them in your own source tree without depending on this crate. See the documentation for more information and examples.
Rust iterators implement a function next() that returns Option<Item>
where Item
is the type over which the iterator is iterating. For example:
let v: Vec<i32> = vec![1, 2, 3];
let iter = v.into_iter(); // satisfies trait bound Iterator<Item=i32>
while let Some(i) = iter.next() {
println!("{}", i); // i has type i32
}
// Output:
// 1
// 2
// 3
In the somewhat contrived example above, iter
is an iterator over the vector v
and satisfies the trait bound Iterator<Item=i32>
. The while let
statement executes as long as iter.next()
returns Some(i)
where i
is the next integer in the vector. After iter.next()
returns Some(3)
, the next call to iter.next()
returns None
and the while let
loop ends. Usually you would use the more idiomatic constructs for i in vec
or for i in iter
or iter.for_each(|i| println!("{}", i)
and the Option<Item>
would be unwrapped for you automatically.
As we all know, not everything in programming always goes as planned. This crate exists to help with cases where Item
is a Result
that could possibly contain an Err
. Using such an iterator is challenging in particular when:
FlattenResults
and flatten_results()
TryError
StopAfterError
and stop_after_error()
Please see the rustdoc documentation for details of how to use each of the above tools.
There are multiple didactic examples in the documentation. A real-world example using the glob crate follows:
// Use the resultit crate.
use resultit::*;
// Look for image files with different extensions.
let glob_patterns = vec!["*.png", "*.jpg"];
// Print out a list of matching image files.
glob_patterns.into_iter()
// Attempt to convert each glob pattern into an iterator over matching paths.
.map(|pattern| -> glob::glob(&pattern))
// Flatten over each inner iterator over matching paths.
.flatten_results()
// Flatten/erase the nested error types PatternError and GlobError.
.map(|path| -> lib::TryResult<_> { Ok(path??) })
// Stop iteration after the first error is encountered.
.stop_after_error()
// Generate some output, propagating errors up the stack.
.try_for_each(|path| -> TryResult<()> {
Ok(println!("Found image: {:?}", path?))
});