Skip to content

Commit

Permalink
Feat: Implement trait IntoEither
Browse files Browse the repository at this point in the history
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
  • Loading branch information
SFM61319 committed Apr 11, 2024
1 parent ede3c47 commit d62efa6
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
64 changes: 64 additions & 0 deletions src/into_either.rs
Original file line number Diff line number Diff line change
@@ -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<Self, Self>`](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<Self, Self>`](Either)
/// if `into_left` is `true`.
/// Converts `self` into a [`Right`] variant of [`Either<Self, Self>`](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<Self, Self> {
if into_left {
Left(self)
} else {
Right(self)
}
}

/// Converts `self` into a [`Left`] variant of [`Either<Self, Self>`](Either)
/// if `into_left(&self)` returns `true`.
/// Converts `self` into a [`Right`] variant of [`Either<Self, Self>`](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<F>(self, into_left: F) -> Either<Self, Self>
where
F: FnOnce(&Self) -> bool,
{
let into_left = into_left(&self);
self.into_either(into_left)
}
}

impl<T> IntoEither for T {}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<L: Clone, R: Clone> Clone for Either<L, R> {
fn clone(&self) -> Self {
match self {
Expand Down

0 comments on commit d62efa6

Please sign in to comment.