use super::{for_both, Either, Left, Right}; use core::iter; macro_rules! wrap_either { ($value:expr => $( $tail:tt )*) => { match $value { Left(inner) => inner.map(Left) $($tail)*, Right(inner) => inner.map(Right) $($tail)*, } }; } /// Iterator that maps left or right iterators to corresponding `Either`-wrapped items. /// /// This struct is created by the [`Either::factor_into_iter`], /// [`factor_iter`][Either::factor_iter], /// and [`factor_iter_mut`][Either::factor_iter_mut] methods. #[derive(Clone, Debug)] pub struct IterEither { inner: Either, } impl IterEither { pub(crate) fn new(inner: Either) -> Self { IterEither { inner } } } impl Extend for Either where L: Extend, R: Extend, { fn extend(&mut self, iter: T) where T: IntoIterator, { for_both!(*self, ref mut inner => inner.extend(iter)) } } /// `Either` is an iterator if both `L` and `R` are iterators. impl Iterator for Either where L: Iterator, R: Iterator, { type Item = L::Item; fn next(&mut self) -> Option { for_both!(*self, ref mut inner => inner.next()) } fn size_hint(&self) -> (usize, Option) { for_both!(*self, ref inner => inner.size_hint()) } fn fold(self, init: Acc, f: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, { for_both!(self, inner => inner.fold(init, f)) } fn for_each(self, f: F) where F: FnMut(Self::Item), { for_both!(self, inner => inner.for_each(f)) } fn count(self) -> usize { for_both!(self, inner => inner.count()) } fn last(self) -> Option { for_both!(self, inner => inner.last()) } fn nth(&mut self, n: usize) -> Option { for_both!(*self, ref mut inner => inner.nth(n)) } fn collect(self) -> B where B: iter::FromIterator, { for_both!(self, inner => inner.collect()) } fn partition(self, f: F) -> (B, B) where B: Default + Extend, F: FnMut(&Self::Item) -> bool, { for_both!(self, inner => inner.partition(f)) } fn all(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool, { for_both!(*self, ref mut inner => inner.all(f)) } fn any(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool, { for_both!(*self, ref mut inner => inner.any(f)) } fn find

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { for_both!(*self, ref mut inner => inner.find(predicate)) } fn find_map(&mut self, f: F) -> Option where F: FnMut(Self::Item) -> Option, { for_both!(*self, ref mut inner => inner.find_map(f)) } fn position

(&mut self, predicate: P) -> Option where P: FnMut(Self::Item) -> bool, { for_both!(*self, ref mut inner => inner.position(predicate)) } } impl DoubleEndedIterator for Either where L: DoubleEndedIterator, R: DoubleEndedIterator, { fn next_back(&mut self) -> Option { for_both!(*self, ref mut inner => inner.next_back()) } fn nth_back(&mut self, n: usize) -> Option { for_both!(*self, ref mut inner => inner.nth_back(n)) } fn rfold(self, init: Acc, f: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, { for_both!(self, inner => inner.rfold(init, f)) } fn rfind

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { for_both!(*self, ref mut inner => inner.rfind(predicate)) } } impl ExactSizeIterator for Either where L: ExactSizeIterator, R: ExactSizeIterator, { fn len(&self) -> usize { for_both!(*self, ref inner => inner.len()) } } impl iter::FusedIterator for Either where L: iter::FusedIterator, R: iter::FusedIterator, { } impl Iterator for IterEither where L: Iterator, R: Iterator, { type Item = Either; fn next(&mut self) -> Option { Some(map_either!(self.inner, ref mut inner => inner.next()?)) } fn size_hint(&self) -> (usize, Option) { for_both!(self.inner, ref inner => inner.size_hint()) } fn fold(self, init: Acc, f: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, { wrap_either!(self.inner => .fold(init, f)) } fn for_each(self, f: F) where F: FnMut(Self::Item), { wrap_either!(self.inner => .for_each(f)) } fn count(self) -> usize { for_both!(self.inner, inner => inner.count()) } fn last(self) -> Option { Some(map_either!(self.inner, inner => inner.last()?)) } fn nth(&mut self, n: usize) -> Option { Some(map_either!(self.inner, ref mut inner => inner.nth(n)?)) } fn collect(self) -> B where B: iter::FromIterator, { wrap_either!(self.inner => .collect()) } fn partition(self, f: F) -> (B, B) where B: Default + Extend, F: FnMut(&Self::Item) -> bool, { wrap_either!(self.inner => .partition(f)) } fn all(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool, { wrap_either!(&mut self.inner => .all(f)) } fn any(&mut self, f: F) -> bool where F: FnMut(Self::Item) -> bool, { wrap_either!(&mut self.inner => .any(f)) } fn find

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { wrap_either!(&mut self.inner => .find(predicate)) } fn find_map(&mut self, f: F) -> Option where F: FnMut(Self::Item) -> Option, { wrap_either!(&mut self.inner => .find_map(f)) } fn position

(&mut self, predicate: P) -> Option where P: FnMut(Self::Item) -> bool, { wrap_either!(&mut self.inner => .position(predicate)) } } impl DoubleEndedIterator for IterEither where L: DoubleEndedIterator, R: DoubleEndedIterator, { fn next_back(&mut self) -> Option { Some(map_either!(self.inner, ref mut inner => inner.next_back()?)) } fn nth_back(&mut self, n: usize) -> Option { Some(map_either!(self.inner, ref mut inner => inner.nth_back(n)?)) } fn rfold(self, init: Acc, f: G) -> Acc where G: FnMut(Acc, Self::Item) -> Acc, { wrap_either!(self.inner => .rfold(init, f)) } fn rfind

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { wrap_either!(&mut self.inner => .rfind(predicate)) } } impl ExactSizeIterator for IterEither where L: ExactSizeIterator, R: ExactSizeIterator, { fn len(&self) -> usize { for_both!(self.inner, ref inner => inner.len()) } } impl iter::FusedIterator for IterEither where L: iter::FusedIterator, R: iter::FusedIterator, { }