# ResultIt Rust iterators return `Option`, 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](https://docs.rs/resultit/) for more information and examples. ## Background Rust iterators implement a function [next()](https://doc.rust-lang.org/std/iter/trait.Iterator.html#tymethod.next) that returns `Option` where `Item` is the type over which the iterator is iterating. For example: ``` let v: Vec = vec![1, 2, 3]; let iter = v.into_iter(); // satisfies trait bound Iterator 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`. 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` 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: * Flattening an iterator of results, see `FlattenResults` and `flatten_results()` * Flattening or erasing error types in an iterator of nested results, see `TryError` * Stopping iteration after the first error, see `StopAfterError` and `stop_after_error()` Please see the [rustdoc documentation](https://docs.rs/resultit/) for details of how to use each of the above tools. ## Example There are multiple didactic examples in the [documentation](https://docs.rs/resultit/). A real-world example using the [glob](https://crates.io/crates/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?)) }); ```