itertools/
either_or_both.rs

1use core::ops::{Deref, DerefMut};
2
3use crate::EitherOrBoth::*;
4
5use either::Either;
6
7/// Value that either holds a single A or B, or both.
8#[derive(Clone, PartialEq, Eq, Hash, Debug)]
9pub enum EitherOrBoth<A, B> {
10    /// Both values are present.
11    Both(A, B),
12    /// Only the left value of type `A` is present.
13    Left(A),
14    /// Only the right value of type `B` is present.
15    Right(B),
16}
17
18impl<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()
22    }
23
24    /// If `Right`, or `Both`, return true, otherwise, return false.
25    pub fn has_right(&self) -> bool {
26        self.as_ref().right().is_some()
27    }
28
29    /// If `Left`, return true. Otherwise, return false.
30    /// Exclusive version of [`has_left`](EitherOrBoth::has_left).
31    pub fn is_left(&self) -> bool {
32        match *self {
33            Left(_) => true,
34            _ => false,
35        }
36    }
37
38    /// If `Right`, return true. Otherwise, return false.
39    /// Exclusive version of [`has_right`](EitherOrBoth::has_right).
40    pub fn is_right(&self) -> bool {
41        match *self {
42            Right(_) => true,
43            _ => false,
44        }
45    }
46
47    /// If `Both`, return true. Otherwise, return false.
48    pub fn is_both(&self) -> bool {
49        self.as_ref().both().is_some()
50    }
51
52    /// If `Left`, or `Both`, return `Some` with the left value. Otherwise, return `None`.
53    pub fn left(self) -> Option<A> {
54        match self {
55            Left(left) | Both(left, _) => Some(left),
56            _ => None,
57        }
58    }
59
60    /// If `Right`, or `Both`, return `Some` with the right value. Otherwise, return `None`.
61    pub fn right(self) -> Option<B> {
62        match self {
63            Right(right) | Both(_, right) => Some(right),
64            _ => None,
65        }
66    }
67
68    /// If `Left`, return `Some` with the left value. If `Right` or `Both`, return `None`.
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// // On the `Left` variant.
74    /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Right, Both}};
75    /// let x: EitherOrBoth<_, ()> = Left("bonjour");
76    /// assert_eq!(x.just_left(), Some("bonjour"));
77    ///
78    /// // On the `Right` variant.
79    /// let x: EitherOrBoth<(), _> = Right("hola");
80    /// assert_eq!(x.just_left(), None);
81    ///
82    /// // On the `Both` variant.
83    /// let x = Both("bonjour", "hola");
84    /// assert_eq!(x.just_left(), None);
85    /// ```
86    pub fn just_left(self) -> Option<A> {
87        match self {
88            Left(left) => Some(left),
89            _ => None,
90        }
91    }
92
93    /// If `Right`, return `Some` with the right value. If `Left` or `Both`, return `None`.
94    ///
95    /// # Examples
96    ///
97    /// ```
98    /// // On the `Left` variant.
99    /// # use itertools::{EitherOrBoth::{Left, Right, Both}, EitherOrBoth};
100    /// let x: EitherOrBoth<_, ()> = Left("auf wiedersehen");
101    /// assert_eq!(x.just_left(), Some("auf wiedersehen"));
102    ///
103    /// // On the `Right` variant.
104    /// let x: EitherOrBoth<(), _> = Right("adios");
105    /// assert_eq!(x.just_left(), None);
106    ///
107    /// // On the `Both` variant.
108    /// let x = Both("auf wiedersehen", "adios");
109    /// assert_eq!(x.just_left(), None);
110    /// ```
111    pub fn just_right(self) -> Option<B> {
112        match self {
113            Right(right) => Some(right),
114            _ => None,
115        }
116    }
117
118    /// If `Both`, return `Some` containing the left and right values. Otherwise, return `None`.
119    pub fn both(self) -> Option<(A, B)> {
120        match self {
121            Both(a, b) => Some((a, b)),
122            _ => None,
123        }
124    }
125
126    /// If `Left` or `Both`, return the left value. Otherwise, convert the right value and return it.
127    pub fn into_left(self) -> A
128    where
129        B: Into<A>,
130    {
131        match self {
132            Left(a) | Both(a, _) => a,
133            Right(b) => b.into(),
134        }
135    }
136
137    /// If `Right` or `Both`, return the right value. Otherwise, convert the left value and return it.
138    pub fn into_right(self) -> B
139    where
140        A: Into<B>,
141    {
142        match self {
143            Right(b) | Both(_, b) => b,
144            Left(a) => a.into(),
145        }
146    }
147
148    /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
149    pub fn as_ref(&self) -> EitherOrBoth<&A, &B> {
150        match *self {
151            Left(ref left) => Left(left),
152            Right(ref right) => Right(right),
153            Both(ref left, ref right) => Both(left, right),
154        }
155    }
156
157    /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut A, &mut B>`.
158    pub fn as_mut(&mut self) -> EitherOrBoth<&mut A, &mut B> {
159        match *self {
160            Left(ref mut left) => Left(left),
161            Right(ref mut right) => Right(right),
162            Both(ref mut left, ref mut right) => Both(left, right),
163        }
164    }
165
166    /// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&_, &_>` using the [`Deref`] trait.
167    pub fn as_deref(&self) -> EitherOrBoth<&A::Target, &B::Target>
168    where
169        A: Deref,
170        B: Deref,
171    {
172        match *self {
173            Left(ref left) => Left(left),
174            Right(ref right) => Right(right),
175            Both(ref left, ref right) => Both(left, right),
176        }
177    }
178
179    /// Converts from `&mut EitherOrBoth<A, B>` to `EitherOrBoth<&mut _, &mut _>` using the [`DerefMut`] trait.
180    pub fn as_deref_mut(&mut self) -> EitherOrBoth<&mut A::Target, &mut B::Target>
181    where
182        A: DerefMut,
183        B: DerefMut,
184    {
185        match *self {
186            Left(ref mut left) => Left(left),
187            Right(ref mut right) => Right(right),
188            Both(ref mut left, ref mut right) => Both(left, right),
189        }
190    }
191
192    /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
193    pub fn flip(self) -> EitherOrBoth<B, A> {
194        match self {
195            Left(a) => Right(a),
196            Right(b) => Left(b),
197            Both(a, b) => Both(b, a),
198        }
199    }
200
201    /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
202    /// present rewrapping the result in `self`'s original variant.
203    pub fn map_left<F, M>(self, f: F) -> EitherOrBoth<M, B>
204    where
205        F: FnOnce(A) -> M,
206    {
207        match self {
208            Both(a, b) => Both(f(a), b),
209            Left(a) => Left(f(a)),
210            Right(b) => Right(b),
211        }
212    }
213
214    /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
215    /// If it is present rewrapping the result in `self`'s original variant.
216    pub fn map_right<F, M>(self, f: F) -> EitherOrBoth<A, M>
217    where
218        F: FnOnce(B) -> M,
219    {
220        match self {
221            Left(a) => Left(a),
222            Right(b) => Right(f(b)),
223            Both(a, b) => Both(a, f(b)),
224        }
225    }
226
227    /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
228    /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
229    /// The Result is rewrapped `self`'s original variant.
230    pub fn map_any<F, L, G, R>(self, f: F, g: G) -> EitherOrBoth<L, R>
231    where
232        F: FnOnce(A) -> L,
233        G: FnOnce(B) -> R,
234    {
235        match self {
236            Left(a) => Left(f(a)),
237            Right(b) => Right(g(b)),
238            Both(a, b) => Both(f(a), g(b)),
239        }
240    }
241
242    /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, _)` variants if it is
243    /// present.
244    pub fn left_and_then<F, L>(self, f: F) -> EitherOrBoth<L, B>
245    where
246        F: FnOnce(A) -> EitherOrBoth<L, B>,
247    {
248        match self {
249            Left(a) | Both(a, _) => f(a),
250            Right(b) => Right(b),
251        }
252    }
253
254    /// Apply the function `f` on the value `b`
255    /// in `Right(b)` or `Both(_, b)` variants if it is present.
256    pub fn right_and_then<F, R>(self, f: F) -> EitherOrBoth<A, R>
257    where
258        F: FnOnce(B) -> EitherOrBoth<A, R>,
259    {
260        match self {
261            Left(a) => Left(a),
262            Right(b) | Both(_, b) => f(b),
263        }
264    }
265
266    /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
267    /// Otherwise, returns the wrapped value for the present element, and the supplied
268    /// value for the other. The first (`l`) argument is used for a missing `Left`
269    /// value. The second (`r`) argument is used for a missing `Right` value.
270    ///
271    /// Arguments passed to `or` are eagerly evaluated; if you are passing
272    /// the result of a function call, it is recommended to use [`or_else`],
273    /// which is lazily evaluated.
274    ///
275    /// [`or_else`]: EitherOrBoth::or_else
276    ///
277    /// # Examples
278    ///
279    /// ```
280    /// # use itertools::EitherOrBoth;
281    /// assert_eq!(EitherOrBoth::Both("tree", 1).or("stone", 5), ("tree", 1));
282    /// assert_eq!(EitherOrBoth::Left("tree").or("stone", 5), ("tree", 5));
283    /// assert_eq!(EitherOrBoth::Right(1).or("stone", 5), ("stone", 1));
284    /// ```
285    pub fn or(self, l: A, r: B) -> (A, B) {
286        match self {
287            Left(inner_l) => (inner_l, r),
288            Right(inner_r) => (l, inner_r),
289            Both(inner_l, inner_r) => (inner_l, inner_r),
290        }
291    }
292
293    /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
294    /// Otherwise, returns the wrapped value for the present element, and the [`default`](Default::default)
295    /// for the other.
296    pub fn or_default(self) -> (A, B)
297    where
298        A: Default,
299        B: Default,
300    {
301        match self {
302            EitherOrBoth::Left(l) => (l, B::default()),
303            EitherOrBoth::Right(r) => (A::default(), r),
304            EitherOrBoth::Both(l, r) => (l, r),
305        }
306    }
307
308    /// Returns a tuple consisting of the `l` and `r` in `Both(l, r)`, if present.
309    /// Otherwise, returns the wrapped value for the present element, and computes the
310    /// missing value with the supplied closure. The first argument (`l`) is used for a
311    /// missing `Left` value. The second argument (`r`) is used for a missing `Right` value.
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// # use itertools::EitherOrBoth;
317    /// let k = 10;
318    /// assert_eq!(EitherOrBoth::Both("tree", 1).or_else(|| "stone", || 2 * k), ("tree", 1));
319    /// assert_eq!(EitherOrBoth::Left("tree").or_else(|| "stone", || 2 * k), ("tree", 20));
320    /// assert_eq!(EitherOrBoth::Right(1).or_else(|| "stone", || 2 * k), ("stone", 1));
321    /// ```
322    pub fn or_else<L: FnOnce() -> A, R: FnOnce() -> B>(self, l: L, r: R) -> (A, B) {
323        match self {
324            Left(inner_l) => (inner_l, r()),
325            Right(inner_r) => (l(), inner_r),
326            Both(inner_l, inner_r) => (inner_l, inner_r),
327        }
328    }
329
330    /// Returns a mutable reference to the left value. If the left value is not present,
331    /// it is replaced with `val`.
332    pub fn left_or_insert(&mut self, val: A) -> &mut A {
333        self.left_or_insert_with(|| val)
334    }
335
336    /// Returns a mutable reference to the right value. If the right value is not present,
337    /// it is replaced with `val`.
338    pub fn right_or_insert(&mut self, val: B) -> &mut B {
339        self.right_or_insert_with(|| val)
340    }
341
342    /// If the left value is not present, replace it the value computed by the closure `f`.
343    /// Returns a mutable reference to the now-present left value.
344    pub fn left_or_insert_with<F>(&mut self, f: F) -> &mut A
345    where
346        F: FnOnce() -> A,
347    {
348        match self {
349            Left(left) | Both(left, _) => left,
350            Right(_) => self.insert_left(f()),
351        }
352    }
353
354    /// If the right value is not present, replace it the value computed by the closure `f`.
355    /// Returns a mutable reference to the now-present right value.
356    pub fn right_or_insert_with<F>(&mut self, f: F) -> &mut B
357    where
358        F: FnOnce() -> B,
359    {
360        match self {
361            Right(right) | Both(_, right) => right,
362            Left(_) => self.insert_right(f()),
363        }
364    }
365
366    /// Sets the `left` value of this instance, and returns a mutable reference to it.
367    /// Does not affect the `right` value.
368    ///
369    /// # Examples
370    /// ```
371    /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Right, Both}};
372    ///
373    /// // Overwriting a pre-existing value.
374    /// let mut either: EitherOrBoth<_, ()> = Left(0_u32);
375    /// assert_eq!(*either.insert_left(69), 69);
376    ///
377    /// // Inserting a second value.
378    /// let mut either = Right("no");
379    /// assert_eq!(*either.insert_left("yes"), "yes");
380    /// assert_eq!(either, Both("yes", "no"));
381    /// ```
382    pub fn insert_left(&mut self, val: A) -> &mut A {
383        match self {
384            Left(left) | Both(left, _) => {
385                *left = val;
386                left
387            }
388            Right(right) => {
389                // This is like a map in place operation. We move out of the reference,
390                // change the value, and then move back into the reference.
391                unsafe {
392                    // SAFETY: We know this pointer is valid for reading since we got it from a reference.
393                    let right = std::ptr::read(right as *mut _);
394                    // SAFETY: Again, we know the pointer is valid since we got it from a reference.
395                    std::ptr::write(self as *mut _, Both(val, right));
396                }
397
398                if let Both(left, _) = self {
399                    left
400                } else {
401                    // SAFETY: The above pattern will always match, since we just
402                    // set `self` equal to `Both`.
403                    unsafe { std::hint::unreachable_unchecked() }
404                }
405            }
406        }
407    }
408
409    /// Sets the `right` value of this instance, and returns a mutable reference to it.
410    /// Does not affect the `left` value.
411    ///
412    /// # Examples
413    /// ```
414    /// # use itertools::{EitherOrBoth, EitherOrBoth::{Left, Both}};
415    /// // Overwriting a pre-existing value.
416    /// let mut either: EitherOrBoth<_, ()> = Left(0_u32);
417    /// assert_eq!(*either.insert_left(69), 69);
418    ///
419    /// // Inserting a second value.
420    /// let mut either = Left("what's");
421    /// assert_eq!(*either.insert_right(9 + 10), 21 - 2);
422    /// assert_eq!(either, Both("what's", 9+10));
423    /// ```
424    pub fn insert_right(&mut self, val: B) -> &mut B {
425        match self {
426            Right(right) | Both(_, right) => {
427                *right = val;
428                right
429            }
430            Left(left) => {
431                // This is like a map in place operation. We move out of the reference,
432                // change the value, and then move back into the reference.
433                unsafe {
434                    // SAFETY: We know this pointer is valid for reading since we got it from a reference.
435                    let left = std::ptr::read(left as *mut _);
436                    // SAFETY: Again, we know the pointer is valid since we got it from a reference.
437                    std::ptr::write(self as *mut _, Both(left, val));
438                }
439                if let Both(_, right) = self {
440                    right
441                } else {
442                    // SAFETY: The above pattern will always match, since we just
443                    // set `self` equal to `Both`.
444                    unsafe { std::hint::unreachable_unchecked() }
445                }
446            }
447        }
448    }
449
450    /// Set `self` to `Both(..)`, containing the specified left and right values,
451    /// and returns a mutable reference to those values.
452    pub fn insert_both(&mut self, left: A, right: B) -> (&mut A, &mut B) {
453        *self = Both(left, right);
454        if let Both(left, right) = self {
455            (left, right)
456        } else {
457            // SAFETY: The above pattern will always match, since we just
458            // set `self` equal to `Both`.
459            unsafe { std::hint::unreachable_unchecked() }
460        }
461    }
462}
463
464impl<T> EitherOrBoth<T, T> {
465    /// Return either value of left, right, or apply a function `f` to both values if both are present.
466    /// The input function has to return the same type as both Right and Left carry.
467    /// 
468    /// # Examples
469    /// ```
470    /// # use itertools::EitherOrBoth;
471    /// assert_eq!(EitherOrBoth::Both(3, 7).reduce(u32::max), 7);
472    /// assert_eq!(EitherOrBoth::Left(3).reduce(u32::max), 3);
473    /// assert_eq!(EitherOrBoth::Right(7).reduce(u32::max), 7);
474    /// ```
475    pub fn reduce<F>(self, f: F) -> T
476    where
477        F: FnOnce(T, T) -> T,
478    {
479        match self {
480            Left(a) => a,
481            Right(b) => b,
482            Both(a, b) => f(a, b),
483        }
484    }
485}
486
487impl<A, B> Into<Option<Either<A, B>>> for EitherOrBoth<A, B> {
488    fn into(self) -> Option<Either<A, B>> {
489        match self {
490            EitherOrBoth::Left(l) => Some(Either::Left(l)),
491            EitherOrBoth::Right(r) => Some(Either::Right(r)),
492            _ => None,
493        }
494    }
495}