itertools
itertools copied to clipboard
Feature: `and_then`/`and_then_results`
Similar to map_results, this combinator would allow the mapping function to return an error. The Item type of the iterator would be any Result<T, E> where E1: Into<E>, E2: Into<E>.
I made a version of and_then using a separate trait before seeing this issue:
impl
trait Iteresult: Iterator {
type Ok;
type Err;
fn and_then<B, F, E>(self, f: F) -> AndThen<Self, F>
where
F: FnMut(Self::Ok) -> Result<B, E>,
Self::Err: From<E>;
}
impl<T, E_, I> Iteresult for I
where
I: Iterator<Item = Result<T, E_>>,
{
type Ok = T;
type Err = E_;
fn and_then<B, F, E>(self, f: F) -> AndThen<Self, F>
where
F: FnMut(Self::Ok) -> Result<B, E>,
E_: From<Self::Err>,
{
AndThen { f, iter: self }
}
}
struct AndThen<I: ?Sized, F> {
f: F,
iter: I,
}
impl<T, E_, I: ?Sized, B, F, E> Iterator for AndThen<I, F>
where
I: Iterator<Item = Result<T, E_>>,
F: FnMut(T) -> Result<B, E>,
E_: From<E>,
{
type Item = Result<B, E_>;
fn next(&mut self) -> Option<Result<B, E_>> {
self.iter
.next()
.map(|res| res.and_then(|t| Ok((self.f)(t)?)))
}
}
trait Itertools: Iterator {
..
fn and_then<T1, E1, T2, E2, F>(self, f: F) -> AndThen<Self, F>
where
Self: Iterator<Item = Result<T1, E1>> + Sized,
F: FnMut(T1) -> Result<T2, E2>,
E1: From<E2>,
{
AndThen { f, iter: self }
}
}
struct AndThen<I, F> {
f: F,
iter: I,
}
impl<T1, E1, T2, E2, F, I> Iterator for AndThen<I, F>
where
I: Iterator<Item = Result<T1, E1>>,
F: FnMut(T1) -> Result<T2, E2>,
E1: From<E2>,
{
type Item = Result<T2, E1>;
fn next(&mut self) -> Option<Result<T2, E1>> {
self.iter
.next()
.map(|res| res.and_then(|t| Ok((self.f)(t)?)))
}
}