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_refconverts from&EitherOrBoth<L, R>toEitherOrBoth<&L, &R>as_mutconverts from&mut EitherOrBoth<L, R>toEitherOrBoth<&mut L, &mut R>as_derefconverts from&EitherOrBoth<L, R>toEitherOrBoth<&L::Target, &R::Target>as_deref_mutconverts from&mut EitherOrBoth<L, R>toEitherOrBoth<&mut L::Target, &mut R::Target>as_pin_refconverts fromPin<&EitherOrBoth<L, R>>toEitherOrBoth<Pin<&L>, Pin<&R>>as_pin_mutconverts 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_leftpanics with a provided custom message if the variant isRightexpect_rightpanics with a provided custom message if the variant isLeftunwrap_leftpanics with a generic message if the variant isRightunwrap_rightpanics with a generic message if the variant isLeftunwrap_left_uncheckedproduces undefined behavior if the variant isRightunwrap_right_uncheckedproduces undefined behavior if the variant isLeft
EitherOrBoth provides additional methods:
expect_bothpanics with a provided custom message if the variant isRightorLeftunwrap_bothpanics with a generic message if the variant isRightorLeftunwrap_both_uncheckedproduces undefined behavior if the variant isRightorLeftexpect_only_leftpanics with a provided custom message if the variant isRightorBothunwrap_only_leftpanics with a generic message if the variant isRightorBothunwrap_only_left_uncheckedproduces undefined behavior if the variant isRightorBothexpect_only_rightpanics with a provided custom message if the variant isLeftorBothunwrap_only_rightpanics with a generic message if the variant isLeftorBothunwrap_only_right_uncheckedproduces undefined behavior if the variant isLeftorBoth
Non-panicking methods, optionally extract the contained values:
leftreturnsSomewith the left value if present otherwiseNonerightreturnsSomewith 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:
orproduces a tuple(L, R)with the given values supplying a possibly missing left or right valueor_defaultreturns a tuple withL::defaultorR::defaultif one of them is missing.or_elsereturns 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_leftextracts theLvalue, otherwise applies a given function converting theRvalue to aLvaluereduce_rightextracts theRvalue, otherwise applies a given function converting theLvalue to aRvalue
Other reductions work differently for EitherOrBoth and Either. With Either
bireduceapplies the given functions converting theLandRto a typeT. The uniform type version ofbireduceis namedreduce.
EitherOrBoth<L, R> doesn’t have a single bireduce method, but instead two
methods:
reduce_map_leftwhich applies the given function to theLvalue if the variant isLeftorBothand another function to theRvalue if the variant isRight.reduce_map_rightwhich applies a given function to theRvalue if the variant isRightorBothand another function to theLvalue 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_leftconverts aRightorBothvariant into aLeftvariant by applying a provided conversion function to theRightvalue if necessaryinto_rightconverts aLeftorBothvariant into aRightvariant by applying a provided conversion function to theLeftvalue 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_ortransformsRight(v)toOk(v)and a left value toErrwith the providederrvalue.ok_or_elsetransformsRight(v)toOk(v)and a left value toErrusing the provided function.
These methods transform the inner values to other types using provided functions:
bimaptransformsEitherOrBoth<L, R>toEitherOrBoth<T, U>map_lefttransformsEitherOrBoth<L, R>toEitherOrBoth<T, R>map_righttransformsEitherOrBoth<L, R>toEitherOrBoth<L, U>maptransformsEitherOrBoth<T, T>toEitherOrBoth<U, U>
These methods transform EitherOrBoth<L, R> to a value of a possibly different type
T:
map_left_orapplies the provided function to the left value or returns the provided default value if there is only a right value.map_left_or_elseapplies 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_defaultapplies 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.
biapplyapplies the provided functions to the contained values taking mutable references to capture variables.biapply_withworks similar but also takes a mutable accumulator which is available in both functions.apply_leftapplies the provided function to the contained left valueapply_rightapplies the provided function to the contained right valueapplyis 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.
biinspectapplies the provided functions to the contained values starting with the left and continuing with the right value.inspect_leftapplies the provided function to the contained left valueinspect_rightapplies the provided function to the contained right valueinspectis 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_iterconsumes theEitherOrBothiterproduces immutable references of type&Tto the contained valuesiter_mutproduces mutable references of type&mut Tto 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_chainconsumes theEitherOrBothiter_chainproduces immutable references of type&Tof the chained iteratorsiter_chain_mutproduces mutable references of type&mut Tof 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_swapconsumes theEitherOrBothiter_swapproduces immutable references ofEitherOrBoth<&L, &R>iter_swap_mutproduces 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_iterconsumes theEitheriterproduces an immutable reference of type&Tto the contained valueiter_mutproduces an mutable reference of type&mut Tto the contained value
If the uniform inner types implement IntoIterator, the Either can be iterator
over with:
into_iter_innerconsumes theEitheriter_innerproduces immutable references of type&Tto the inner iterator valuesiter_inner_mutproduces mutable references of type&mut Tto 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_swapconsumes theEitheriter_swapproduces immutable references ofEither<&L, &R>iter_swap_mutproduces 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_leftas the name suggests replaces the left value returning the old value if successfulreplace_rightreplaces 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 ifRightchanges to aBothvalueinsert_right: inserts a new right value and ifLeftchanges to aBothvalueleft_or_insert: returns a mutable reference to the left value or ifRight, inserts a left value convertingselfto aBothvalueleft_or_insert_with: returns a mutable reference to the left value or ifRight, inserts a lazily computed left value convertingselfto aBothvalueright_or_insert: returns a mutable reference to the right value or ifLeft, inserts a right value convertingselfto aBothvalueright_or_insert_with: returns a mutable reference to the right value or ifLeft, inserts a lazily computed right value convertingselfto aBothvalue
Modules§
- iter
- Iterators for
EitherOrBoth - iter_
either either - Iterators for
Either
Structs§
- TryFrom
Options Error - The error if converting from a 2-tuple of
Optionstocrate::EitherOrBothfails
Enums§
- Either
either - Represent values with two possibilities.
Eithercan be eitherLeftorRight - Either
OrBoth - Represent values that have either a
LeftorRightvalue orBothvalues