diff --git a/src/lib.rs b/src/lib.rs index 9a271c3..c526430 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,20 +18,13 @@ #[cfg(any(test, feature = "use_std"))] extern crate std; -#[cfg(feature = "serde")] -pub mod serde_untagged; - -#[cfg(feature = "serde")] -pub mod serde_untagged_optional; - -use core::convert::{AsMut, AsRef}; +use core::convert::{identity, AsMut, AsRef}; use core::fmt; use core::future::Future; use core::iter; use core::ops::Deref; use core::ops::DerefMut; use core::pin::Pin; - #[cfg(any(test, feature = "use_std"))] use std::error::Error; #[cfg(any(test, feature = "use_std"))] @@ -39,6 +32,12 @@ use std::io::{self, BufRead, Read, Seek, SeekFrom, Write}; pub use crate::Either::{Left, Right}; +#[cfg(feature = "serde")] +pub mod serde_untagged; + +#[cfg(feature = "serde")] +pub mod serde_untagged_optional; + /// The enum `Either` with variants `Left` and `Right` is a general purpose /// sum type with two cases. /// @@ -858,6 +857,38 @@ impl Either<(L, T), (R, T)> { } } +impl Either, R> { + /// Flattens a nested structure where the left value type is an [`Either`]. + /// + /// ``` + /// use either::*; + /// let left: Either, u64> = Left(Left("foo")); + /// assert_eq!(left.flatten_left(), Left("foo")); + /// + /// let right: Either, u64> = Right(30); + /// assert_eq!(right.flatten_left(), Right(30)); + /// ``` + pub fn flatten_left(self) -> Either { + self.either(identity, Right) + } +} + +impl Either> { + /// Flattens a nested structure where the right value type is an [`Either`]. + /// + /// ``` + /// use either::*; + /// let left: Either<&str, Either<&str, u64>> = Right(Right(10)); + /// assert_eq!(left.flatten_right(), Right(10)); + /// + /// let right: Either<&str, Either<&str, u64>> = Left("foo"); + /// assert_eq!(right.flatten_right(), Left("foo")); + /// ``` + pub fn flatten_right(self) -> Either { + self.either(Left, identity) + } +} + impl Either { /// Extract the value of an either over two equivalent types. ///