1 use core
::ops
::{Deref, DerefMut}
;
3 use crate::EitherOrBoth
::*;
7 /// Value that either holds a single A or B, or both.
8 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
9 pub enum EitherOrBoth
<A
, B
= A
> {
10 /// Both values are present.
12 /// Only the left value of type `A` is present.
14 /// Only the right value of type `B` is present.
18 impl<A
, B
> EitherOrBoth
<A
, B
> {
19 /// If `Left`, or `Both`, return true. Otherwise, return false.
20 pub fn has_left(&self) -> bool
{
21 self.as_ref().left().is_some()
24 /// If `Right`, or `Both`, return true, otherwise, return false.
25 pub fn has_right(&self) -> bool
{
26 self.as_ref().right().is_some()
29 /// If `Left`, return true. Otherwise, return false.
30 /// Exclusive version of [`has_left`](EitherOrBoth::has_left).
31 pub fn is_left(&self) -> bool
{
38 /// If `Right`, return true. Otherwise, return false.
39 /// Exclusive version of [`has_right`](EitherOrBoth::has_right).
40 pub fn is_right(&self) -> bool
{
47 /// If `Both`, return true. Otherwise, return false.
48 pub fn is_both(&self) -> bool
{
49 self.as_ref().both().is_some()
52 /// If `Left`, or `Both`, return `Some` with the left value. Otherwise, return `None`.
53 pub fn left(self) -> Option
<A
> {
55 Left(left
) | Both(left
, _
) => Some(left
),
60 /// If `Right`, or `Both`, return `Some` with the right value. Otherwise, return `None`.
61 pub fn right(self) -> Option
<B
> {
63 Right(right
) | Both(_
, right
) => Some(right
),
68 /// Return tuple of options corresponding to the left and right value respectively
70 /// If `Left` return `(Some(..), None)`, if `Right` return `(None,Some(..))`, else return
71 /// `(Some(..),Some(..))`
72 pub fn left_and_right(self) -> (Option
<A
>, Option
<B
>) {
73 self.map_any(Some
, Some
).or_default()
76 /// If `Left`, return `Some` with the left value. If `Right` or `Both`, return `None`.
81 /// // On the `Left` variant.
82 /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Right, Both}};
83 /// let x: EitherOrBoth<_, ()> = Left("bonjour");
84 /// assert_eq!(x.just_left(), Some("bonjour"));
86 /// // On the `Right` variant.
87 /// let x: EitherOrBoth<(), _> = Right("hola");
88 /// assert_eq!(x.just_left(), None);
90 /// // On the `Both` variant.
91 /// let x = Both("bonjour", "hola");
92 /// assert_eq!(x.just_left(), None);
94 pub fn just_left(self) -> Option
<A
> {
96 Left(left
) => Some(left
),
101 /// If `Right`, return `Some` with the right value. If `Left` or `Both`, return `None`.
106 /// // On the `Left` variant.
107 /// # use itertools::{EitherOrBoth::{Left, Right, Both}, EitherOrBoth};
108 /// let x: EitherOrBoth<_, ()> = Left("auf wiedersehen");
109 /// assert_eq!(x.just_left(), Some("auf wiedersehen"));
111 /// // On the `Right` variant.
112 /// let x: EitherOrBoth<(), _> = Right("adios");
113 /// assert_eq!(x.just_left(), None);
115 /// // On the `Both` variant.
116 /// let x = Both("auf wiedersehen", "adios");
117 /// assert_eq!(x.just_left(), None);
119 pub fn just_right(self) -> Option
<B
> {
121 Right(right
) => Some(right
),
126 /// If `Both`, return `Some` containing the left and right values. Otherwise, return `None`.
127 pub fn both(self) -> Option
<(A
, B
)> {
129 Both(a
, b
) => Some((a
, b
)),
134 /// If `Left` or `Both`, return the left value. Otherwise, convert the right value and return it.
135 pub fn into_left(self) -> A
140 Left(a
) | Both(a
, _
) => a
,
141 Right(b
) => b
.into(),
145 /// If `Right` or `Both`, return the right value. Otherwise, convert the left value and return it.
146 pub fn into_right(self) -> B
151 Right(b
) | Both(_
, b
) => b
,
156 /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
157 pub fn as_ref(&self) -> EitherOrBoth
<&A
, &B
> {
159 Left(ref left
) => Left(left
),
160 Right(ref right
) => Right(right
),
161 Both(ref left
, ref right
) => Both(left
, right
),
165 /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut A, &mut B>`.
166 pub fn as_mut(&mut self) -> EitherOrBoth
<&mut A
, &mut B
> {
168 Left(ref mut left
) => Left(left
),
169 Right(ref mut right
) => Right(right
),
170 Both(ref mut left
, ref mut right
) => Both(left
, right
),
174 /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&_, &_>` using the [`Deref`] trait.
175 pub fn as_deref(&self) -> EitherOrBoth
<&A
::Target
, &B
::Target
>
181 Left(ref left
) => Left(left
),
182 Right(ref right
) => Right(right
),
183 Both(ref left
, ref right
) => Both(left
, right
),
187 /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut _, &mut _>` using the [`DerefMut`] trait.
188 pub fn as_deref_mut(&mut self) -> EitherOrBoth
<&mut A
::Target
, &mut B
::Target
>
194 Left(ref mut left
) => Left(left
),
195 Right(ref mut right
) => Right(right
),
196 Both(ref mut left
, ref mut right
) => Both(left
, right
),
200 /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
201 pub fn flip(self) -> EitherOrBoth
<B
, A
> {
205 Both(a
, b
) => Both(b
, a
),
209 /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
210 /// present rewrapping the result in `self`'s original variant.
211 pub fn map_left
<F
, M
>(self, f
: F
) -> EitherOrBoth
<M
, B
>
216 Both(a
, b
) => Both(f(a
), b
),
217 Left(a
) => Left(f(a
)),
218 Right(b
) => Right(b
),
222 /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
223 /// If it is present rewrapping the result in `self`'s original variant.
224 pub fn map_right
<F
, M
>(self, f
: F
) -> EitherOrBoth
<A
, M
>
230 Right(b
) => Right(f(b
)),
231 Both(a
, b
) => Both(a
, f(b
)),
235 /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
236 /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
237 /// The Result is rewrapped `self`'s original variant.
238 pub fn map_any
<F
, L
, G
, R
>(self, f
: F
, g
: G
) -> EitherOrBoth
<L
, R
>
244 Left(a
) => Left(f(a
)),
245 Right(b
) => Right(g(b
)),
246 Both(a
, b
) => Both(f(a
), g(b
)),
250 /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, _)` variants if it is
252 pub fn left_and_then
<F
, L
>(self, f
: F
) -> EitherOrBoth
<L
, B
>
254 F
: FnOnce(A
) -> EitherOrBoth
<L
, B
>,
257 Left(a
) | Both(a
, _
) => f(a
),
258 Right(b
) => Right(b
),
262 /// Apply the function `f` on the value `b`
263 /// in `Right(b)` or `Both(_, b)` variants if it is present.
264 pub fn right_and_then
<F
, R
>(self, f
: F
) -> EitherOrBoth
<A
, R
>
266 F
: FnOnce(B
) -> EitherOrBoth
<A
, R
>,
270 Right(b
) | Both(_
, b
) => f(b
),
274 /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
275 /// Otherwise, returns the wrapped value for the present element, and the supplied
276 /// value for the other. The first (`l`) argument is used for a missing `Left`
277 /// value. The second (`r`) argument is used for a missing `Right` value.
279 /// Arguments passed to `or` are eagerly evaluated; if you are passing
280 /// the result of a function call, it is recommended to use [`or_else`],
281 /// which is lazily evaluated.
283 /// [`or_else`]: EitherOrBoth::or_else
288 /// # use itertools::EitherOrBoth;
289 /// assert_eq!(EitherOrBoth::Both("tree", 1).or("stone", 5), ("tree", 1));
290 /// assert_eq!(EitherOrBoth::Left("tree").or("stone", 5), ("tree", 5));
291 /// assert_eq!(EitherOrBoth::Right(1).or("stone", 5), ("stone", 1));
293 pub fn or(self, l
: A
, r
: B
) -> (A
, B
) {
295 Left(inner_l
) => (inner_l
, r
),
296 Right(inner_r
) => (l
, inner_r
),
297 Both(inner_l
, inner_r
) => (inner_l
, inner_r
),
301 /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
302 /// Otherwise, returns the wrapped value for the present element, and the [`default`](Default::default)
304 pub fn or_default(self) -> (A
, B
)
310 EitherOrBoth
::Left(l
) => (l
, B
::default()),
311 EitherOrBoth
::Right(r
) => (A
::default(), r
),
312 EitherOrBoth
::Both(l
, r
) => (l
, r
),
316 /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
317 /// Otherwise, returns the wrapped value for the present element, and computes the
318 /// missing value with the supplied closure. The first argument (`l`) is used for a
319 /// missing `Left` value. The second argument (`r`) is used for a missing `Right` value.
324 /// # use itertools::EitherOrBoth;
326 /// assert_eq!(EitherOrBoth::Both("tree", 1).or_else(|| "stone", || 2 * k), ("tree", 1));
327 /// assert_eq!(EitherOrBoth::Left("tree").or_else(|| "stone", || 2 * k), ("tree", 20));
328 /// assert_eq!(EitherOrBoth::Right(1).or_else(|| "stone", || 2 * k), ("stone", 1));
330 pub fn or_else
<L
: FnOnce() -> A
, R
: FnOnce() -> B
>(self, l
: L
, r
: R
) -> (A
, B
) {
332 Left(inner_l
) => (inner_l
, r()),
333 Right(inner_r
) => (l(), inner_r
),
334 Both(inner_l
, inner_r
) => (inner_l
, inner_r
),
338 /// Returns a mutable reference to the left value. If the left value is not present,
339 /// it is replaced with `val`.
340 pub fn left_or_insert(&mut self, val
: A
) -> &mut A
{
341 self.left_or_insert_with(|| val
)
344 /// Returns a mutable reference to the right value. If the right value is not present,
345 /// it is replaced with `val`.
346 pub fn right_or_insert(&mut self, val
: B
) -> &mut B
{
347 self.right_or_insert_with(|| val
)
350 /// If the left value is not present, replace it the value computed by the closure `f`.
351 /// Returns a mutable reference to the now-present left value.
352 pub fn left_or_insert_with
<F
>(&mut self, f
: F
) -> &mut A
357 Left(left
) | Both(left
, _
) => left
,
358 Right(_
) => self.insert_left(f()),
362 /// If the right value is not present, replace it the value computed by the closure `f`.
363 /// Returns a mutable reference to the now-present right value.
364 pub fn right_or_insert_with
<F
>(&mut self, f
: F
) -> &mut B
369 Right(right
) | Both(_
, right
) => right
,
370 Left(_
) => self.insert_right(f()),
374 /// Sets the `left` value of this instance, and returns a mutable reference to it.
375 /// Does not affect the `right` value.
379 /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Right, Both}};
381 /// // Overwriting a pre-existing value.
382 /// let mut either: EitherOrBoth<_, ()> = Left(0_u32);
383 /// assert_eq!(*either.insert_left(69), 69);
385 /// // Inserting a second value.
386 /// let mut either = Right("no");
387 /// assert_eq!(*either.insert_left("yes"), "yes");
388 /// assert_eq!(either, Both("yes", "no"));
390 pub fn insert_left(&mut self, val
: A
) -> &mut A
{
392 Left(left
) | Both(left
, _
) => {
397 // This is like a map in place operation. We move out of the reference,
398 // change the value, and then move back into the reference.
400 // SAFETY: We know this pointer is valid for reading since we got it from a reference.
401 let right
= std
::ptr
::read(right
as *mut _
);
402 // SAFETY: Again, we know the pointer is valid since we got it from a reference.
403 std
::ptr
::write(self as *mut _
, Both(val
, right
));
406 if let Both(left
, _
) = self {
409 // SAFETY: The above pattern will always match, since we just
410 // set `self` equal to `Both`.
411 unsafe { std::hint::unreachable_unchecked() }
417 /// Sets the `right` value of this instance, and returns a mutable reference to it.
418 /// Does not affect the `left` value.
422 /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Both}};
423 /// // Overwriting a pre-existing value.
424 /// let mut either: EitherOrBoth<_, ()> = Left(0_u32);
425 /// assert_eq!(*either.insert_left(69), 69);
427 /// // Inserting a second value.
428 /// let mut either = Left("what's");
429 /// assert_eq!(*either.insert_right(9 + 10), 21 - 2);
430 /// assert_eq!(either, Both("what's", 9+10));
432 pub fn insert_right(&mut self, val
: B
) -> &mut B
{
434 Right(right
) | Both(_
, right
) => {
439 // This is like a map in place operation. We move out of the reference,
440 // change the value, and then move back into the reference.
442 // SAFETY: We know this pointer is valid for reading since we got it from a reference.
443 let left
= std
::ptr
::read(left
as *mut _
);
444 // SAFETY: Again, we know the pointer is valid since we got it from a reference.
445 std
::ptr
::write(self as *mut _
, Both(left
, val
));
447 if let Both(_
, right
) = self {
450 // SAFETY: The above pattern will always match, since we just
451 // set `self` equal to `Both`.
452 unsafe { std::hint::unreachable_unchecked() }
458 /// Set `self` to `Both(..)`, containing the specified left and right values,
459 /// and returns a mutable reference to those values.
460 pub fn insert_both(&mut self, left
: A
, right
: B
) -> (&mut A
, &mut B
) {
461 *self = Both(left
, right
);
462 if let Both(left
, right
) = self {
465 // SAFETY: The above pattern will always match, since we just
466 // set `self` equal to `Both`.
467 unsafe { std::hint::unreachable_unchecked() }
472 impl<T
> EitherOrBoth
<T
, T
> {
473 /// Return either value of left, right, or apply a function `f` to both values if both are present.
474 /// The input function has to return the same type as both Right and Left carry.
476 /// This function can be used to preferrably extract the left resp. right value,
477 /// but fall back to the other (i.e. right resp. left) if the preferred one is not present.
481 /// # use itertools::EitherOrBoth;
482 /// assert_eq!(EitherOrBoth::Both(3, 7).reduce(u32::max), 7);
483 /// assert_eq!(EitherOrBoth::Left(3).reduce(u32::max), 3);
484 /// assert_eq!(EitherOrBoth::Right(7).reduce(u32::max), 7);
486 /// // Extract the left value if present, fall back to the right otherwise.
487 /// assert_eq!(EitherOrBoth::Left("left").reduce(|l, _r| l), "left");
488 /// assert_eq!(EitherOrBoth::Right("right").reduce(|l, _r| l), "right");
489 /// assert_eq!(EitherOrBoth::Both("left", "right").reduce(|l, _r| l), "left");
491 pub fn reduce
<F
>(self, f
: F
) -> T
493 F
: FnOnce(T
, T
) -> T
,
498 Both(a
, b
) => f(a
, b
),
503 impl<A
, B
> Into
<Option
<Either
<A
, B
>>> for EitherOrBoth
<A
, B
> {
504 fn into(self) -> Option
<Either
<A
, B
>> {
506 EitherOrBoth
::Left(l
) => Some(Either
::Left(l
)),
507 EitherOrBoth
::Right(r
) => Some(Either
::Right(r
)),
513 impl<A
, B
> From
<Either
<A
, B
>> for EitherOrBoth
<A
, B
> {
514 fn from(either
: Either
<A
, B
>) -> Self {
516 Either
::Left(l
) => EitherOrBoth
::Left(l
),
517 Either
::Right(l
) => EitherOrBoth
::Right(l
),