1 use core::ops::{Deref, DerefMut};
2 
3 use crate::EitherOrBoth::*;
4 
5 use either::Either;
6 
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> {
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 
18 impl<A, B> EitherOrBoth<A, B> {
19     /// If `Left`, or `Both`, return true. Otherwise, return false.
has_left(&self) -> bool20     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.
has_right(&self) -> bool25     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).
is_left(&self) -> bool31     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).
is_right(&self) -> bool40     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.
is_both(&self) -> bool48     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`.
left(self) -> Option<A>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`.
right(self) -> Option<B>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     /// ```
just_left(self) -> Option<A>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     /// ```
just_right(self) -> Option<B>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`.
both(self) -> Option<(A, B)>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.
into_left(self) -> A where B: Into<A>,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.
into_right(self) -> B where A: Into<B>,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>`.
as_ref(&self) -> 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>`.
as_mut(&mut self) -> 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.
as_deref(&self) -> EitherOrBoth<&A::Target, &B::Target> where A: Deref, B: Deref,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.
as_deref_mut(&mut self) -> EitherOrBoth<&mut A::Target, &mut B::Target> where A: DerefMut, B: DerefMut,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>`.
flip(self) -> 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.
map_left<F, M>(self, f: F) -> EitherOrBoth<M, B> where F: FnOnce(A) -> M,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.
map_right<F, M>(self, f: F) -> EitherOrBoth<A, M> where F: FnOnce(B) -> M,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.
map_any<F, L, G, R>(self, f: F, g: G) -> EitherOrBoth<L, R> where F: FnOnce(A) -> L, G: FnOnce(B) -> R,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.
left_and_then<F, L>(self, f: F) -> EitherOrBoth<L, B> where F: FnOnce(A) -> EitherOrBoth<L, B>,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.
right_and_then<F, R>(self, f: F) -> EitherOrBoth<A, R> where F: FnOnce(B) -> EitherOrBoth<A, R>,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     /// ```
or(self, l: A, r: B) -> (A, B)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.
or_default(self) -> (A, B) where A: Default, B: Default,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     /// ```
or_else<L: FnOnce() -> A, R: FnOnce() -> B>(self, l: L, r: R) -> (A, B)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`.
left_or_insert(&mut self, val: A) -> &mut A332     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`.
right_or_insert(&mut self, val: B) -> &mut B338     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.
left_or_insert_with<F>(&mut self, f: F) -> &mut A where F: FnOnce() -> A,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.
right_or_insert_with<F>(&mut self, f: F) -> &mut B where F: FnOnce() -> B,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     /// ```
insert_left(&mut self, val: A) -> &mut A382     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     /// ```
insert_right(&mut self, val: B) -> &mut B424     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.
insert_both(&mut self, left: A, right: B) -> (&mut A, &mut B)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 
464 impl<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     /// ```
reduce<F>(self, f: F) -> T where F: FnOnce(T, T) -> T,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 
487 impl<A, B> Into<Option<Either<A, B>>> for EitherOrBoth<A, B> {
into(self) -> Option<Either<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 }
496