From f21b17d3f38cb8b79b21a4ad7374622b8b82f15a Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Wed, 6 Dec 2023 16:30:59 +0000 Subject: [PATCH 01/12] add factor_iter method to convert Either, Iter> into Iter> Added as a method as Iter is already implemented if both sides are iterators of the same type of item. --- src/lib.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 4c940fd..cdad72f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -913,6 +913,32 @@ impl Either<(L, T), (R, T)> { } } +/// `Either` is an iterator if both `L` and `R` are iterators. +impl Either +where + L: IntoIterator, + R: IntoIterator, +{ + /// Factors an `Either` of `Itorator`s to be an `Itorator` of `Either`s + /// ``` + /// use either::*; + /// let left: Either<_, Vec> = Left(&["hello"]); + /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); + + /// let right: Either<&[&str], _> = Right(vec![0, 1]); + /// assert_eq!(right.factor_iter().collect::>(), vec![Right(0), Right(1)]); + /// + /// ``` + // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 + // #[doc(alias = "transpose")] + pub fn factor_iter(self) -> impl Iterator> { + self.map_either( + |l| l.into_iter().map(Either::Left), + |r| r.into_iter().map(Either::Right), + ) + } +} + impl Either { /// Extract the value of an either over two equivalent types. /// From 43f61a5c7c0e6a4f94e1d9108af4a08e5ab89838 Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Tue, 12 Dec 2023 09:29:37 +0000 Subject: [PATCH 02/12] add iter() method to borrow as an iterator --- src/lib.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index cdad72f..2646e6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -528,6 +528,28 @@ impl Either { } } + /// Borrow the inner value as an iterator. + /// + /// ``` + /// use either::*; + /// + /// let left: Either<_, &[u32]> = Left(vec![2, 3]); + /// let mut right: Either, _> = Right([4, 5].as_slice()); + /// let mut all = vec![1]; + /// all.extend(left.iter()); + /// all.extend(right.iter()); + /// assert_eq!(all, vec![1, 2, 3, 4, 5]); + /// ``` + pub fn iter<'a>( + &'a self, + ) -> Either<<&'a L as IntoIterator>::IntoIter, <&'a R as IntoIterator>::IntoIter> + where + &'a L: IntoIterator, + &'a R: IntoIterator::Item>, + { + self.as_ref().into_iter() + } + /// Return left value or given value /// /// Arguments passed to `left_or` are eagerly evaluated; if you are passing From a155f76e9e41e2a296f6a32c051c67d33e2c7b38 Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Tue, 2 Jan 2024 10:06:44 +0000 Subject: [PATCH 03/12] add iter_mut() for iterating of mutable refs --- src/lib.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 2646e6d..2508846 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -550,6 +550,34 @@ impl Either { self.as_ref().into_iter() } + /// Mutably borrow the inner value as an iterator. + /// + /// ``` + /// use either::*; + /// + /// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]); + /// for l in left.iter_mut() { + /// *l *= *l + /// } + /// assert_eq!(left, Left(vec![4, 9])); + /// + /// let mut inner = [4, 5]; + /// let mut right: Either, _> = Right(inner.as_mut_slice()); + /// for r in right.iter_mut() { + /// *r *= *r + /// } + /// assert_eq!(inner, [16, 25]); + /// ``` + pub fn iter_mut<'a>( + &'a mut self, + ) -> Either<<&'a mut L as IntoIterator>::IntoIter, <&'a mut R as IntoIterator>::IntoIter> + where + &'a mut L: IntoIterator, + &'a mut R: IntoIterator::Item>, + { + self.as_mut().into_iter() + } + /// Return left value or given value /// /// Arguments passed to `left_or` are eagerly evaluated; if you are passing From 753971380569c7b07baf3a044e5d756992cfcb09 Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Tue, 2 Jan 2024 10:13:32 +0000 Subject: [PATCH 04/12] Refine factor_iter return type Based on cuviper's review add a bit more detail to the factor_iter return type so that it will implement more specific iterators (e.g. DoubleEndedIterator) if both sides do. --- src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 2508846..6624383 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -981,7 +981,12 @@ where /// ``` // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 // #[doc(alias = "transpose")] - pub fn factor_iter(self) -> impl Iterator> { + pub fn factor_iter( + self, + ) -> Either< + iter::Map Either>, + iter::Map Either>, + > { self.map_either( |l| l.into_iter().map(Either::Left), |r| r.into_iter().map(Either::Right), From 55b6237abc6b845647c855da5a563244ba0045e4 Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Fri, 19 Jan 2024 22:19:03 +0000 Subject: [PATCH 05/12] clean up iter() lifetimes Co-authored-by: Josh Stone --- src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6624383..a09b098 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -540,12 +540,12 @@ impl Either { /// all.extend(right.iter()); /// assert_eq!(all, vec![1, 2, 3, 4, 5]); /// ``` - pub fn iter<'a>( - &'a self, - ) -> Either<<&'a L as IntoIterator>::IntoIter, <&'a R as IntoIterator>::IntoIter> + pub fn iter( + &self, + ) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> where - &'a L: IntoIterator, - &'a R: IntoIterator::Item>, + for<'a> &'a L: IntoIterator, + for<'a> &'a R: IntoIterator::Item>, { self.as_ref().into_iter() } From 009bf8ff47da4bec864db2b88ec2632ef05a4f32 Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Fri, 19 Jan 2024 22:19:42 +0000 Subject: [PATCH 06/12] clean up iter_mut() lifetimes Co-authored-by: Josh Stone --- src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a09b098..63dc04d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -568,12 +568,12 @@ impl Either { /// } /// assert_eq!(inner, [16, 25]); /// ``` - pub fn iter_mut<'a>( - &'a mut self, - ) -> Either<<&'a mut L as IntoIterator>::IntoIter, <&'a mut R as IntoIterator>::IntoIter> + pub fn iter_mut( + &mut self, + ) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> where - &'a mut L: IntoIterator, - &'a mut R: IntoIterator::Item>, + for<'a> &'a mut L: IntoIterator, + for<'a> &'a mut R: IntoIterator::Item>, { self.as_mut().into_iter() } From a6e0026d4838658f9d2f656be0ecd6cdb32a37f0 Mon Sep 17 00:00:00 2001 From: AJ Bagwell Date: Fri, 19 Jan 2024 22:20:28 +0000 Subject: [PATCH 07/12] fix It-o-erator typo Co-authored-by: Jack Wrenn --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 63dc04d..233e085 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -969,7 +969,7 @@ where L: IntoIterator, R: IntoIterator, { - /// Factors an `Either` of `Itorator`s to be an `Itorator` of `Either`s + /// Factors an `Either` of `Iterator`s to be an `Iterator` of `Either`s /// ``` /// use either::*; /// let left: Either<_, Vec> = Left(&["hello"]); From 356d9b60af6b9bd42c33aa6412fed8976fd50968 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 19 Jan 2024 15:42:04 -0800 Subject: [PATCH 08/12] Move iterator code into a module --- src/iterator.rs | 254 +++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 258 +----------------------------------------------- 2 files changed, 256 insertions(+), 256 deletions(-) create mode 100644 src/iterator.rs diff --git a/src/iterator.rs b/src/iterator.rs new file mode 100644 index 0000000..a20d67f --- /dev/null +++ b/src/iterator.rs @@ -0,0 +1,254 @@ +use super::{for_both, Either, Left, Right}; +use core::iter; + +impl Either { + /// Convert the inner value to an iterator. + /// + /// ``` + /// use either::*; + /// + /// let left: Either<_, Vec> = Left(vec![1, 2, 3, 4, 5]); + /// let mut right: Either, _> = Right(vec![]); + /// right.extend(left.into_iter()); + /// assert_eq!(right, Right(vec![1, 2, 3, 4, 5])); + /// ``` + #[allow(clippy::should_implement_trait)] + pub fn into_iter(self) -> Either + where + L: IntoIterator, + R: IntoIterator, + { + match self { + Left(l) => Left(l.into_iter()), + Right(r) => Right(r.into_iter()), + } + } + + /// Borrow the inner value as an iterator. + /// + /// ``` + /// use either::*; + /// + /// let left: Either<_, &[u32]> = Left(vec![2, 3]); + /// let mut right: Either, _> = Right([4, 5].as_slice()); + /// let mut all = vec![1]; + /// all.extend(left.iter()); + /// all.extend(right.iter()); + /// assert_eq!(all, vec![1, 2, 3, 4, 5]); + /// ``` + pub fn iter(&self) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> + where + for<'a> &'a L: IntoIterator, + for<'a> &'a R: IntoIterator::Item>, + { + self.as_ref().into_iter() + } + + /// Mutably borrow the inner value as an iterator. + /// + /// ``` + /// use either::*; + /// + /// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]); + /// for l in left.iter_mut() { + /// *l *= *l + /// } + /// assert_eq!(left, Left(vec![4, 9])); + /// + /// let mut inner = [4, 5]; + /// let mut right: Either, _> = Right(inner.as_mut_slice()); + /// for r in right.iter_mut() { + /// *r *= *r + /// } + /// assert_eq!(inner, [16, 25]); + /// ``` + pub fn iter_mut( + &mut self, + ) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> + where + for<'a> &'a mut L: IntoIterator, + for<'a> &'a mut R: IntoIterator::Item>, + { + self.as_mut().into_iter() + } + + /// Factors an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// ``` + /// use either::*; + /// let left: Either<_, Vec> = Left(&["hello"]); + /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); + + /// let right: Either<&[&str], _> = Right(vec![0, 1]); + /// assert_eq!(right.factor_iter().collect::>(), vec![Right(0), Right(1)]); + /// + /// ``` + // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 + // #[doc(alias = "transpose")] + pub fn factor_iter( + self, + ) -> Either< + core::iter::Map Either>, + core::iter::Map Either>, + > + where + L: IntoIterator, + R: IntoIterator, + { + self.map_either( + |l| l.into_iter().map(Either::Left), + |r| r.into_iter().map(Either::Right), + ) + } +} + +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()) + } + + // TODO(MSRV): This was stabilized in Rust 1.37 + // 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.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()) - } - - // TODO(MSRV): This was stabilized in Rust 1.37 - // 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, -{ -} - /// `Either` is a future if both `L` and `R` are futures. impl Future for Either where From c1ec796f40097d6b89532cd982e5456fbbd8cc1c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 19 Jan 2024 16:55:28 -0800 Subject: [PATCH 09/12] Add a new type for the factored iterator --- src/iterator.rs | 178 +++++++++++++++++++++++++++++++++++++++++++++--- src/lib.rs | 1 + 2 files changed, 169 insertions(+), 10 deletions(-) diff --git a/src/iterator.rs b/src/iterator.rs index a20d67f..26d8aaf 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -84,23 +84,25 @@ impl Either { /// ``` // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 // #[doc(alias = "transpose")] - pub fn factor_iter( - self, - ) -> Either< - core::iter::Map Either>, - core::iter::Map Either>, - > + pub fn factor_iter(self) -> IterEither where L: IntoIterator, R: IntoIterator, { - self.map_either( - |l| l.into_iter().map(Either::Left), - |r| r.into_iter().map(Either::Right), - ) + IterEither { + inner: self.map_either(L::into_iter, R::into_iter), + } } } +/// Iterator that maps left or right iterators to corresponding `Either`-wrapped items. +/// +/// This struct is created by the [`Either::factor_iter`] method. +#[derive(Clone, Debug)] +pub struct IterEither { + inner: Either, +} + impl Extend for Either where L: Extend, @@ -252,3 +254,159 @@ where R: iter::FusedIterator, { } + +macro_rules! map_either { + ($value:expr, $pattern:pat => $result:expr) => { + match $value { + Left($pattern) => Left($result), + Right($pattern) => Right($result), + } + }; +} + +macro_rules! wrap_either { + ($value:expr => $( $tail:tt )*) => { + match $value { + Left(inner) => inner.map(Left) $($tail)*, + Right(inner) => inner.map(Right) $($tail)*, + } + }; +} + +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()?)) + } + + // TODO(MSRV): This was stabilized in Rust 1.37 + // 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, +{ +} diff --git a/src/lib.rs b/src/lib.rs index d480a61..71cd239 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -929,6 +929,7 @@ impl Either { } mod iterator; +pub use iterator::IterEither; /// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`. impl From> for Either { From c3178afc82d692e1f278f2584d70741a28338546 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 19 Jan 2024 16:56:18 -0800 Subject: [PATCH 10/12] Fix iter and iter_mut doc tests for MSRV --- src/iterator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iterator.rs b/src/iterator.rs index 26d8aaf..043e873 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -30,7 +30,7 @@ impl Either { /// use either::*; /// /// let left: Either<_, &[u32]> = Left(vec![2, 3]); - /// let mut right: Either, _> = Right([4, 5].as_slice()); + /// let mut right: Either, _> = Right(&[4, 5][..]); /// let mut all = vec![1]; /// all.extend(left.iter()); /// all.extend(right.iter()); @@ -56,7 +56,7 @@ impl Either { /// assert_eq!(left, Left(vec![4, 9])); /// /// let mut inner = [4, 5]; - /// let mut right: Either, _> = Right(inner.as_mut_slice()); + /// let mut right: Either, _> = Right(&mut inner[..]); /// for r in right.iter_mut() { /// *r *= *r /// } From 2a37eba2be0f7ba50345a94907b215542a9c47f5 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sun, 28 Jan 2024 11:44:45 -0800 Subject: [PATCH 11/12] Split `factor_iter` into owned/ref/mut variations --- src/iterator.rs | 126 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 30 deletions(-) diff --git a/src/iterator.rs b/src/iterator.rs index 043e873..d31d32a 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -1,9 +1,30 @@ use super::{for_both, Either, Left, Right}; use core::iter; +macro_rules! map_either { + ($value:expr, $pattern:pat => $result:expr) => { + match $value { + Left($pattern) => Left($result), + Right($pattern) => Right($result), + } + }; +} + +macro_rules! wrap_either { + ($value:expr => $( $tail:tt )*) => { + match $value { + Left(inner) => inner.map(Left) $($tail)*, + Right(inner) => inner.map(Right) $($tail)*, + } + }; +} + impl Either { /// Convert the inner value to an iterator. /// + /// This requires the `Left` and `Right` iterators to have the same item type. + /// See [`factor_into_iter`][Either::factor_into_iter] to iterate different types. + /// /// ``` /// use either::*; /// @@ -18,14 +39,14 @@ impl Either { L: IntoIterator, R: IntoIterator, { - match self { - Left(l) => Left(l.into_iter()), - Right(r) => Right(r.into_iter()), - } + map_either!(self, inner => inner.into_iter()) } /// Borrow the inner value as an iterator. /// + /// This requires the `Left` and `Right` iterators to have the same item type. + /// See [`factor_iter`][Either::factor_iter] to iterate different types. + /// /// ``` /// use either::*; /// @@ -41,11 +62,14 @@ impl Either { for<'a> &'a L: IntoIterator, for<'a> &'a R: IntoIterator::Item>, { - self.as_ref().into_iter() + map_either!(self, inner => inner.into_iter()) } /// Mutably borrow the inner value as an iterator. /// + /// This requires the `Left` and `Right` iterators to have the same item type. + /// See [`factor_iter_mut`][Either::factor_iter_mut] to iterate different types. + /// /// ``` /// use either::*; /// @@ -69,35 +93,95 @@ impl Either { for<'a> &'a mut L: IntoIterator, for<'a> &'a mut R: IntoIterator::Item>, { - self.as_mut().into_iter() + map_either!(self, inner => inner.into_iter()) } - /// Factors an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// Converts an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// + /// Unlike [`into_iter`][Either::into_iter], this does not require the + /// `Left` and `Right` iterators to have the same item type. + /// /// ``` /// use either::*; /// let left: Either<_, Vec> = Left(&["hello"]); - /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); + /// assert_eq!(left.factor_into_iter().next(), Some(Left(&"hello"))); /// let right: Either<&[&str], _> = Right(vec![0, 1]); - /// assert_eq!(right.factor_iter().collect::>(), vec![Right(0), Right(1)]); + /// assert_eq!(right.factor_into_iter().collect::>(), vec![Right(0), Right(1)]); /// /// ``` // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 // #[doc(alias = "transpose")] - pub fn factor_iter(self) -> IterEither + pub fn factor_into_iter(self) -> IterEither where L: IntoIterator, R: IntoIterator, { IterEither { - inner: self.map_either(L::into_iter, R::into_iter), + inner: map_either!(self, inner => inner.into_iter()), + } + } + + /// Borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// + /// Unlike [`iter`][Either::iter], this does not require the + /// `Left` and `Right` iterators to have the same item type. + /// + /// ``` + /// use either::*; + /// let left: Either<_, Vec> = Left(["hello"]); + /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); + + /// let right: Either<[&str; 2], _> = Right(vec![0, 1]); + /// assert_eq!(right.factor_iter().collect::>(), vec![Right(&0), Right(&1)]); + /// + /// ``` + pub fn factor_iter( + &self, + ) -> IterEither<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> + where + for<'a> &'a L: IntoIterator, + for<'a> &'a R: IntoIterator, + { + IterEither { + inner: map_either!(self, inner => inner.into_iter()), + } + } + + /// Mutably borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// + /// Unlike [`iter_mut`][Either::iter_mut], this does not require the + /// `Left` and `Right` iterators to have the same item type. + /// + /// ``` + /// use either::*; + /// let mut left: Either<_, Vec> = Left(["hello"]); + /// left.factor_iter_mut().for_each(|x| *x.unwrap_left() = "goodbye"); + /// assert_eq!(left, Left(["goodbye"])); + + /// let mut right: Either<[&str; 2], _> = Right(vec![0, 1, 2]); + /// right.factor_iter_mut().for_each(|x| if let Right(r) = x { *r = -*r; }); + /// assert_eq!(right, Right(vec![0, -1, -2])); + /// + /// ``` + pub fn factor_iter_mut( + &mut self, + ) -> IterEither<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> + where + for<'a> &'a mut L: IntoIterator, + for<'a> &'a mut R: IntoIterator, + { + IterEither { + inner: map_either!(self, inner => inner.into_iter()), } } } /// Iterator that maps left or right iterators to corresponding `Either`-wrapped items. /// -/// This struct is created by the [`Either::factor_iter`] method. +/// 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, @@ -255,24 +339,6 @@ where { } -macro_rules! map_either { - ($value:expr, $pattern:pat => $result:expr) => { - match $value { - Left($pattern) => Left($result), - Right($pattern) => Right($result), - } - }; -} - -macro_rules! wrap_either { - ($value:expr => $( $tail:tt )*) => { - match $value { - Left(inner) => inner.map(Left) $($tail)*, - Right(inner) => inner.map(Right) $($tail)*, - } - }; -} - impl Iterator for IterEither where L: Iterator, From 499b9ed121e4b2a7d63b7253026ddb5006307276 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sun, 28 Jan 2024 11:57:42 -0800 Subject: [PATCH 12/12] Move the iter methods back to the root for doc order --- src/iterator.rs | 173 ++---------------------------------------------- src/lib.rs | 165 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 168 insertions(+), 170 deletions(-) diff --git a/src/iterator.rs b/src/iterator.rs index d31d32a..791d5ec 100644 --- a/src/iterator.rs +++ b/src/iterator.rs @@ -1,15 +1,6 @@ use super::{for_both, Either, Left, Right}; use core::iter; -macro_rules! map_either { - ($value:expr, $pattern:pat => $result:expr) => { - match $value { - Left($pattern) => Left($result), - Right($pattern) => Right($result), - } - }; -} - macro_rules! wrap_either { ($value:expr => $( $tail:tt )*) => { match $value { @@ -19,164 +10,6 @@ macro_rules! wrap_either { }; } -impl Either { - /// Convert the inner value to an iterator. - /// - /// This requires the `Left` and `Right` iterators to have the same item type. - /// See [`factor_into_iter`][Either::factor_into_iter] to iterate different types. - /// - /// ``` - /// use either::*; - /// - /// let left: Either<_, Vec> = Left(vec![1, 2, 3, 4, 5]); - /// let mut right: Either, _> = Right(vec![]); - /// right.extend(left.into_iter()); - /// assert_eq!(right, Right(vec![1, 2, 3, 4, 5])); - /// ``` - #[allow(clippy::should_implement_trait)] - pub fn into_iter(self) -> Either - where - L: IntoIterator, - R: IntoIterator, - { - map_either!(self, inner => inner.into_iter()) - } - - /// Borrow the inner value as an iterator. - /// - /// This requires the `Left` and `Right` iterators to have the same item type. - /// See [`factor_iter`][Either::factor_iter] to iterate different types. - /// - /// ``` - /// use either::*; - /// - /// let left: Either<_, &[u32]> = Left(vec![2, 3]); - /// let mut right: Either, _> = Right(&[4, 5][..]); - /// let mut all = vec![1]; - /// all.extend(left.iter()); - /// all.extend(right.iter()); - /// assert_eq!(all, vec![1, 2, 3, 4, 5]); - /// ``` - pub fn iter(&self) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> - where - for<'a> &'a L: IntoIterator, - for<'a> &'a R: IntoIterator::Item>, - { - map_either!(self, inner => inner.into_iter()) - } - - /// Mutably borrow the inner value as an iterator. - /// - /// This requires the `Left` and `Right` iterators to have the same item type. - /// See [`factor_iter_mut`][Either::factor_iter_mut] to iterate different types. - /// - /// ``` - /// use either::*; - /// - /// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]); - /// for l in left.iter_mut() { - /// *l *= *l - /// } - /// assert_eq!(left, Left(vec![4, 9])); - /// - /// let mut inner = [4, 5]; - /// let mut right: Either, _> = Right(&mut inner[..]); - /// for r in right.iter_mut() { - /// *r *= *r - /// } - /// assert_eq!(inner, [16, 25]); - /// ``` - pub fn iter_mut( - &mut self, - ) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> - where - for<'a> &'a mut L: IntoIterator, - for<'a> &'a mut R: IntoIterator::Item>, - { - map_either!(self, inner => inner.into_iter()) - } - - /// Converts an `Either` of `Iterator`s to be an `Iterator` of `Either`s - /// - /// Unlike [`into_iter`][Either::into_iter], this does not require the - /// `Left` and `Right` iterators to have the same item type. - /// - /// ``` - /// use either::*; - /// let left: Either<_, Vec> = Left(&["hello"]); - /// assert_eq!(left.factor_into_iter().next(), Some(Left(&"hello"))); - - /// let right: Either<&[&str], _> = Right(vec![0, 1]); - /// assert_eq!(right.factor_into_iter().collect::>(), vec![Right(0), Right(1)]); - /// - /// ``` - // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 - // #[doc(alias = "transpose")] - pub fn factor_into_iter(self) -> IterEither - where - L: IntoIterator, - R: IntoIterator, - { - IterEither { - inner: map_either!(self, inner => inner.into_iter()), - } - } - - /// Borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s - /// - /// Unlike [`iter`][Either::iter], this does not require the - /// `Left` and `Right` iterators to have the same item type. - /// - /// ``` - /// use either::*; - /// let left: Either<_, Vec> = Left(["hello"]); - /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); - - /// let right: Either<[&str; 2], _> = Right(vec![0, 1]); - /// assert_eq!(right.factor_iter().collect::>(), vec![Right(&0), Right(&1)]); - /// - /// ``` - pub fn factor_iter( - &self, - ) -> IterEither<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> - where - for<'a> &'a L: IntoIterator, - for<'a> &'a R: IntoIterator, - { - IterEither { - inner: map_either!(self, inner => inner.into_iter()), - } - } - - /// Mutably borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s - /// - /// Unlike [`iter_mut`][Either::iter_mut], this does not require the - /// `Left` and `Right` iterators to have the same item type. - /// - /// ``` - /// use either::*; - /// let mut left: Either<_, Vec> = Left(["hello"]); - /// left.factor_iter_mut().for_each(|x| *x.unwrap_left() = "goodbye"); - /// assert_eq!(left, Left(["goodbye"])); - - /// let mut right: Either<[&str; 2], _> = Right(vec![0, 1, 2]); - /// right.factor_iter_mut().for_each(|x| if let Right(r) = x { *r = -*r; }); - /// assert_eq!(right, Right(vec![0, -1, -2])); - /// - /// ``` - pub fn factor_iter_mut( - &mut self, - ) -> IterEither<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> - where - for<'a> &'a mut L: IntoIterator, - for<'a> &'a mut R: IntoIterator, - { - IterEither { - inner: map_either!(self, inner => inner.into_iter()), - } - } -} - /// Iterator that maps left or right iterators to corresponding `Either`-wrapped items. /// /// This struct is created by the [`Either::factor_into_iter`], @@ -187,6 +20,12 @@ pub struct IterEither { inner: Either, } +impl IterEither { + pub(crate) fn new(inner: Either) -> Self { + IterEither { inner } + } +} + impl Extend for Either where L: Extend, diff --git a/src/lib.rs b/src/lib.rs index 71cd239..fc72c2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -130,6 +130,18 @@ macro_rules! try_right { }; } +macro_rules! map_either { + ($value:expr, $pattern:pat => $result:expr) => { + match $value { + Left($pattern) => Left($result), + Right($pattern) => Right($result), + } + }; +} + +mod iterator; +pub use self::iterator::IterEither; + impl Clone for Either { fn clone(&self) -> Self { match self { @@ -505,6 +517,156 @@ impl Either { } } + /// Convert the inner value to an iterator. + /// + /// This requires the `Left` and `Right` iterators to have the same item type. + /// See [`factor_into_iter`][Either::factor_into_iter] to iterate different types. + /// + /// ``` + /// use either::*; + /// + /// let left: Either<_, Vec> = Left(vec![1, 2, 3, 4, 5]); + /// let mut right: Either, _> = Right(vec![]); + /// right.extend(left.into_iter()); + /// assert_eq!(right, Right(vec![1, 2, 3, 4, 5])); + /// ``` + #[allow(clippy::should_implement_trait)] + pub fn into_iter(self) -> Either + where + L: IntoIterator, + R: IntoIterator, + { + map_either!(self, inner => inner.into_iter()) + } + + /// Borrow the inner value as an iterator. + /// + /// This requires the `Left` and `Right` iterators to have the same item type. + /// See [`factor_iter`][Either::factor_iter] to iterate different types. + /// + /// ``` + /// use either::*; + /// + /// let left: Either<_, &[u32]> = Left(vec![2, 3]); + /// let mut right: Either, _> = Right(&[4, 5][..]); + /// let mut all = vec![1]; + /// all.extend(left.iter()); + /// all.extend(right.iter()); + /// assert_eq!(all, vec![1, 2, 3, 4, 5]); + /// ``` + pub fn iter(&self) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> + where + for<'a> &'a L: IntoIterator, + for<'a> &'a R: IntoIterator::Item>, + { + map_either!(self, inner => inner.into_iter()) + } + + /// Mutably borrow the inner value as an iterator. + /// + /// This requires the `Left` and `Right` iterators to have the same item type. + /// See [`factor_iter_mut`][Either::factor_iter_mut] to iterate different types. + /// + /// ``` + /// use either::*; + /// + /// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]); + /// for l in left.iter_mut() { + /// *l *= *l + /// } + /// assert_eq!(left, Left(vec![4, 9])); + /// + /// let mut inner = [4, 5]; + /// let mut right: Either, _> = Right(&mut inner[..]); + /// for r in right.iter_mut() { + /// *r *= *r + /// } + /// assert_eq!(inner, [16, 25]); + /// ``` + pub fn iter_mut( + &mut self, + ) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> + where + for<'a> &'a mut L: IntoIterator, + for<'a> &'a mut R: IntoIterator::Item>, + { + map_either!(self, inner => inner.into_iter()) + } + + /// Converts an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// + /// Unlike [`into_iter`][Either::into_iter], this does not require the + /// `Left` and `Right` iterators to have the same item type. + /// + /// ``` + /// use either::*; + /// let left: Either<_, Vec> = Left(&["hello"]); + /// assert_eq!(left.factor_into_iter().next(), Some(Left(&"hello"))); + + /// let right: Either<&[&str], _> = Right(vec![0, 1]); + /// assert_eq!(right.factor_into_iter().collect::>(), vec![Right(0), Right(1)]); + /// + /// ``` + // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 + // #[doc(alias = "transpose")] + pub fn factor_into_iter(self) -> IterEither + where + L: IntoIterator, + R: IntoIterator, + { + IterEither::new(map_either!(self, inner => inner.into_iter())) + } + + /// Borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// + /// Unlike [`iter`][Either::iter], this does not require the + /// `Left` and `Right` iterators to have the same item type. + /// + /// ``` + /// use either::*; + /// let left: Either<_, Vec> = Left(["hello"]); + /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); + + /// let right: Either<[&str; 2], _> = Right(vec![0, 1]); + /// assert_eq!(right.factor_iter().collect::>(), vec![Right(&0), Right(&1)]); + /// + /// ``` + pub fn factor_iter( + &self, + ) -> IterEither<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> + where + for<'a> &'a L: IntoIterator, + for<'a> &'a R: IntoIterator, + { + IterEither::new(map_either!(self, inner => inner.into_iter())) + } + + /// Mutably borrows an `Either` of `Iterator`s to be an `Iterator` of `Either`s + /// + /// Unlike [`iter_mut`][Either::iter_mut], this does not require the + /// `Left` and `Right` iterators to have the same item type. + /// + /// ``` + /// use either::*; + /// let mut left: Either<_, Vec> = Left(["hello"]); + /// left.factor_iter_mut().for_each(|x| *x.unwrap_left() = "goodbye"); + /// assert_eq!(left, Left(["goodbye"])); + + /// let mut right: Either<[&str; 2], _> = Right(vec![0, 1, 2]); + /// right.factor_iter_mut().for_each(|x| if let Right(r) = x { *r = -*r; }); + /// assert_eq!(right, Right(vec![0, -1, -2])); + /// + /// ``` + pub fn factor_iter_mut( + &mut self, + ) -> IterEither<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> + where + for<'a> &'a mut L: IntoIterator, + for<'a> &'a mut R: IntoIterator, + { + IterEither::new(map_either!(self, inner => inner.into_iter())) + } + /// Return left value or given value /// /// Arguments passed to `left_or` are eagerly evaluated; if you are passing @@ -928,9 +1090,6 @@ impl Either { } } -mod iterator; -pub use iterator::IterEither; - /// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`. impl From> for Either { fn from(r: Result) -> Self {

