use core::convert::Infallible;
use core::fmt;
use easy_ext::ext;
use crate::inherent::sealed::Sealed;
#[ext]
pub impl<T> T
where
T: Iterator,
Self: Sealed<T>,
{
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where
Self: Sized,
P: FnMut(Self::Item) -> Option<B>,
{
MapWhile { iter: self, predicate }
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone)]
pub struct MapWhile<I, P> {
iter: I,
predicate: P,
}
impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MapWhile").field("iter", &self.iter).finish()
}
}
impl<B, I: Iterator, P> Iterator for MapWhile<I, P>
where P: FnMut(I::Item) -> Option<B>
{
type Item = B;
fn next(&mut self) -> Option<B> {
let x = self.iter.next()?;
(self.predicate)(x)
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
where
Self: Sized,
Fold: FnMut(Acc, Self::Item) -> Acc,
{
fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, Infallible> {
move |acc, x| Ok(f(acc, x))
}
self.try_fold(init, ok(fold)).unwrap()
}
}