From 499b9ed121e4b2a7d63b7253026ddb5006307276 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Sun, 28 Jan 2024 11:57:42 -0800 Subject: [PATCH] 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 {