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