itertools icon indicating copy to clipboard operation
itertools copied to clipboard

Proposal: `Iterator::try_flat_map()` method

Open Niedzwiedzw opened this issue 1 year ago • 2 comments

Managed to get it to work with Box<_>, maybe it can be further optimized by defining a custom iterator. I use it a lot, it's very helpful

use std::iter::once;
use tap::prelude::*;

fn boxed_iter<'a, T: 'a>(
    iter: impl Iterator<Item = T> + 'a,
) -> Box<dyn Iterator<Item = T> + 'a> {
    Box::new(iter)
}

#[extension_traits::extension(pub trait IteratorTryFlatMapExt)]
impl<'iter, T, E, I> I
where
    E: 'iter,
    T: 'iter,
    I: Iterator<Item = std::result::Result<T, E>> + 'iter,
{
    fn try_flat_map<U, NewIterator, F>(
        self,
        mut try_flat_map: F,
    ) -> impl Iterator<Item = std::result::Result<U, E>> + 'iter
    where
        U: 'iter,
        NewIterator: Iterator<Item = std::result::Result<U, E>> + 'iter,
        F: FnMut(T) -> NewIterator + 'iter,
    {
        self.flat_map(move |e| match e {
            Ok(value) => value.pipe(&mut try_flat_map).pipe(boxed_iter),
            Err(e) => e.pipe(Err).pipe(once).pipe(boxed_iter),
        })
    }
}

Niedzwiedzw avatar Jul 06 '24 09:07 Niedzwiedzw