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//! ## Extracting the contained values
66//!
67//! These methods extract the contained value in an [`EitherOrBoth<L, R>`] or [`Either<L,
68//! R>`]
69//!
70//! * [`expect_left`] panics with a provided custom message if the variant is `Right`
71//! * [`expect_right`] panics with a provided custom message if the variant is `Left`
72//! * [`unwrap_left`] panics with a generic message if the variant is `Right`
73//! * [`unwrap_right`] panics with a generic message if the variant is `Left`
74//! * [`unwrap_left_unchecked`] produces *[undefined behavior]* if the variant is `Right`
75//! * [`unwrap_right_unchecked`] produces *[undefined behavior]* if the variant is `Left`
76//!
77//! [`EitherOrBoth`] provides additional methods:
78//!
79//! * [`expect_both`] panics with a provided custom message if the variant is `Right` or `Left`
80//! * [`unwrap_both`] panics with a generic message if the variant is `Right` or `Left`
81//! * [`unwrap_both_unchecked`] produces *[undefined behavior]* if the variant is `Right` or
82//! `Left`
83//! * [`expect_only_left`] panics with a provided custom message if the variant is `Right` or
84//! `Both`
85//! * [`unwrap_only_left`] panics with a generic message if the variant is `Right` or `Both`
86//! * [`unwrap_only_left_unchecked`] produces *[undefined behavior]* if the variant is `Right`
87//! or `Both`
88//! * [`expect_only_right`] panics with a provided custom message if the variant is `Left` or
89//! `Both`
90//! * [`unwrap_only_right`] panics with a generic message if the variant is `Left` or `Both`
91//! * [`unwrap_only_right_unchecked`] produces *[undefined behavior]* if the variant is `Left`
92//! or `Both`
93//!
94//! Non-panicking methods, optionally extract the contained values:
95//!
96//! * [`left`] returns `Some` with the left value if present otherwise `None`
97//! * [`right`] returns `Some` with the right value if present otherwise `None`
98//!
99//! The methods [`both`], [`only_left`], [`only_right`] are exclusive to [`EitherOrBoth`]
100//! and return `Some` with both values if `Both`, and respectively `Some` with the left
101//! value if only `Left` and `Some` with the right value if only `Right`. Finally,
102//! [`unzip`] produces a 2-tuple of [`Options`][Option] containing both values if present.
103//!
104//! The [`left_and`], [`right_and`] methods take another [`EitherOrBoth`] or [`Either`] as
105//! input and produce an [`EitherOrBoth`] or [`Either`] as output.
106//!
107//! Accordingly, [`left_and_then`], [`right_and_then`] methods evaluate lazily by taking a
108//! function as input.
109//!
110//! The following non-panicking methods extract the contained value of an
111//! [`EitherOrBoth<L, R>`] and [`Either<L, R>`] by providing default values or methods if
112//! one of the values is missing:
113//!
114//! * [`or`] produces a tuple `(L, R)` with the given values supplying a possibly missing left
115//! or right value
116//! * [`or_default`] returns a tuple with `L::default` or `R::default` if one of them is
117//! missing.
118//! * [`or_else`] returns a tuple computing the missing left or right values with a given
119//! function.
120//!
121//! Reducing methods extract the contained value into a single value, potentially
122//! converting it to a different type `T`, rather than returning a tuple:
123//!
124//! * [`reduce_left`] extracts the `L` value, otherwise applies a given function converting the
125//! `R` value to a `L` value
126//! * [`reduce_right`] extracts the `R` value, otherwise applies a given function converting
127//! the `L` value to a `R` value
128//!
129//! Other reductions work differently for [`EitherOrBoth`] and [`Either`]. With [`Either`]
130//!
131//! * [`bireduce`] applies the given functions converting the `L` and `R` to a type `T`. The
132//! uniform type version of [`bireduce`] is named [`reduce`].
133//!
134//! [`EitherOrBoth<L, R>`] doesn't have a single `bireduce` method, but instead two
135//! methods:
136//!
137//! * [`reduce_map_left`] which applies the given function to the `L` value if the variant is
138//! `Left` or `Both` and another function to the `R` value if the variant is `Right`.
139//! * [`reduce_map_right`] which applies a given function to the `R` value if the variant is
140//! `Right` or `Both` and another function to the `L` value if the variant is `Left`.
141//!
142//! There is a uniform type version [`EitherOrBoth::reduce`], which extracts `Left` or
143//! `Right`, otherwise it applies a function reducing `Both` to a single value.
144//!
145//! ## Conversions
146//!
147//! The most basic conversion [`EitherOrBoth<L, R>`] to [`EitherOrBoth<R, L>`] can be
148//! achieved with [`flip`][EitherOrBoth::flip]. Similar [`Either<L, R>`] to [`Either<R,
149//! L>`] with [`flip`][Either::flip].
150//!
151//! These methods convert to the other variant without changing the signature:
152//!
153//! * [`into_left`] converts a `Right` or `Both` variant into a `Left` variant by applying a
154//! provided conversion function to the `Right` value if necessary
155//! * [`into_right`] converts a `Left` or `Both` variant into a `Right` variant by applying a
156//! provided conversion function to the `Left` value if necessary
157//!
158//! ## Transforming contained values
159//!
160//! The methods below convert to a [`Result`] as described in the [convention]:
161//!
162//! * [`ok`]: This method transforms [`Left(v)`] to [`Err(v)`], [`Right(v)`] to [`Ok(v)`] and
163//! in the case of [`EitherOrBoth`], [`Both(l, r)`] to [`Err(l)`]
164//! * [`ok_or`] transforms [`Right(v)`] to [`Ok(v)`] and a left value to [`Err`] with the
165//! provided `err` value.
166//! * [`ok_or_else`] transforms [`Right(v)`] to [`Ok(v)`] and a left value to [`Err`] using the
167//! provided function.
168//!
169//! These methods transform the inner values to other types using provided functions:
170//!
171//! * [`bimap`] transforms [`EitherOrBoth<L, R>`] to [`EitherOrBoth<T, U>`]
172//! * [`map_left`] transforms [`EitherOrBoth<L, R>`] to [`EitherOrBoth<T, R>`]
173//! * [`map_right`] transforms [`EitherOrBoth<L, R>`] to [`EitherOrBoth<L, U>`]
174//! * [`map`] transforms [`EitherOrBoth<T, T>`] to [`EitherOrBoth<U, U>`]
175//!
176//! These methods transform [`EitherOrBoth<L, R>`] to a value of a possibly different type
177//! `T`:
178//!
179//! * [`map_left_or`] applies the provided function to the left value or returns the provided
180//! default value if there is only a right value.
181//! * [`map_left_or_else`] applies the provided function to the left value or returns the
182//! result of evaluating the provided fallback function if there is only a right value.
183//! * [`map_left_or_default`] applies the provided function to the left value or returns the
184//! default of the target value if there is only a right value.
185//!
186//! The [`map_right_or`], [`map_right_or_else`] and [`map_right_or_default`] methods are
187//! the equivalent methods applying a provided function to the right value.
188//!
189//! Swapping an [`EitherOrBoth`] or [`Either`] of an inner value to the inner value of an
190//! [`EitherOrBoth`] or [`Either`] is possible with [`transpose`] if the inner values are
191//! a [`Result`], [`Option`] or tuple respectively. The `Both` variant can be tricky
192//! because it can contain an error (or `None`) and correct value (or `Some`)
193//! simultaneously. As per [convention] mentioned above, the error (or `None`) value takes
194//! precedence.
195//!
196//! | From | To |
197//! | --- | --- |
198//! | [`EitherOrBoth<Result<L1, E1>, Result<L2, E2>>`] | [`Result<EitherOrBoth<L1, L2> EitherOrBoth<E1, E2>>`] |
199//! | [`EitherOrBoth<Option<L>, Option<R>>`] | [`Option<EitherOrBoth<L, R>>`] |
200//! | [`EitherOrBoth<(L1, R1), (L2, R2)>`][EitherOrBoth] | [`(EitherOrBoth<L1, L2>, EitherOrBoth<R1, R2>)`][EitherOrBoth] |
201//!
202//! The uniform type cases can be handled separately with [`transpose_ok`] and
203//! [`transpose_err`] for [`Result`] and [`transpose_left`] and [`transpose_right`] for
204//! tuples.
205//!
206//! ## Consumers
207//!
208//! These methods apply a method to the contained values and the mutable environment
209//! consuming the [`EitherOrBoth`]. The evaluation order is from left to right if `Both`
210//! values are present. Evaluation from right to left is possible by first
211//! [`flipping`][`EitherOrBoth::flip`] the values.
212//!
213//! * [`biapply`] applies the provided functions to the contained values taking mutable
214//! references to capture variables.
215//! * [`biapply_with`] works similar but also takes a mutable accumulator which is available in
216//! both functions.
217//! * [`apply_left`] applies the provided function to the contained left value
218//! * [`apply_right`] applies the provided function to the contained right value
219//! * [`apply`] is the uniform type method equivalent to [`biapply`]
220//!
221//! These methods are lighter versions, consuming the [`EitherOrBoth`] or [`Either`] then
222//! apply functions to the contained values by reference and eventually returning the
223//! [`EitherOrBoth`] or [`Either`] again.
224//!
225//! * [`biinspect`] applies the provided functions to the contained values starting with the
226//! left and continuing with the right value.
227//! * [`inspect_left`] applies the provided function to the contained left value
228//! * [`inspect_right`] applies the provided function to the contained right value
229//! * [`inspect`] is the uniform type method equivalent to [`biinspect`]
230//!
231//! ## Iterating
232//!
233//! Iterating over [`Either`] and [`EitherOrBoth`] is slightly different
234//!
235//! ### Iterating over [`EitherOrBoth`]
236//!
237//! [`EitherOrBoth`] can be iterated over directly if the types are uniform
238//! [`EitherOrBoth<T>`]. The iterator produces a single value if `Left` or `Right` and two
239//! values if `Both` by iterating from left to right. The uniform iterators over the type
240//! `T` come in in three types:
241//!
242//! * [`into_iter`][EitherOrBoth::into_iter] consumes the [`EitherOrBoth`]
243//! * [`iter`][EitherOrBoth::iter] produces immutable references of type `&T` to the contained
244//! values
245//! * [`iter_mut`][EitherOrBoth::iter_mut] produces mutable references of type `&mut T` to the
246//! contained values
247//!
248//! If the uniform inner types implement [`IntoIterator`] the [`EitherOrBoth`] can be
249//! iterated over by chaining both iterators from left to right:
250//!
251//! * [`into_iter_chain`] consumes the [`EitherOrBoth`]
252//! * [`iter_chain`] produces immutable references of type `&T` of the chained iterators
253//! * [`iter_chain_mut`] produces mutable references of type `&mut T` of the chained iterators
254//!
255//! If the types are not uniform iterating over [`EitherOrBoth`] can be achieved if the
256//! inner types implement [`IntoIterator`]. Instead of [`EitherOrBoth<Iterator<Item = L>,
257//! Iterator<Item = R>>`][EitherOrBoth] the iterators are swapped [`Iterator<Item =
258//! EitherOrBoth<L, R>>`][Iterator]:
259//!
260//! * [`into_iter_swap`] consumes the [`EitherOrBoth`]
261//! * [`iter_swap`] produces immutable references of [`EitherOrBoth<&L, &R>`]
262//! * [`iter_swap_mut`] produces mutable references of [`EitherOrBoth<&mut L, &mut R>`]
263//!
264//! ### Iterating over [`Either`]
265//!
266//! Like [`EitherOrBoth`], an [`Either`] can be iterated over directly if the types are
267//! uniform [`Either<T>`]. The iterator produces a single value. The uniform iterators
268//! over the type `T` come in in three types:
269//!
270//! * [`into_iter`][Either::into_iter] consumes the [`Either`]
271//! * [`iter`][Either::iter] produces an immutable reference of type `&T` to the contained
272//! value
273//! * [`iter_mut`][Either::iter_mut] produces an mutable reference of type `&mut T` to the
274//! contained value
275//!
276//! If the uniform inner types implement [`IntoIterator`], the [`Either`] can be iterator
277//! over with:
278//!
279//! * [`into_iter_inner`][Either::into_iter_inner] consumes the [`Either`]
280//! * [`iter_inner`][Either::iter_inner] produces immutable references of type `&T` to the
281//! inner iterator values
282//! * [`iter_inner_mut`][Either::iter_inner_mut] produces mutable references of type `&mut T`
283//! to the inner iterator values
284//!
285//! If the [`Either`] types are non-uniform, the swap iterator for [`Either`] work exactly
286//! the same as the [`EitherOrBoth`] swap iterators:
287//!
288//! * [`into_iter_swap`][Either::into_iter_swap] consumes the [`Either`]
289//! * [`iter_swap`][Either::iter_swap] produces immutable references of [`Either<&L, &R>`]
290//! * [`iter_swap_mut`][Either::iter_swap_mut] produces mutable references of [`Either<&mut L,
291//! &mut R>`]
292//!
293//! ## Collecting into [`EitherOrBoth`]
294//!
295//! [`EitherOrBoth`] implements the [`FromIterator`] trait which allows an iterator over
296//! [`Either`] or [`EitherOrBoth`] to be collected into an [`EitherOrBoth`] of two
297//! collections, the left collection containing the left values and the right collection
298//! containing the right values.
299#![cfg_attr(all(feature = "std", feature = "either"), doc = "```rust")]
300#![cfg_attr(not(all(feature = "std", feature = "either")), doc = "```rust,ignore")]
301//! use either_or_both::{Either, EitherOrBoth};
302//!
303//! let vector: Vec<Either<i32>> = vec![Either::Left(2), Either::Left(1)];
304//! let either_or_both: EitherOrBoth<Vec<i32>> = vector.into_iter().collect();
305//!
306//! assert_eq!(either_or_both, EitherOrBoth::Left(vec![2, 1]));
307//!
308//! let vector: Vec<Either<i32>> = vec![Either::Left(2), Either::Right(1)];
309//! let either_or_both: EitherOrBoth<Vec<i32>> = vector.into_iter().collect();
310//!
311//! assert_eq!(either_or_both, EitherOrBoth::Both(vec![2], vec![1]));
312//! ```
313//!
314//! ## Trait implementations
315//!
316//! Both [`Either`] and [`EitherOrBoth`] derive [`Debug`], [`PartialEq`], [`Eq`],
317//! [`Clone`], [`Copy`], and [`Hash`].
318//!
319//! ### Comparison
320//!
321//! Both types implement [`Ord`] and [`PartialOrd`] with custom orderings that differ
322//! from a derived implementation:
323//!
324//! * [`Either`] orders [`Left`][Either::Left] before [`Right`][Either::Right]. When
325//! both values are the same variant, their inner values are compared directly.
326//! * [`EitherOrBoth`] orders [`Left`][EitherOrBoth::Left] before
327//! [`Both`][EitherOrBoth::Both] before [`Right`][EitherOrBoth::Right]. When both
328//! values are the same variant, their inner values are compared directly. For the
329//! [`Both`][EitherOrBoth::Both] variant, the left values are compared first, and only
330//! if equal are the right values compared.
331//!
332//! ### Display and Error
333//!
334//! Both types implement [`Display`] by delegating to the inner value's [`Display`]
335//! implementation. For [`EitherOrBoth`], the [`Both`][EitherOrBoth::Both] variant
336//! formats both values separated by a newline.
337//!
338//! Both types implement [`Error`] when both inner types implement [`Error`]. For the
339//! [`Both`][EitherOrBoth::Both] variant of [`EitherOrBoth`], the left error's source
340//! takes precedence (see [convention]).
341//!
342//! ### Delegation traits
343//!
344//! [`Either`] implements several traits by delegating to whichever inner value is
345//! present, allowing [`Either`] to be used transparently where the inner type's trait
346//! is expected:
347//!
348//! * [`AsRef<T>`] and [`AsMut<T>`] delegate to the inner value's [`AsRef`] or [`AsMut`]
349//! implementation
350//! * [`Deref`] and [`DerefMut`] delegate to the inner value, with
351//! [`Deref::Target`] set to `R::Target`
352//! * [`Extend<A>`] delegates to the inner collection's [`Extend`] implementation
353//! * [`Write`][FmtWrite] delegates to the inner value's [`Write`][FmtWrite] implementation
354//!
355//! [`Either`] also implements [`Future`] when both inner types are futures with the
356//! same output type, polling whichever side is present.
357//!
358//! ### I/O traits
359//!
360//! [`Either`] implements [`Read`], [`Write`][IoWrite], [`BufRead`], and [`Seek`] by delegating to
361//! the inner value's implementation.
362//!
363//! ### Conversions from tuples and Result
364//!
365//! [`Either`] implements [`From<Result<R, L>>`][Either-From], converting [`Ok`] to
366//! [`Right`][Either::Right] and [`Err`] to [`Left`][Either::Left].
367//!
368//! [`EitherOrBoth`] implements several [`From`] conversions from tuples:
369//!
370//! * [`From<(L, R)>`][EitherOrBoth-From-tuple] always produces a [`Both`][EitherOrBoth::Both] variant
371//! * [`From<(Option<L>, R)>`][EitherOrBoth-From-tuple-opt-left] produces [`Both`][EitherOrBoth::Both] if
372//! the left is [`Some`], otherwise [`Right`][EitherOrBoth::Right]
373//! * [`From<(L, Option<R>)>`][EitherOrBoth-From-tuple-opt-right] produces [`Both`][EitherOrBoth::Both] if
374//! the right is [`Some`], otherwise [`Left`][EitherOrBoth::Left]
375//!
376//! Additionally, [`TryFrom<(Option<L>, Option<R>)>`][EitherOrBoth-TryFrom] is implemented for
377//! [`EitherOrBoth`], returning [`TryFromOptionsError`] if both options are [`None`].
378//!
379//! [`EitherOrBoth`] also implements [`From<Either<L, R>>`][EitherOrBoth-From-Either].
380//!
381//! ## Modifying in-place
382//!
383//! Both enums support replacing the left or right values:
384//!
385//! * [`replace_left`] as the name suggests replaces the left value returning the old value if
386//! successful
387//! * [`replace_right`] replaces the right value returning the old value if successful
388//!
389//! [`replace_any`] is special to [`EitherOrBoth`] and replaces all values returning the old
390//! [`EitherOrBoth`].
391//!
392//! Insertion is supported for [`EitherOrBoth`] and these methods return a mutable reference to the
393//! contained value:
394//!
395//! * [`insert_left`]: inserts a new left value and if `Right` changes to a `Both` value
396//! * [`insert_right`]: inserts a new right value and if `Left` changes to a `Both` value
397//! * [`left_or_insert`]: returns a mutable reference to the left value or if `Right`, inserts a
398//! left value converting `self` to a `Both` value
399//! * [`left_or_insert_with`]: returns a mutable reference to the left value or if `Right`, inserts
400//! a lazily computed left value converting `self` to a `Both` value
401//! * [`right_or_insert`]: returns a mutable reference to the right value or if `Left`, inserts a
402//! right value converting `self` to a `Both` value
403//! * [`right_or_insert_with`]: returns a mutable reference to the right value or if `Left`, inserts
404//! a lazily computed right value converting `self` to a `Both` value
405//!
406//! [Either-From-ref-mut]: Either#impl-From<&'a+mut+Either<L,+R>>-for-Either<&'a+mut+L,+&'a+mut+R>
407//! [Either-From-ref]: Either#impl-From<&'a+Either<L,+R>>-for-Either<&'a+L,+&'a+R>
408//! [Either-From]: Either#impl-From<Result<R,+L>>-for-Either<L,+R>
409//! [EitherOrBoth-From-Either]: EitherOrBoth#impl-From<Either<L,+R>>-for-EitherOrBoth<L,+R>
410//! [EitherOrBoth-From-tuple-opt-left]: EitherOrBoth#impl-From<(Option<L>,+R)>-for-EitherOrBoth<L,+R>
411//! [EitherOrBoth-From-tuple-opt-right]: EitherOrBoth#impl-From<(L,+Option<R>)>-for-EitherOrBoth<L,+R>
412//! [EitherOrBoth-From-tuple]: EitherOrBoth#impl-From<(L,+R)>-for-EitherOrBoth<L,+R>
413//! [EitherOrBoth-TryFrom]: EitherOrBoth#impl-TryFrom<(Option<L>,+Option<R>)>-for-EitherOrBoth<L,+R>
414//! [`AsMut<T>`]: core::convert::AsMut
415//! [`AsMut`]: core::convert::AsMut
416//! [`AsRef<T>`]: core::convert::AsRef
417//! [`AsRef`]: core::convert::AsRef
418//! [`Both(l, r)`]: EitherOrBoth::Both
419//! [`BufRead`]: std::io::BufRead
420//! [`Clone`]: core::clone::Clone
421//! [`Copy`]: core::marker::Copy
422//! [`Debug`]: core::fmt::Debug
423//! [`Deref::Target`]: core::ops::Deref::Target
424//! [`DerefMut`]: core::ops::DerefMut
425//! [`Deref`]: core::ops::Deref
426//! [`Display`]: core::fmt::Display
427//! [`Eq`]: core::cmp::Eq
428//! [`Err(l)`]: Result::Err
429//! [`Err(r)`]: Result::Err
430//! [`Err(v)`]: Result::Err
431//! [`Err`]: Result::Err
432//! [`Error`]: std::error::Error
433//! [`Extend<A>`]: core::iter::Extend
434//! [`Extend`]: core::iter::Extend
435//! [`Future`]: core::future::Future
436//! [`Hash`]: core::hash::Hash
437//! [`Left(v)`]: Either::Left
438//! [`Left`]: Either::Left
439//! [`None`]: Option::None
440//! [`Ok(v)`]: Result::Ok
441//! [`Ok`]: Result::Ok
442//! [`Ord`]: core::cmp::Ord
443//! [`PartialEq`]: core::cmp::PartialEq
444//! [`PartialOrd`]: core::cmp::PartialOrd
445//! [`Read`]: std::io::Read
446//! [`Right(v)`]: Either::Right
447//! [`Seek`]: std::io::Seek
448//! [`Some`]: Option::Some
449//! [`TryFromOptionsError`]: crate::TryFromOptionsError
450//! [FmtWrite]: core::fmt::Write
451//! [IoWrite]: std::io::Write
452//! [`apply_left`]: EitherOrBoth::apply_left
453//! [`apply_right`]: EitherOrBoth::apply_right
454//! [`apply`]: EitherOrBoth::apply
455//! [`as_deref_mut`]: EitherOrBoth::as_deref_mut
456//! [`as_deref`]: EitherOrBoth::as_deref
457//! [`as_mut`]: EitherOrBoth::as_mut
458//! [`as_pin_mut`]: EitherOrBoth::as_pin_mut
459//! [`as_pin_ref`]: EitherOrBoth::as_pin_ref
460//! [`as_ref`]: EitherOrBoth::as_ref
461//! [`biapply_with`]: EitherOrBoth::biapply_with
462//! [`biapply`]: EitherOrBoth::biapply
463//! [`biinspect`]: EitherOrBoth::biinspect
464//! [`bimap`]: EitherOrBoth::bimap
465//! [`bireduce`]: Either::bireduce
466//! [`both`]: EitherOrBoth::both
467//! [`expect_both`]: EitherOrBoth::expect_both
468//! [`expect_left`]: EitherOrBoth::expect_left
469//! [`expect_only_left`]: EitherOrBoth::expect_left
470//! [`expect_only_right`]: EitherOrBoth::expect_right
471//! [`expect_right`]: EitherOrBoth::expect_right
472//! [`insert_left`]: EitherOrBoth::insert_left
473//! [`insert_right`]: EitherOrBoth::insert_right
474//! [`inspect_left`]: EitherOrBoth::inspect_left
475//! [`inspect_right`]: EitherOrBoth::inspect_right
476//! [`inspect`]: EitherOrBoth::inspect
477//! [`into_iter_chain`]: EitherOrBoth::into_iter_chain
478//! [`into_iter_swap`]: EitherOrBoth::into_iter_swap
479//! [`into_left`]: EitherOrBoth::into_left
480//! [`into_right`]: EitherOrBoth::into_right
481//! [`iter_chain_mut`]: EitherOrBoth::iter_chain_mut
482//! [`iter_chain`]: EitherOrBoth::iter_chain
483//! [`iter_swap_mut`]: EitherOrBoth::iter_swap_mut
484//! [`iter_swap`]: EitherOrBoth::iter_swap
485//! [`left_and_then`]: EitherOrBoth::left_and_then
486//! [`left_and`]: EitherOrBoth::left_and
487//! [`left_or_insert_with`]: EitherOrBoth::left_or_insert_with
488//! [`left_or_insert`]: EitherOrBoth::left_or_insert
489//! [`left`]: EitherOrBoth::left
490//! [`map_left_or_default`]: EitherOrBoth::map_left_or_default
491//! [`map_left_or_else`]: EitherOrBoth::map_left_or_else
492//! [`map_left_or`]: EitherOrBoth::map_left_or
493//! [`map_left`]: EitherOrBoth::map_left
494//! [`map_right_or_default`]: EitherOrBoth::map_right_or_default
495//! [`map_right_or_else`]: EitherOrBoth::map_right_or_else
496//! [`map_right_or`]: EitherOrBoth::map_right_or
497//! [`map_right`]: EitherOrBoth::map_right
498//! [`map`]: EitherOrBoth::map
499//! [`ok_or_else`]: Either::ok_or
500//! [`ok_or`]: Either::ok_or
501//! [`ok`]: Either::ok
502//! [`only_left`]: EitherOrBoth::only_left
503//! [`only_right`]: EitherOrBoth::only_right
504//! [`or_default`]: EitherOrBoth::or_default
505//! [`or_else`]: EitherOrBoth::or_else
506//! [`or`]: EitherOrBoth::or
507//! [`reduce_left`]: EitherOrBoth::reduce_left
508//! [`reduce_map_left`]: EitherOrBoth::reduce_map_left
509//! [`reduce_map_right`]: EitherOrBoth::reduce_map_right
510//! [`reduce_right`]: EitherOrBoth::reduce_right
511//! [`reduce`]: Either::reduce
512//! [`replace_any`]: EitherOrBoth::replace_any
513//! [`replace_left`]: EitherOrBoth::replace_left
514//! [`replace_right`]: EitherOrBoth::replace_right
515//! [`right_and_then`]: EitherOrBoth::right_and_then
516//! [`right_and`]: EitherOrBoth::right_and
517//! [`right_or_insert_with`]: EitherOrBoth::right_or_insert_with
518//! [`right_or_insert`]: EitherOrBoth::right_or_insert
519//! [`right`]: EitherOrBoth::right
520//! [`transpose_err`]: EitherOrBoth::transpose_err
521//! [`transpose_left`]: EitherOrBoth::transpose_left
522//! [`transpose_ok`]: EitherOrBoth::transpose_ok
523//! [`transpose_right`]: EitherOrBoth::transpose_right
524//! [`transpose`]: EitherOrBoth::transpose
525//! [`unwrap_both_unchecked`]: EitherOrBoth::unwrap_both_unchecked
526//! [`unwrap_both`]: EitherOrBoth::unwrap_both
527//! [`unwrap_left_unchecked`]: EitherOrBoth::unwrap_left_unchecked
528//! [`unwrap_left`]: EitherOrBoth::unwrap_left
529//! [`unwrap_only_left_unchecked`]: EitherOrBoth::unwrap_left_unchecked
530//! [`unwrap_only_left`]: EitherOrBoth::unwrap_left
531//! [`unwrap_only_right_unchecked`]: EitherOrBoth::unwrap_right_unchecked
532//! [`unwrap_only_right`]: EitherOrBoth::unwrap_right
533//! [`unwrap_right_unchecked`]: EitherOrBoth::unwrap_right_unchecked
534//! [`unwrap_right`]: EitherOrBoth::unwrap_right
535//! [`unzip`]: EitherOrBoth::unzip
536//! [convention]: #conventions-and-edge-cases
537//! [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
538
539#![cfg_attr(not(feature = "std"), no_std)]
540#![cfg_attr(docsrs, feature(doc_cfg))]
541
542#[cfg(feature = "std")]
543extern crate std;
544
545#[cfg(feature = "either")]
546mod either;
547mod either_or_both;
548mod error;
549
550#[cfg(feature = "either")]
551pub use either::{iter as iter_either, Either};
552pub use error::TryFromOptionsError;
553
554pub use crate::either_or_both::{iter, EitherOrBoth};