(&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, +{ +} diff --git a/src/lib.rs b/src/lib.rs index 233e085..d480a61 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,7 +27,6 @@ pub mod serde_untagged_optional; use core::convert::{AsMut, AsRef}; use core::fmt; use core::future::Future; -use core::iter; use core::ops::Deref; use core::ops::DerefMut; use core::pin::Pin; @@ -506,78 +505,6 @@ impl Either { } } - /// Convert the inner value to an iterator. - /// - /// ``` - /// use either::*; - /// - /// let left: Either<_, Vec> = Left(vec![1, 2, 3, 4, 5]); - /// let mut right: Either, _> = Right(vec![]); - /// right.extend(left.into_iter()); - /// assert_eq!(right, Right(vec![1, 2, 3, 4, 5])); - /// ``` - #[allow(clippy::should_implement_trait)] - pub fn into_iter(self) -> Either - where - L: IntoIterator, - R: IntoIterator, - { - match self { - Left(l) => Left(l.into_iter()), - Right(r) => Right(r.into_iter()), - } - } - - /// Borrow the inner value as an iterator. - /// - /// ``` - /// use either::*; - /// - /// let left: Either<_, &[u32]> = Left(vec![2, 3]); - /// let mut right: Either, _> = Right([4, 5].as_slice()); - /// let mut all = vec![1]; - /// all.extend(left.iter()); - /// all.extend(right.iter()); - /// assert_eq!(all, vec![1, 2, 3, 4, 5]); - /// ``` - pub fn iter( - &self, - ) -> Either<<&L as IntoIterator>::IntoIter, <&R as IntoIterator>::IntoIter> - where - for<'a> &'a L: IntoIterator, - for<'a> &'a R: IntoIterator::Item>, - { - self.as_ref().into_iter() - } - - /// Mutably borrow the inner value as an iterator. - /// - /// ``` - /// use either::*; - /// - /// let mut left: Either<_, &mut [u32]> = Left(vec![2, 3]); - /// for l in left.iter_mut() { - /// *l *= *l - /// } - /// assert_eq!(left, Left(vec![4, 9])); - /// - /// let mut inner = [4, 5]; - /// let mut right: Either, _> = Right(inner.as_mut_slice()); - /// for r in right.iter_mut() { - /// *r *= *r - /// } - /// assert_eq!(inner, [16, 25]); - /// ``` - pub fn iter_mut( - &mut self, - ) -> Either<<&mut L as IntoIterator>::IntoIter, <&mut R as IntoIterator>::IntoIter> - where - for<'a> &'a mut L: IntoIterator, - for<'a> &'a mut R: IntoIterator::Item>, - { - self.as_mut().into_iter() - } - /// Return left value or given value /// /// Arguments passed to `left_or` are eagerly evaluated; if you are passing @@ -963,37 +890,6 @@ impl Either<(L, T), (R, T)> { } } -/// `Either` is an iterator if both `L` and `R` are iterators. -impl Either -where - L: IntoIterator, - R: IntoIterator, -{ - /// Factors an `Either` of `Iterator`s to be an `Iterator` of `Either`s - /// ``` - /// use either::*; - /// let left: Either<_, Vec> = Left(&["hello"]); - /// assert_eq!(left.factor_iter().next(), Some(Left(&"hello"))); - - /// let right: Either<&[&str], _> = Right(vec![0, 1]); - /// assert_eq!(right.factor_iter().collect::>(), vec![Right(0), Right(1)]); - /// - /// ``` - // TODO(MSRV): doc(alias) was stabilized in Rust 1.48 - // #[doc(alias = "transpose")] - pub fn factor_iter( - self, - ) -> Either< - iter::Map Either>, - iter::Map Either>, - > { - self.map_either( - |l| l.into_iter().map(Either::Left), - |r| r.into_iter().map(Either::Right), - ) - } -} - impl Either { /// Extract the value of an either over two equivalent types. /// @@ -1032,6 +928,8 @@ impl Either { } } +mod iterator; + /// Convert from `Result` to `Either` with `Ok => Right` and `Err => Left`. impl From> for Either { fn from(r: Result) -> Self { @@ -1053,158 +951,6 @@ impl Into> for Either { } } -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