diff --git a/src/either.rs b/src/either.rs index 5bf45b5..03f580c 100644 --- a/src/either.rs +++ b/src/either.rs @@ -2,7 +2,7 @@ use core::{ convert::identity, fmt, hint, - ops::{Deref, DerefMut}, + ops::{Deref, DerefMut}, iter::FusedIterator, }; use crate::convert::{clone, clone_mut, copy, copy_mut, Empty}; @@ -398,6 +398,16 @@ impl Either { } self } + + pub fn iter<'a>(&'a self) + -> Iter<<&'a L as IntoIterator>::IntoIter, <&'a R as IntoIterator>::IntoIter> + where + &'a L: IntoIterator, + &'a R: IntoIterator, + { + self.as_ref().into_iter() + } + } impl Either<&L, &R> { @@ -610,3 +620,71 @@ where } } } + +impl IntoIterator for Either +where + L: IntoIterator, + R: IntoIterator, +{ + type Item = Either<::Item, ::Item>; + + type IntoIter = Iter<::IntoIter, ::IntoIter>; + + fn into_iter(self) -> Self::IntoIter { + Iter { + inner: self.map(::into_iter, ::into_iter), + } + } +} + +pub struct Iter { + inner: Either, +} + +impl Iterator for Iter +where + L: Iterator, + R: Iterator, +{ + type Item = Either<::Item, ::Item>; + + fn next(&mut self) -> Option { + match &mut self.inner { + Inl(l) => l.next().map(Inl), + Inr(r) => r.next().map(Inr), + } + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.as_ref().fold(L::size_hint, R::size_hint) + } + + fn count(self) -> usize { + self.inner.fold(L::count, R::count) + } +} + +impl DoubleEndedIterator for Iter +where + L: DoubleEndedIterator, + R: DoubleEndedIterator, +{ + fn next_back(&mut self) -> Option { + match &mut self.inner { + Inl(l) => l.next_back().map(Inl), + Inr(r) => r.next_back().map(Inr), + } + } +} + +impl ExactSizeIterator for Iter +where + L: ExactSizeIterator, + R: ExactSizeIterator, +{} + +impl FusedIterator for Iter +where + L: FusedIterator, + R: FusedIterator, +{}