From 8f3f0a326c150bbadc623bc13a5aa3bb3f51b3ed Mon Sep 17 00:00:00 2001 From: Zachary S Date: Thu, 7 Apr 2022 16:28:28 -0500 Subject: [PATCH] Feature: add methods to factor common Result and Option types. Similar to Either::factor_first/second and Result/Option::transpose (though those lose no information). Either::factor_none takes an Either, Option> and gives an Option>, merging Left(None) and Right(None) into None. Either::factor_error takes an Either, Result> and gives an Result, E>, merging Left(Err) and Right(Err) into Err. Similar for Either::factor_ok. --- src/lib.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3ef249f..80a43f0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -656,6 +656,70 @@ impl Either { } } +impl Either, Option> { + /// Factors out `None` from an `Either` of [`Option`]. + /// + /// ``` + /// use either::*; + /// let left: Either<_, Option> = Left(Some(vec![0])); + /// assert_eq!(left.factor_none(), Some(Left(vec![0]))); + /// + /// let right: Either>, _> = Right(Some(String::new())); + /// assert_eq!(right.factor_none(), Some(Right(String::new()))); + /// ``` + #[doc(alias = "transpose")] + pub fn factor_none(self) -> Option> { + match self { + Left(l) => l.map(Either::Left), + Right(r) => r.map(Either::Right), + } + } +} + +impl Either, Result> { + /// Factors out a homogenous type from an `Either` of [`Result`]. + /// + /// Here, the homogeneous type is the `Err` type of the [`Result`]. + /// + /// ``` + /// use either::*; + /// let left: Either<_, Result> = Left(Ok(vec![0])); + /// assert_eq!(left.factor_error(), Ok(Left(vec![0]))); + /// + /// let right: Either, u32>, _> = Right(Ok(String::new())); + /// assert_eq!(right.factor_error(), Ok(Right(String::new()))); + /// ``` + #[doc(alias = "transpose")] + pub fn factor_error(self) -> Result, E> { + match self { + Left(l) => l.map(Either::Left), + Right(r) => r.map(Either::Right), + } + } +} + +impl Either, Result> { + /// Factors out a homogenous type from an `Either` of [`Result`]. + /// + /// Here, the homogeneous type is the `Ok` type of the [`Result`]. + /// + /// ``` + /// use either::*; + /// let left: Either<_, Result> = Left(Err(vec![0])); + /// assert_eq!(left.factor_ok(), Err(Left(vec![0]))); + /// + /// let right: Either>, _> = Right(Err(String::new())); + /// assert_eq!(right.factor_ok(), Err(Right(String::new()))); + /// ``` + #[doc(alias = "transpose")] + pub fn factor_ok(self) -> Result> { + match self { + Left(l) => l.map_err(Either::Left), + Right(r) => r.map_err(Either::Right), + } + } +} + impl Either<(T, L), (T, R)> { /// Factor out a homogeneous type from an either of pairs. ///