Crate either_or_both

Crate either_or_both 

Source
Expand description

§EitherOrBoth and Either

either-or-both provides two enums: Either and EitherOrBoth.

  • Either<L, R> — a value that is either Left(L) or Right(R)
  • EitherOrBoth<L, R> — a value that can be Left(L), Right(R), or Both(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

§Extracting the contained values

These methods extract the contained value in an EitherOrBoth<L, R> or Either<L, R>

EitherOrBoth provides additional methods:

Non-panicking methods, optionally extract the contained values:

  • left returns Some with the left value if present otherwise None
  • right returns Some with the right value if present otherwise None

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 value
  • or_default returns a tuple with L::default or R::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 the L value, otherwise applies a given function converting the R value to a L value
  • reduce_right extracts the R value, otherwise applies a given function converting the L value to a R value

Other reductions work differently for EitherOrBoth and Either. With Either

  • bireduce applies the given functions converting the L and R to a type T. The uniform type version of bireduce is named reduce.

EitherOrBoth<L, R> doesn’t have a single bireduce method, but instead two methods:

  • reduce_map_left which applies the given function to the L value if the variant is Left or Both and another function to the R value if the variant is Right.
  • reduce_map_right which applies a given function to the R value if the variant is Right or Both and another function to the L value if the variant is Left.

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 a Right or Both variant into a Left variant by applying a provided conversion function to the Right value if necessary
  • into_right converts a Left or Both variant into a Right variant by applying a provided conversion function to the Left value if necessary

§Transforming contained values

The methods below convert to a Result as described in the convention:

These methods transform the inner values to other types using provided functions:

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 value
  • apply_right applies the provided function to the contained right value
  • apply is the uniform type method equivalent to biapply

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 value
  • inspect_right applies the provided function to the contained right value
  • inspect is the uniform type method equivalent to biinspect

§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 the EitherOrBoth
  • iter produces immutable references of type &T to the contained values
  • iter_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:

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>>:

§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 the Either
  • iter produces an immutable reference of type &T to the contained value
  • iter_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:

If the Either types are non-uniform, the swap iterator for Either work exactly the same as the EitherOrBoth swap iterators:

§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 successful
  • replace_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 if Right changes to a Both value
  • insert_right: inserts a new right value and if Left changes to a Both value
  • left_or_insert: returns a mutable reference to the left value or if Right, inserts a left value converting self to a Both value
  • left_or_insert_with: returns a mutable reference to the left value or if Right, inserts a lazily computed left value converting self to a Both value
  • right_or_insert: returns a mutable reference to the right value or if Left, inserts a right value converting self to a Both value
  • right_or_insert_with: returns a mutable reference to the right value or if Left, inserts a lazily computed right value converting self to a Both value

Modules§

iter
Iterators for EitherOrBoth
iter_eithereither
Iterators for Either

Structs§

TryFromOptionsError
The error if converting from a 2-tuple of Options to crate::EitherOrBoth fails

Enums§

Eithereither
Represent values with two possibilities. Either can be either Left or Right
EitherOrBoth
Represent values that have either a Left or Right value or Both values