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. |
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 | |
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 | /// ``` |
475 | pub fn reduce<F>(self, f: F) -> T |
476 | where |
477 | F: FnOnce(T, T) -> T, |
478 | { |
479 | match self { |
480 | Left(a: T) => a, |
481 | Right(b: T) => b, |
482 | Both(a: T, b: T) => f(a, b), |
483 | } |
484 | } |
485 | } |
486 | |
487 | impl<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: A) => Some(Either::Left(l)), |
491 | EitherOrBoth::Right(r: B) => Some(Either::Right(r)), |
492 | _ => None, |
493 | } |
494 | } |
495 | } |
496 | |