From d62efa6fffde2c90dc60aaa80301f9ab83010dd8 Mon Sep 17 00:00:00 2001 From: Avinash Maddikonda <45308169+SFM61319@users.noreply.github.com> Date: Wed, 21 Feb 2024 18:16:03 +0530 Subject: [PATCH] Feat: Implement trait `IntoEither` Add: + Trait `IntoEither` - `into_either`: Conditionally convert any sized type into any variant of `Either`. - `into_either_with`: Like `into_either`, but takes a predicate function instead. + Impl `IntoEither` for generic type `T`, where `T` is `Sized` Close #99 --- src/into_either.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 3 +++ 2 files changed, 67 insertions(+) create mode 100644 src/into_either.rs diff --git a/src/into_either.rs b/src/into_either.rs new file mode 100644 index 0000000..73746c8 --- /dev/null +++ b/src/into_either.rs @@ -0,0 +1,64 @@ +//! The trait [`IntoEither`] provides methods for converting a type `Self`, whose +//! size is constant and known at compile-time, into an [`Either`] variant. + +use super::{Either, Left, Right}; + +/// Provides methods for converting a type `Self` into either a [`Left`] or [`Right`] +/// variant of [`Either`](Either). +/// +/// The [`into_either`](IntoEither::into_either) method takes a [`bool`] to determine +/// whether to convert to [`Left`] or [`Right`]. +/// +/// The [`into_either_with`](IntoEither::into_either_with) method takes a +/// [predicate function](FnOnce) to determine whether to convert to [`Left`] or [`Right`]. +pub trait IntoEither: Sized { + /// Converts `self` into a [`Left`] variant of [`Either`](Either) + /// if `into_left` is `true`. + /// Converts `self` into a [`Right`] variant of [`Either`](Either) + /// otherwise. + /// + /// # Examples + /// + /// ``` + /// use either::{IntoEither, Left, Right}; + /// + /// let x = 0; + /// assert_eq!(x.into_either(true), Left(x)); + /// assert_eq!(x.into_either(false), Right(x)); + /// ``` + fn into_either(self, into_left: bool) -> Either { + if into_left { + Left(self) + } else { + Right(self) + } + } + + /// Converts `self` into a [`Left`] variant of [`Either`](Either) + /// if `into_left(&self)` returns `true`. + /// Converts `self` into a [`Right`] variant of [`Either`](Either) + /// otherwise. + /// + /// # Examples + /// + /// ``` + /// use either::{IntoEither, Left, Right}; + /// + /// fn is_even(x: &u8) -> bool { + /// x % 2 == 0 + /// } + /// + /// let x = 0; + /// assert_eq!(x.into_either_with(is_even), Left(x)); + /// assert_eq!(x.into_either_with(|x| !is_even(x)), Right(x)); + /// ``` + fn into_either_with(self, into_left: F) -> Either + where + F: FnOnce(&Self) -> bool, + { + let into_left = into_left(&self); + self.into_either(into_left) + } +} + +impl IntoEither for T {} diff --git a/src/lib.rs b/src/lib.rs index fc72c2d..e0792f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,6 +142,9 @@ macro_rules! map_either { mod iterator; pub use self::iterator::IterEither; +mod into_either; +pub use self::into_either::IntoEither; + impl Clone for Either { fn clone(&self) -> Self { match self {