use std::iter::FromIterator; use std::marker::PhantomData; #[derive(Clone, Debug)] #[must_use = "iterator adaptors are lazy and do nothing unless consumed"] pub struct MapSpecialCase { pub(crate) iter: I, pub(crate) f: F, } pub trait MapSpecialCaseFn { type Out; fn call(&mut self, t: T) -> Self::Out; } impl Iterator for MapSpecialCase where I: Iterator, R: MapSpecialCaseFn, { type Item = R::Out; fn next(&mut self) -> Option { self.iter.next().map(|i| self.f.call(i)) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } fn fold(self, init: Acc, mut fold_f: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { let mut f = self.f; self.iter.fold(init, move |acc, v| fold_f(acc, f.call(v))) } fn collect(self) -> C where C: FromIterator, { let mut f = self.f; self.iter.map(move |v| f.call(v)).collect() } } impl DoubleEndedIterator for MapSpecialCase where I: DoubleEndedIterator, R: MapSpecialCaseFn, { fn next_back(&mut self) -> Option { self.iter.next_back().map(|i| self.f.call(i)) } } impl ExactSizeIterator for MapSpecialCase where I: ExactSizeIterator, R: MapSpecialCaseFn, { } /// An iterator adapter to apply a transformation within a nested `Result::Ok`. /// /// See [`.map_ok()`](crate::Itertools::map_ok) for more information. pub type MapOk = MapSpecialCase>; impl MapSpecialCaseFn> for MapSpecialCaseFnOk where F: FnMut(T) -> U, { type Out = Result; fn call(&mut self, t: Result) -> Self::Out { t.map(|v| self.0(v)) } } #[derive(Clone)] pub struct MapSpecialCaseFnOk(F); impl std::fmt::Debug for MapSpecialCaseFnOk { debug_fmt_fields!(MapSpecialCaseFnOk,); } /// Create a new `MapOk` iterator. pub fn map_ok(iter: I, f: F) -> MapOk where I: Iterator>, F: FnMut(T) -> U, { MapSpecialCase { iter, f: MapSpecialCaseFnOk(f), } } /// An iterator adapter to apply `Into` conversion to each element. /// /// See [`.map_into()`](crate::Itertools::map_into) for more information. pub type MapInto = MapSpecialCase>; impl, U> MapSpecialCaseFn for MapSpecialCaseFnInto { type Out = U; fn call(&mut self, t: T) -> Self::Out { t.into() } } pub struct MapSpecialCaseFnInto(PhantomData); impl std::fmt::Debug for MapSpecialCaseFnInto { debug_fmt_fields!(MapSpecialCaseFnInto, 0); } impl Clone for MapSpecialCaseFnInto { #[inline] fn clone(&self) -> Self { Self(PhantomData) } } /// Create a new [`MapInto`] iterator. pub fn map_into(iter: I) -> MapInto { MapSpecialCase { iter, f: MapSpecialCaseFnInto(PhantomData), } }