//! Iterator adapter to flatten an `Iterator<Item> where: Item = Result<IntoIterator,_>`.
//! See documentation for [FlattenResults] for details.
//!
//! Based on solution proposed by redditor [earthengine](https://www.reddit.com/user/earthengine/) in [this post](https://www.reddit.com/r/rust/comments/9u6846/rust_puzzle_flatten_a_nested_iterator_of_results/) and on the [rust playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=30e0fb57a8ba63777052a344054b22c0).
//
// Implementation is non-trivial because trait methods cannot return impl trait, see the relevant RFC:
// https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
// This necessitates the rather complex and manually-defined return type of FlattenResults::flatten_result().
// To further complicated matters, rust rlosures are anonymous types and therefore cannot be expressed in a manually-defined return type. Instead we declare module-private functions flatten() and wrap_result() below, and we use pointers to these functions (which do have a type) instead of closures.
// Module-private function to flatten an iterator of results, see earthengine's solution for an explanation.
// Function pointer to pass to map() adapter in flatten() above.
// Wraps a type T in a Result<T,_>.
/// Module-level free-standing function analog to [flatten_results()](FlattenResults::flatten_results()) that can be called without using the [FlattenResults] trait. It is more idiomatic to use the iterator adapter and call [flatten_results()](FlattenResults::flatten_results()) instead.
///
/// For example:
///
/// ```
/// # struct MyError;
/// # impl std::fmt::Display for MyError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # write!(f, "MyError")
/// # }
/// # }
/// # impl std::fmt::Debug for MyError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # <MyError as std::fmt::Display>::fmt(self, f)
/// # }
/// # }
/// # impl std::error::Error for MyError { }
/// // Vector of results, each of which contains its own vector of numbers.
/// let v: Vec<Result<Vec<i32>, MyError>> = vec![
/// Ok(vec![1, 2]),
/// Ok(vec![3, 4]),
/// Err(MyError{}),
/// Ok(vec![5, 6])
/// ];
///
/// // Flatten the vector of results.
/// // Propagates the error instead of panicking.
/// let v: Vec<Result<i32, MyError>> =
/// resultit::flatten_results::transform(v.into_iter())
/// .collect();
///
/// println!("{:?}", v);
/// // [Ok(1), Ok(2), Ok(3), Ok(4), Err(MyError), Ok(5), Ok(6)]
/// # assert_eq!(*v[0].as_ref().unwrap(), 1);
/// # assert_eq!(*v[1].as_ref().unwrap(), 2);
/// # assert_eq!(*v[2].as_ref().unwrap(), 3);
/// # assert_eq!(*v[3].as_ref().unwrap(), 4);
/// # assert_eq!(v[4].is_err(), true);
/// # assert_eq!(*v[5].as_ref().unwrap(), 5);
/// # assert_eq!(*v[6].as_ref().unwrap(), 6);
/// ```
/// Iterator adapter to flatten an `Iterator<Item> where: Item = Result<IntoIterator,_>`. This is needed because the standard [flatten()](std::iter::Iterator::flatten()) adapter only works on an iterator of iterators and does not work on an iterator of results.
///
/// Example of what not to do:
///
/// ```should_panic
/// # struct MyError;
/// # impl std::fmt::Display for MyError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # write!(f, "MyError")
/// # }
/// # }
/// # impl std::fmt::Debug for MyError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # <MyError as std::fmt::Display>::fmt(self, f)
/// # }
/// # }
/// # impl std::error::Error for MyError { }
/// // Vector of results, each of which contains its own vector of numbers.
/// let v: Vec<Result<Vec<i32>, MyError>> = vec![
/// Ok(vec![1, 2]),
/// Ok(vec![3, 4]),
/// Err(MyError{}),
/// Ok(vec![5, 6])
/// ];
///
/// // Panics after printing the number 4. Probably not what you want!
/// v.into_iter()
/// .map(|res| res.unwrap())
/// .flatten()
/// .for_each(|i| println!("{}", i));
/// ```
///
/// Instead of [flatten()](std::iter::Iterator::flatten()), use [flatten_results()](FlattenResults::flatten_results()) to flatten each `Ok(IntoInterator)` and pass through the errors.
///
/// ```
/// # struct MyError;
/// # impl std::fmt::Display for MyError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # write!(f, "MyError")
/// # }
/// # }
/// # impl std::fmt::Debug for MyError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # <MyError as std::fmt::Display>::fmt(self, f)
/// # }
/// # }
/// # impl std::error::Error for MyError { }
/// // Use the FlattenResults trait to enable flatten_results() on iterators.
/// use resultit::FlattenResults;
///
/// // Vector of results, each of which contains its own vector of numbers.
/// let v: Vec<Result<Vec<i32>, MyError>> = vec![
/// Ok(vec![1, 2]),
/// Ok(vec![3, 4]),
/// Err(MyError{}),
/// Ok(vec![5, 6])
/// ];
///
/// // Flatten the vector of results.
/// // Propagates the error instead of panicking.
/// let v: Vec<Result<i32, MyError>> = v.into_iter()
/// .flatten_results()
/// .collect();
///
/// println!("{:?}", v);
/// // [Ok(1), Ok(2), Ok(3), Ok(4), Err(MyError), Ok(5), Ok(6)]
/// # assert_eq!(*v[0].as_ref().unwrap(), 1);
/// # assert_eq!(*v[1].as_ref().unwrap(), 2);
/// # assert_eq!(*v[2].as_ref().unwrap(), 3);
/// # assert_eq!(*v[3].as_ref().unwrap(), 4);
/// # assert_eq!(v[4].is_err(), true);
/// # assert_eq!(*v[5].as_ref().unwrap(), 5);
/// # assert_eq!(*v[6].as_ref().unwrap(), 6);
/// ```