Expand description
§EitherOrBoth
and Either
either-or-both
provides two enums: Either
and EitherOrBoth
.
Either<L, R>
— a value that is eitherLeft(L)
orRight(R)
EitherOrBoth<L, R>
— a value that can beLeft(L)
,Right(R)
, orBoth(L, R)
While Either
is useful for representing mutually exclusive values, EitherOrBoth
extends this idea by allowing both values to be present simultaneously.
§Conventions and edge cases
In most cases, Either
and EitherOrBoth
do not prioritize Left
over Right
values, or vice versa. However, in some contexts, Left
is used to represent an error
and Right
a correct value - using “right” as a mnemonic for “correct”.
With EitherOrBoth
, the Both
variant may contain both an error and a correct
value. Unless explicitly stated otherwise, the error value takes precedence during
evaluation. The same principle applies to Option
types, where None
takes
precedence over Some
.
Uniform type versions of bi-functional methods drop the bi- prefix. For example, bimap
applies two functions to potentially different types (L
and R
), while map applies
the same function to both sides of a uniform type T
.
When evaluation order matters for EitherOrBoth
methods, values are processed left
to right. To reverse this order, use flip.
§Method Overview
Either
and EitherOrBoth
provide a wide variety of different methods. Often,
the links and descriptions in the following sections use EitherOrBoth
but if not
specified otherwise, the same methods are available for Either
.
§Querying the variant
Similar to Option::is_some
and Option::is_none
, is_left
and is_right
return true
if the Either
or EitherOrBoth
is Left
or Right
respectively. Additionally, is_both
returns true if EitherOrBoth
is Both
. Since EitherOrBoth
can hold a left
value in the Both
and Left
case, the method has_left
returns true if the variant is either Both
or Left
. Symmetrically, the right value
is covered with has_right
.
Methods like is_left_and
, is_left_or
,
has_left_and
,
has_left_or
, … apply a function to the contents of
Either
or EitherOrBoth
to compute a boolean value.
§Adapters for working with references
as_ref
converts from&EitherOrBoth<L, R>
toEitherOrBoth<&L, &R>
as_mut
converts from&mut EitherOrBoth<L, R>
toEitherOrBoth<&mut L, &mut R>
as_deref
converts from&EitherOrBoth<L, R>
toEitherOrBoth<&L::Target, &R::Target>
as_deref_mut
converts from&mut EitherOrBoth<L, R>
toEitherOrBoth<&mut L::Target, &mut R::Target>
as_pin_ref
converts fromPin<&EitherOrBoth<L, R>>
toEitherOrBoth<Pin<&L>, Pin<&R>>
as_pin_mut
converts fromPin<&mut EitherOrBoth<L, R>>
toEitherOrBoth<Pin<&mut L>, Pin<&mut R>>
§Extracting the contained values
These methods extract the contained value in an EitherOrBoth<L, R>
or Either<L, R>
expect_left
panics with a provided custom message if the variant isRight
expect_right
panics with a provided custom message if the variant isLeft
unwrap_left
panics with a generic message if the variant isRight
unwrap_right
panics with a generic message if the variant isLeft
unwrap_left_unchecked
produces undefined behavior if the variant isRight
unwrap_right_unchecked
produces undefined behavior if the variant isLeft
EitherOrBoth
provides additional methods:
expect_both
panics with a provided custom message if the variant isRight
orLeft
unwrap_both
panics with a generic message if the variant isRight
orLeft
unwrap_both_unchecked
produces undefined behavior if the variant isRight
orLeft
expect_only_left
panics with a provided custom message if the variant isRight
orBoth
unwrap_only_left
panics with a generic message if the variant isRight
orBoth
unwrap_only_left_unchecked
produces undefined behavior if the variant isRight
orBoth
expect_only_right
panics with a provided custom message if the variant isLeft
orBoth
unwrap_only_right
panics with a generic message if the variant isLeft
orBoth
unwrap_only_right_unchecked
produces undefined behavior if the variant isLeft
orBoth
Non-panicking methods, optionally extract the contained values:
left
returnsSome
with the left value if present otherwiseNone
right
returnsSome
with the right value if present otherwiseNone
The methods both
, only_left
, only_right
are exclusive to EitherOrBoth
and return Some
with both values if Both
, and respectively Some
with the left
value if only Left
and Some
with the right value if only Right
. Finally,
unzip
produces a 2-tuple of Options
containing both values if present.
The left_and
, right_and
methods take another EitherOrBoth
or Either
as
input and produce an EitherOrBoth
or Either
as output.
Accordingly, left_and_then
, right_and_then
methods evaluate lazily by taking a
function as input.
The following non-panicking methods extract the contained value of an
EitherOrBoth<L, R>
and Either<L, R>
by providing default values or methods if
one of the values is missing:
or
produces a tuple(L, R)
with the given values supplying a possibly missing left or right valueor_default
returns a tuple withL::default
orR::default
if one of them is missing.or_else
returns a tuple computing the missing left or right values with a given function.
Reducing methods extract the contained value into a single value, potentially
converting it to a different type T
, rather than returning a tuple:
reduce_left
extracts theL
value, otherwise applies a given function converting theR
value to aL
valuereduce_right
extracts theR
value, otherwise applies a given function converting theL
value to aR
value
Other reductions work differently for EitherOrBoth
and Either
. With Either
bireduce
applies the given functions converting theL
andR
to a typeT
. The uniform type version ofbireduce
is namedreduce
.
EitherOrBoth<L, R>
doesn’t have a single bireduce
method, but instead two
methods:
reduce_map_left
which applies the given function to theL
value if the variant isLeft
orBoth
and another function to theR
value if the variant isRight
.reduce_map_right
which applies a given function to theR
value if the variant isRight
orBoth
and another function to theL
value if the variant isLeft
.
There is a uniform type version EitherOrBoth::reduce
, which extracts Left
or
Right
, otherwise it applies a function reducing Both
to a single value.
§Conversions
The most basic conversion EitherOrBoth<L, R>
to EitherOrBoth<R, L>
can be
achieved with flip
. Similar Either<L, R>
to Either<R, L>
with flip
.
These methods convert to the other variant without changing the signature:
into_left
converts aRight
orBoth
variant into aLeft
variant by applying a provided conversion function to theRight
value if necessaryinto_right
converts aLeft
orBoth
variant into aRight
variant by applying a provided conversion function to theLeft
value if necessary
§Transforming contained values
The methods below convert to a Result
as described in the convention:
ok
: This method transformsLeft(v)
toErr(v)
,Right(v)
toOk(v)
and in the case ofEitherOrBoth
,Both(l, r)
toErr(l)
ok_or
transformsRight(v)
toOk(v)
and a left value toErr
with the providederr
value.ok_or_else
transformsRight(v)
toOk(v)
and a left value toErr
using the provided function.
These methods transform the inner values to other types using provided functions:
bimap
transformsEitherOrBoth<L, R>
toEitherOrBoth<T, U>
map_left
transformsEitherOrBoth<L, R>
toEitherOrBoth<T, R>
map_right
transformsEitherOrBoth<L, R>
toEitherOrBoth<L, U>
map
transformsEitherOrBoth<T, T>
toEitherOrBoth<U, U>
These methods transform EitherOrBoth<L, R>
to a value of a possibly different type
T
:
map_left_or
applies the provided function to the left value or returns the provided default value if there is only a right value.map_left_or_else
applies the provided function to the left value or returns the result of evaluating the provided fallback function if there is only a right value.map_left_or_default
applies the provided function to the left value or returns the default of the target value if there is only a right value.
The map_right_or
, map_right_or_else
and map_right_or_default
methods are
the equivalent methods applying a provided function to the right value.
Swapping an EitherOrBoth
or Either
of an inner value to the inner value of an
EitherOrBoth
or Either
is possible with transpose
if the inner values are
a Result
, Option
or tuple respectively. The Both
variant can be tricky
because it can contain an error (or None
) and correct value (or Some
)
simultaneously. As per convention mentioned above, the error (or None
) value takes
precedence.
The uniform type cases can be handled separately with transpose_ok
and
transpose_err
for Result
and transpose_left
and transpose_right
for
tuples.
§Consumers
These methods apply a method to the contained values and the mutable environment
consuming the EitherOrBoth
. The evaluation order is from left to right if Both
values are present. Evaluation from right to left is possible by first
flipping
the values.
biapply
applies the provided functions to the contained values taking mutable references to capture variables.biapply_with
works similar but also takes a mutable accumulator which is available in both functions.apply_left
applies the provided function to the contained left valueapply_right
applies the provided function to the contained right valueapply
is the uniform type method equivalent tobiapply
These methods are lighter versions, consuming the EitherOrBoth
or Either
then
apply functions to the contained values by reference and eventually returning the
EitherOrBoth
or Either
again.
biinspect
applies the provided functions to the contained values starting with the left and continuing with the right value.inspect_left
applies the provided function to the contained left valueinspect_right
applies the provided function to the contained right valueinspect
is the uniform type method equivalent tobiinspect
§Iterating
Iterating over Either
and EitherOrBoth
is slightly different
§Iterating over EitherOrBoth
EitherOrBoth
can be iterated over directly if the types are uniform
EitherOrBoth<T>
. The iterator produces a single value if Left
or Right
and two
values if Both
by iterating from left to right. The uniform iterators over the type
T
come in in three types:
into_iter
consumes theEitherOrBoth
iter
produces immutable references of type&T
to the contained valuesiter_mut
produces mutable references of type&mut T
to the contained values
If the uniform inner types implement IntoIterator
the EitherOrBoth
can be
iterated over by chaining both iterators from left to right:
into_iter_chain
consumes theEitherOrBoth
iter_chain
produces immutable references of type&T
of the chained iteratorsiter_chain_mut
produces mutable references of type&mut T
of the chained iterators
If the types are not uniform iterating over EitherOrBoth
can be achieved if the
inner types implement IntoIterator
. Instead of EitherOrBoth<Iterator<Item = L>, Iterator<Item = R>>
the iterators are swapped Iterator<Item = EitherOrBoth<L, R>>
:
into_iter_swap
consumes theEitherOrBoth
iter_swap
produces immutable references ofEitherOrBoth<&L, &R>
iter_swap_mut
produces mutable references ofEitherOrBoth<&mut L, &mut R>
§Iterating over Either
Like EitherOrBoth
, an Either
can be iterated over directly if the types are
uniform Either<T>
. The iterator produces a single value. The uniform iterators
over the type T
come in in three types:
into_iter
consumes theEither
iter
produces an immutable reference of type&T
to the contained valueiter_mut
produces an mutable reference of type&mut T
to the contained value
If the uniform inner types implement IntoIterator
, the Either
can be iterator
over with:
into_iter_inner
consumes theEither
iter_inner
produces immutable references of type&T
to the inner iterator valuesiter_inner_mut
produces mutable references of type&mut T
to the inner iterator values
If the Either
types are non-uniform, the swap iterator for Either
work exactly
the same as the EitherOrBoth
swap iterators:
into_iter_swap
consumes theEither
iter_swap
produces immutable references ofEither<&L, &R>
iter_swap_mut
produces mutable references ofEither<&mut L, &mut R>
§Collecting into EitherOrBoth
EitherOrBoth
implements the FromIterator
trait which allows an iterator over
Either
or EitherOrBoth
to be collected into an EitherOrBoth
of two
collections, the left collection containing the left values and the right collection
containing the right values.
use either_or_both::{Either, EitherOrBoth};
let vector: Vec<Either<i32>> = vec![Either::Left(2), Either::Left(1)];
let either_or_both: EitherOrBoth<Vec<i32>> = vector.into_iter().collect();
assert_eq!(either_or_both, EitherOrBoth::Left(vec![2, 1]));
let vector: Vec<Either<i32>> = vec![Either::Left(2), Either::Right(1)];
let either_or_both: EitherOrBoth<Vec<i32>> = vector.into_iter().collect();
assert_eq!(either_or_both, EitherOrBoth::Both(vec![2], vec![1]));
§Modifying in-place
Both enums support replacing the left or right values:
replace_left
as the name suggests replaces the left value returning the old value if successfulreplace_right
replaces the right value returning the old value if successful
replace_any
is special to EitherOrBoth
and replaces all values returning the old
EitherOrBoth
.
Insertion is supported for EitherOrBoth
and these methods return a mutable reference to the
contained value:
insert_left
: inserts a new left value and ifRight
changes to aBoth
valueinsert_right
: inserts a new right value and ifLeft
changes to aBoth
valueleft_or_insert
: returns a mutable reference to the left value or ifRight
, inserts a left value convertingself
to aBoth
valueleft_or_insert_with
: returns a mutable reference to the left value or ifRight
, inserts a lazily computed left value convertingself
to aBoth
valueright_or_insert
: returns a mutable reference to the right value or ifLeft
, inserts a right value convertingself
to aBoth
valueright_or_insert_with
: returns a mutable reference to the right value or ifLeft
, inserts a lazily computed right value convertingself
to aBoth
value
Modules§
- iter
- Iterators for
EitherOrBoth
- iter_
either either
- Iterators for
Either
Structs§
- TryFrom
Options Error - The error if converting from a 2-tuple of
Options
tocrate::EitherOrBoth
fails
Enums§
- Either
either
- Represent values with two possibilities.
Either
can be eitherLeft
orRight
- Either
OrBoth - Represent values that have either a
Left
orRight
value orBoth
values