either_or_both/lib.rs
1//! # `EitherOrBoth` and `Either`
2//!
3//! `either-or-both` provides two enums: [`Either`] and [`EitherOrBoth`].
4//!
5//! * **`Either<L, R>`** — a value that is either `Left(L)` or `Right(R)`
6//! * **`EitherOrBoth<L, R>`** — a value that can be `Left(L)`, `Right(R)`, or `Both(L, R)`
7//!
8//! While `Either` is useful for representing mutually exclusive values, `EitherOrBoth`
9//! extends this idea by allowing both values to be present simultaneously.
10//!
11//! # Conventions and edge cases
12//!
13//! In most cases, [`Either`] and [`EitherOrBoth`] do not prioritize `Left` over `Right`
14//! values, or vice versa. However, in some contexts, `Left` is used to represent an error
15//! and `Right` a correct value - using "right" as a mnemonic for "correct".
16//!
17//! With [`EitherOrBoth`], the `Both` variant may contain both an error and a correct
18//! value. Unless explicitly stated otherwise, the error value takes precedence during
19//! evaluation. The same principle applies to [`Option`] types, where `None` takes
20//! precedence over `Some`.
21//!
22//! Uniform type versions of bi-functional methods drop the bi- prefix. For example, bimap
23//! applies two functions to potentially different types (`L` and `R`), while map applies
24//! the same function to both sides of a uniform type `T`.
25//!
26//! When evaluation order matters for [`EitherOrBoth`] methods, values are processed left
27//! to right. To reverse this order, use [flip][EitherOrBoth::flip].
28//!
29//! # Method Overview
30//!
31//! [`Either`] and [`EitherOrBoth`] provide a wide variety of different methods. Often,
32//! the links and descriptions in the following sections use [`EitherOrBoth`] but if not
33//! specified otherwise, the same methods are available for [`Either`].
34//!
35//! ## Querying the variant
36//!
37//! Similar to [`Option::is_some`] and [`Option::is_none`], [`is_left`][Either::is_left]
38//! and [`is_right`][Either::is_right] return `true` if the [`Either`] or [`EitherOrBoth`]
39//! is `Left` or `Right` respectively. Additionally, [`is_both`][EitherOrBoth::is_both]
40//! returns true if [`EitherOrBoth`] is `Both`. Since [`EitherOrBoth`] can hold a left
41//! value in the `Both` and `Left` case, the method [`has_left`][EitherOrBoth::has_left]
42//! returns true if the variant is either `Both` or `Left`. Symmetrically, the right value
43//! is covered with [`has_right`][EitherOrBoth::has_right].
44//!
45//! Methods like [`is_left_and`][Either::is_left_and], [`is_left_or`][Either::is_left_or],
46//! [`has_left_and`][EitherOrBoth::has_left_and],
47//! [`has_left_or`][EitherOrBoth::has_left_or], ... apply a function to the contents of
48//! [`Either`] or [`EitherOrBoth`] to compute a boolean value.
49//!
50//! ## Adapters for working with references
51//!
52//! * [`as_ref`] converts from [`&EitherOrBoth<L, R>`][EitherOrBoth] to [`EitherOrBoth<&L,
53//! &R>`][EitherOrBoth]
54//! * [`as_mut`] converts from [`&mut EitherOrBoth<L, R>`][EitherOrBoth] to [`EitherOrBoth<&mut
55//! L, &mut R>`][EitherOrBoth]
56//! * [`as_deref`] converts from [`&EitherOrBoth<L, R>`][EitherOrBoth] to
57//! [`EitherOrBoth<&L::Target, &R::Target>`][EitherOrBoth]
58//! * [`as_deref_mut`] converts from [`&mut EitherOrBoth<L, R>`][EitherOrBoth] to
59//! [`EitherOrBoth<&mut L::Target, &mut R::Target>`][EitherOrBoth]
60//! * [`as_pin_ref`] converts from [`Pin<&EitherOrBoth<L, R>>`][EitherOrBoth] to
61//! [`EitherOrBoth<Pin<&L>, Pin<&R>>`][EitherOrBoth]
62//! * [`as_pin_mut`] converts from [`Pin<&mut EitherOrBoth<L, R>>`][EitherOrBoth] to
63//! [`EitherOrBoth<Pin<&mut L>, Pin<&mut R>>`][EitherOrBoth]
64//!
65//! [`as_deref`]: EitherOrBoth::as_deref
66//! [`as_deref_mut`]: EitherOrBoth::as_deref_mut
67//! [`as_mut`]: EitherOrBoth::as_mut
68//! [`as_pin_mut`]: EitherOrBoth::as_pin_mut
69//! [`as_pin_ref`]: EitherOrBoth::as_pin_ref
70//! [`as_ref`]: EitherOrBoth::as_ref
71//!
72//! ## Extracting the contained values
73//!
74//! These methods extract the contained value in an [`EitherOrBoth<L, R>`] or [`Either<L,
75//! R>`]
76//!
77//! * [`expect_left`] panics with a provided custom message if the variant is `Right`
78//! * [`expect_right`] panics with a provided custom message if the variant is `Left`
79//! * [`unwrap_left`] panics with a generic message if the variant is `Right`
80//! * [`unwrap_right`] panics with a generic message if the variant is `Left`
81//! * [`unwrap_left_unchecked`] produces *[undefined behavior]* if the variant is `Right`
82//! * [`unwrap_right_unchecked`] produces *[undefined behavior]* if the variant is `Left`
83//!
84//! [`EitherOrBoth`] provides additional methods:
85//!
86//! * [`expect_both`] panics with a provided custom message if the variant is `Right` or `Left`
87//! * [`unwrap_both`] panics with a generic message if the variant is `Right` or `Left`
88//! * [`unwrap_both_unchecked`] produces *[undefined behavior]* if the variant is `Right` or
89//! `Left`
90//! * [`expect_only_left`] panics with a provided custom message if the variant is `Right` or
91//! `Both`
92//! * [`unwrap_only_left`] panics with a generic message if the variant is `Right` or `Both`
93//! * [`unwrap_only_left_unchecked`] produces *[undefined behavior]* if the variant is `Right`
94//! or `Both`
95//! * [`expect_only_right`] panics with a provided custom message if the variant is `Left` or
96//! `Both`
97//! * [`unwrap_only_right`] panics with a generic message if the variant is `Left` or `Both`
98//! * [`unwrap_only_right_unchecked`] produces *[undefined behavior]* if the variant is `Left`
99//! or `Both`
100//!
101//! [`expect_both`]: EitherOrBoth::expect_both
102//! [`unwrap_both`]: EitherOrBoth::unwrap_both
103//! [`unwrap_both_unchecked`]: EitherOrBoth::unwrap_both_unchecked
104//! [`expect_left`]: EitherOrBoth::expect_left
105//! [`unwrap_left`]: EitherOrBoth::unwrap_left
106//! [`unwrap_left_unchecked`]: EitherOrBoth::unwrap_left_unchecked
107//! [`expect_right`]: EitherOrBoth::expect_right
108//! [`unwrap_right`]: EitherOrBoth::unwrap_right
109//! [`unwrap_right_unchecked`]: EitherOrBoth::unwrap_right_unchecked
110//! [`expect_only_left`]: EitherOrBoth::expect_left
111//! [`unwrap_only_left`]: EitherOrBoth::unwrap_left
112//! [`unwrap_only_left_unchecked`]: EitherOrBoth::unwrap_left_unchecked
113//! [`expect_only_right`]: EitherOrBoth::expect_right
114//! [`unwrap_only_right`]: EitherOrBoth::unwrap_right
115//! [`unwrap_only_right_unchecked`]: EitherOrBoth::unwrap_right_unchecked
116//! [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
117//!
118//! Non-panicking methods, optionally extract the contained values:
119//!
120//! * [`left`] returns `Some` with the left value if present otherwise `None`
121//! * [`right`] returns `Some` with the right value if present otherwise `None`
122//!
123//! The methods [`both`], [`only_left`], [`only_right`] are exclusive to [`EitherOrBoth`]
124//! and return `Some` with both values if `Both`, and respectively `Some` with the left
125//! value if only `Left` and `Some` with the right value if only `Right`. Finally,
126//! [`unzip`] produces a 2-tuple of [`Options`][Option] containing both values if present.
127//!
128//! [`both`]: EitherOrBoth::both
129//! [`left`]: EitherOrBoth::left
130//! [`only_left`]: EitherOrBoth::only_left
131//! [`right`]: EitherOrBoth::right
132//! [`only_right`]: EitherOrBoth::only_right
133//! [`unzip`]: EitherOrBoth::unzip
134//!
135//! The [`left_and`], [`right_and`] methods take another [`EitherOrBoth`] or [`Either`] as
136//! input and produce an [`EitherOrBoth`] or [`Either`] as output.
137//!
138//! [`left_and`]: EitherOrBoth::left_and
139//! [`right_and`]: EitherOrBoth::right_and
140//!
141//! Accordingly, [`left_and_then`], [`right_and_then`] methods evaluate lazily by taking a
142//! function as input.
143//!
144//! [`left_and_then`]: EitherOrBoth::left_and_then
145//! [`right_and_then`]: EitherOrBoth::right_and_then
146//!
147//! The following non-panicking methods extract the contained value of an
148//! [`EitherOrBoth<L, R>`] and [`Either<L, R>`] by providing default values or methods if
149//! one of the values is missing:
150//!
151//! * [`or`] produces a tuple `(L, R)` with the given values supplying a possibly missing left
152//! or right value
153//! * [`or_default`] returns a tuple with `L::default` or `R::default` if one of them is
154//! missing.
155//! * [`or_else`] returns a tuple computing the missing left or right values with a given
156//! function.
157//!
158//! [`or`]: EitherOrBoth::or
159//! [`or_default`]: EitherOrBoth::or_default
160//! [`or_else`]: EitherOrBoth::or_else
161//!
162//! Reducing methods extract the contained value into a single value, potentially
163//! converting it to a different type `T`, rather than returning a tuple:
164//!
165//! * [`reduce_left`] extracts the `L` value, otherwise applies a given function converting the
166//! `R` value to a `L` value
167//! * [`reduce_right`] extracts the `R` value, otherwise applies a given function converting
168//! the `L` value to a `R` value
169//!
170//! [`reduce_left`]: EitherOrBoth::reduce_left
171//! [`reduce_right`]: EitherOrBoth::reduce_right
172//!
173//! Other reductions work differently for [`EitherOrBoth`] and [`Either`]. With [`Either`]
174//!
175//! * [`bireduce`] applies the given functions converting the `L` and `R` to a type `T`. The
176//! uniform type version of [`bireduce`] is named [`reduce`].
177//!
178//! [`bireduce`]: Either::bireduce
179//! [`reduce`]: Either::reduce
180//!
181//! [`EitherOrBoth<L, R>`] doesn't have a single `bireduce` method, but instead two
182//! methods:
183//!
184//! * [`reduce_map_left`] which applies the given function to the `L` value if the variant is
185//! `Left` or `Both` and another function to the `R` value if the variant is `Right`.
186//! * [`reduce_map_right`] which applies a given function to the `R` value if the variant is
187//! `Right` or `Both` and another function to the `L` value if the variant is `Left`.
188//!
189//! There is a uniform type version [`EitherOrBoth::reduce`], which extracts `Left` or
190//! `Right`, otherwise it applies a function reducing `Both` to a single value.
191//!
192//! [`reduce_map_left`]: EitherOrBoth::reduce_map_left
193//! [`reduce_map_right`]: EitherOrBoth::reduce_map_right
194//!
195//! ## Conversions
196//!
197//! The most basic conversion [`EitherOrBoth<L, R>`] to [`EitherOrBoth<R, L>`] can be
198//! achieved with [`flip`][EitherOrBoth::flip]. Similar [`Either<L, R>`] to [`Either<R,
199//! L>`] with [`flip`][Either::flip].
200//!
201//! These methods convert to the other variant without changing the signature:
202//!
203//! * [`into_left`] converts a `Right` or `Both` variant into a `Left` variant by applying a
204//! provided conversion function to the `Right` value if necessary
205//! * [`into_right`] converts a `Left` or `Both` variant into a `Right` variant by applying a
206//! provided conversion function to the `Left` value if necessary
207//!
208//! [`into_left`]: EitherOrBoth::into_left
209//! [`into_right`]: EitherOrBoth::into_right
210//!
211//! ## Transforming contained values
212//!
213//! The methods below convert to a [`Result`] as described in the [convention]:
214//!
215//! * [`ok`]: This method transforms [`Left(v)`] to [`Err(v)`], [`Right(v)`] to [`Ok(v)`] and
216//! in the case of [`EitherOrBoth`], [`Both(l, r)`] to [`Err(l)`]
217//! * [`ok_or`] transforms [`Right(v)`] to [`Ok(v)`] and a left value to [`Err`] with the
218//! provided `err` value.
219//! * [`ok_or_else`] transforms [`Right(v)`] to [`Ok(v)`] and a left value to [`Err`] using the
220//! provided function.
221//!
222//! [`ok`]: Either::ok
223//! [`ok_or`]: Either::ok_or
224//! [`ok_or_else`]: Either::ok_or
225//! [`Left`]: Either::Left
226//! [`Left(v)`]: Either::Left
227//! [`Right(v)`]: Either::Right
228//! [`Ok(v)`]: Result::Ok
229//! [`Err(v)`]: Result::Err
230//! [`Err(l)`]: Result::Err
231//! [`Err(r)`]: Result::Err
232//! [`Both(l, r)`]: EitherOrBoth::Both
233//! [convention]: #conventions-and-edge-cases
234//!
235//! These methods transform the inner values to other types using provided functions:
236//!
237//! * [`bimap`] transforms [`EitherOrBoth<L, R>`] to [`EitherOrBoth<T, U>`]
238//! * [`map_left`] transforms [`EitherOrBoth<L, R>`] to [`EitherOrBoth<T, R>`]
239//! * [`map_right`] transforms [`EitherOrBoth<L, R>`] to [`EitherOrBoth<L, U>`]
240//! * [`map`] transforms [`EitherOrBoth<T, T>`] to [`EitherOrBoth<U, U>`]
241//!
242//! [`bimap`]: EitherOrBoth::bimap
243//! [`map_left`]: EitherOrBoth::map_left
244//! [`map_right`]: EitherOrBoth::map_right
245//! [`map`]: EitherOrBoth::map
246//!
247//! These methods transform [`EitherOrBoth<L, R>`] to a value of a possibly different type
248//! `T`:
249//!
250//! * [`map_left_or`] applies the provided function to the left value or returns the provided
251//! default value if there is only a right value.
252//! * [`map_left_or_else`] applies the provided function to the left value or returns the
253//! result of evaluating the provided fallback function if there is only a right value.
254//! * [`map_left_or_default`] applies the provided function to the left value or returns the
255//! default of the target value if there is only a right value.
256//!
257//! The [`map_right_or`], [`map_right_or_else`] and [`map_right_or_default`] methods are
258//! the equivalent methods applying a provided function to the right value.
259//!
260//! [`map_left_or`]: EitherOrBoth::map_left_or
261//! [`map_left_or_default`]: EitherOrBoth::map_left_or_default
262//! [`map_left_or_else`]: EitherOrBoth::map_left_or_else
263//! [`map_right_or`]: EitherOrBoth::map_right_or
264//! [`map_right_or_default`]: EitherOrBoth::map_right_or_default
265//! [`map_right_or_else`]: EitherOrBoth::map_right_or_else
266//!
267//! Swapping an [`EitherOrBoth`] or [`Either`] of an inner value to the inner value of an
268//! [`EitherOrBoth`] or [`Either`] is possible with [`transpose`] if the inner values are
269//! a [`Result`], [`Option`] or tuple respectively. The `Both` variant can be tricky
270//! because it can contain an error (or `None`) and correct value (or `Some`)
271//! simultaneously. As per [convention] mentioned above, the error (or `None`) value takes
272//! precedence.
273//!
274//! | From | To |
275//! | --- | --- |
276//! | [`EitherOrBoth<Result<L1, E1>, Result<L2, E2>>`] | [`Result<EitherOrBoth<L1, L2> EitherOrBoth<E1, E2>>`] |
277//! | [`EitherOrBoth<Option<L>, Option<R>>`] | [`Option<EitherOrBoth<L, R>>`] |
278//! | [`EitherOrBoth<(L1, R1), (L2, R2)>`][EitherOrBoth] | [`(EitherOrBoth<L1, L2>, EitherOrBoth<R1, R2>)`][EitherOrBoth] |
279//!
280//! The uniform type cases can be handled separately with [`transpose_ok`] and
281//! [`transpose_err`] for [`Result`] and [`transpose_left`] and [`transpose_right`] for
282//! tuples.
283//!
284//! [`transpose`]: EitherOrBoth::transpose
285//! [`transpose_left`]: EitherOrBoth::transpose_left
286//! [`transpose_right`]: EitherOrBoth::transpose_right
287//! [`transpose_ok`]: EitherOrBoth::transpose_ok
288//! [`transpose_err`]: EitherOrBoth::transpose_err
289//!
290//! ## Consumers
291//!
292//! These methods apply a method to the contained values and the mutable environment
293//! consuming the [`EitherOrBoth`]. The evaluation order is from left to right if `Both`
294//! values are present. Evaluation from right to left is possible by first
295//! [`flipping`][`EitherOrBoth::flip`] the values.
296//!
297//! * [`biapply`] applies the provided functions to the contained values taking mutable
298//! references to capture variables.
299//! * [`biapply_with`] works similar but also takes a mutable accumulator which is available in
300//! both functions.
301//! * [`apply_left`] applies the provided function to the contained left value
302//! * [`apply_right`] applies the provided function to the contained right value
303//! * [`apply`] is the uniform type method equivalent to [`biapply`]
304//!
305//! [`biapply`]: EitherOrBoth::biapply
306//! [`biapply_with`]: EitherOrBoth::biapply_with
307//! [`apply_left`]: EitherOrBoth::apply_left
308//! [`apply_right`]: EitherOrBoth::apply_right
309//! [`apply`]: EitherOrBoth::apply
310//!
311//! These methods are lighter versions, consuming the [`EitherOrBoth`] or [`Either`] then
312//! apply functions to the contained values by reference and eventually returning the
313//! [`EitherOrBoth`] or [`Either`] again.
314//!
315//! * [`biinspect`] applies the provided functions to the contained values starting with the
316//! left and continuing with the right value.
317//! * [`inspect_left`] applies the provided function to the contained left value
318//! * [`inspect_right`] applies the provided function to the contained right value
319//! * [`inspect`] is the uniform type method equivalent to [`biinspect`]
320//!
321//! [`biinspect`]: EitherOrBoth::biinspect
322//! [`inspect_left`]: EitherOrBoth::inspect_left
323//! [`inspect_right`]: EitherOrBoth::inspect_right
324//! [`inspect`]: EitherOrBoth::inspect
325//!
326//! ## Iterating
327//!
328//! Iterating over [`Either`] and [`EitherOrBoth`] is slightly different
329//!
330//! ### Iterating over [`EitherOrBoth`]
331//!
332//! [`EitherOrBoth`] can be iterated over directly if the types are uniform
333//! [`EitherOrBoth<T>`]. The iterator produces a single value if `Left` or `Right` and two
334//! values if `Both` by iterating from left to right. The uniform iterators over the type
335//! `T` come in in three types:
336//!
337//! * [`into_iter`][EitherOrBoth::into_iter] consumes the [`EitherOrBoth`]
338//! * [`iter`][EitherOrBoth::iter] produces immutable references of type `&T` to the contained
339//! values
340//! * [`iter_mut`][EitherOrBoth::iter_mut] produces mutable references of type `&mut T` to the
341//! contained values
342//!
343//! If the uniform inner types implement [`IntoIterator`] the [`EitherOrBoth`] can be
344//! iterated over by chaining both iterators from left to right:
345//!
346//! * [`into_iter_chain`] consumes the [`EitherOrBoth`]
347//! * [`iter_chain`] produces immutable references of type `&T` of the chained iterators
348//! * [`iter_chain_mut`] produces mutable references of type `&mut T` of the chained iterators
349//!
350//! [`into_iter_chain`]: EitherOrBoth::into_iter_chain
351//! [`iter_chain`]: EitherOrBoth::iter_chain
352//! [`iter_chain_mut`]: EitherOrBoth::iter_chain_mut
353//!
354//! If the types are not uniform iterating over [`EitherOrBoth`] can be achieved if the
355//! inner types implement [`IntoIterator`]. Instead of [`EitherOrBoth<Iterator<Item = L>,
356//! Iterator<Item = R>>`][EitherOrBoth] the iterators are swapped [`Iterator<Item =
357//! EitherOrBoth<L, R>>`][Iterator]:
358//!
359//! * [`into_iter_swap`] consumes the [`EitherOrBoth`]
360//! * [`iter_swap`] produces immutable references of [`EitherOrBoth<&L, &R>`]
361//! * [`iter_swap_mut`] produces mutable references of [`EitherOrBoth<&mut L, &mut R>`]
362//!
363//! [`into_iter_swap`]: EitherOrBoth::into_iter_swap
364//! [`iter_swap`]: EitherOrBoth::iter_swap
365//! [`iter_swap_mut`]: EitherOrBoth::iter_swap_mut
366//!
367//! ### Iterating over [`Either`]
368//!
369//! Like [`EitherOrBoth`], an [`Either`] can be iterated over directly if the types are
370//! uniform [`Either<T>`]. The iterator produces a single value. The uniform iterators
371//! over the type `T` come in in three types:
372//!
373//! * [`into_iter`][Either::into_iter] consumes the [`Either`]
374//! * [`iter`][Either::iter] produces an immutable reference of type `&T` to the contained
375//! value
376//! * [`iter_mut`][Either::iter_mut] produces an mutable reference of type `&mut T` to the
377//! contained value
378//!
379//! If the uniform inner types implement [`IntoIterator`], the [`Either`] can be iterator
380//! over with:
381//!
382//! * [`into_iter_inner`][Either::into_iter_inner] consumes the [`Either`]
383//! * [`iter_inner`][Either::iter_inner] produces immutable references of type `&T` to the
384//! inner iterator values
385//! * [`iter_inner_mut`][Either::iter_inner_mut] produces mutable references of type `&mut T`
386//! to the inner iterator values
387//!
388//! If the [`Either`] types are non-uniform, the swap iterator for [`Either`] work exactly
389//! the same as the [`EitherOrBoth`] swap iterators:
390//!
391//! * [`into_iter_swap`][Either::into_iter_swap] consumes the [`Either`]
392//! * [`iter_swap`][Either::iter_swap] produces immutable references of [`Either<&L, &R>`]
393//! * [`iter_swap_mut`][Either::iter_swap_mut] produces mutable references of [`Either<&mut L,
394//! &mut R>`]
395//!
396//! ## Collecting into [`EitherOrBoth`]
397//!
398//! [`EitherOrBoth`] implements the [`FromIterator`] trait which allows an iterator over
399//! [`Either`] or [`EitherOrBoth`] to be collected into an [`EitherOrBoth`] of two
400//! collections, the left collection containing the left values and the right collection
401//! containing the right values.
402#![cfg_attr(all(feature = "std", feature = "either"), doc = "```rust")]
403#![cfg_attr(not(all(feature = "std", feature = "either")), doc = "```rust,ignore")]
404//! use either_or_both::{Either, EitherOrBoth};
405//!
406//! let vector: Vec<Either<i32>> = vec![Either::Left(2), Either::Left(1)];
407//! let either_or_both: EitherOrBoth<Vec<i32>> = vector.into_iter().collect();
408//!
409//! assert_eq!(either_or_both, EitherOrBoth::Left(vec![2, 1]));
410//!
411//! let vector: Vec<Either<i32>> = vec![Either::Left(2), Either::Right(1)];
412//! let either_or_both: EitherOrBoth<Vec<i32>> = vector.into_iter().collect();
413//!
414//! assert_eq!(either_or_both, EitherOrBoth::Both(vec![2], vec![1]));
415//! ```
416//!
417//! ## Modifying in-place
418//!
419//! Both enums support replacing the left or right values:
420//!
421//! * [`replace_left`] as the name suggests replaces the left value returning the old value if
422//! successful
423//! * [`replace_right`] replaces the right value returning the old value if successful
424//!
425//! [`replace_any`] is special to [`EitherOrBoth`] and replaces all values returning the old
426//! [`EitherOrBoth`].
427//!
428//! [`replace_left`]: EitherOrBoth::replace_left
429//! [`replace_right`]: EitherOrBoth::replace_right
430//! [`replace_any`]: EitherOrBoth::replace_any
431//!
432//! Insertion is supported for [`EitherOrBoth`] and these methods return a mutable reference to the
433//! contained value:
434//!
435//! * [`insert_left`]: inserts a new left value and if `Right` changes to a `Both` value
436//! * [`insert_right`]: inserts a new right value and if `Left` changes to a `Both` value
437//! * [`left_or_insert`]: returns a mutable reference to the left value or if `Right`, inserts a
438//! left value converting `self` to a `Both` value
439//! * [`left_or_insert_with`]: returns a mutable reference to the left value or if `Right`, inserts
440//! a lazily computed left value converting `self` to a `Both` value
441//! * [`right_or_insert`]: returns a mutable reference to the right value or if `Left`, inserts a
442//! right value converting `self` to a `Both` value
443//! * [`right_or_insert_with`]: returns a mutable reference to the right value or if `Left`, inserts
444//! a lazily computed right value converting `self` to a `Both` value
445//!
446//! [`insert_left`]: EitherOrBoth::insert_left
447//! [`insert_right`]: EitherOrBoth::insert_right
448//! [`left_or_insert`]: EitherOrBoth::left_or_insert
449//! [`left_or_insert_with`]: EitherOrBoth::left_or_insert_with
450//! [`right_or_insert`]: EitherOrBoth::right_or_insert
451//! [`right_or_insert_with`]: EitherOrBoth::right_or_insert_with
452
453#![cfg_attr(not(feature = "std"), no_std)]
454#![cfg_attr(docsrs, feature(doc_auto_cfg))]
455
456#[cfg(feature = "std")]
457extern crate std;
458
459#[cfg(feature = "either")]
460mod either;
461mod either_or_both;
462mod error;
463
464#[cfg(feature = "either")]
465pub use either::{iter as iter_either, Either};
466pub use error::TryFromOptionsError;
467
468pub use crate::either_or_both::{iter, EitherOrBoth};