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 = 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 | |
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() |
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 | |
466 | impl<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 | |
497 | impl<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 | |
507 | impl<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 | |