1
+ use core:: ops:: { Deref , DerefMut } ;
2
+
1
3
use crate :: EitherOrBoth :: * ;
2
4
3
5
use either:: Either ;
@@ -14,7 +16,7 @@ pub enum EitherOrBoth<A, B> {
14
16
}
15
17
16
18
impl < A , B > EitherOrBoth < A , B > {
17
- /// If `Left`, or `Both`, return true, otherwise , return false.
19
+ /// If `Left`, or `Both`, return true. Otherwise , return false.
18
20
pub fn has_left ( & self ) -> bool {
19
21
self . as_ref ( ) . left ( ) . is_some ( )
20
22
}
@@ -24,7 +26,7 @@ impl<A, B> EitherOrBoth<A, B> {
24
26
self . as_ref ( ) . right ( ) . is_some ( )
25
27
}
26
28
27
- /// If Left, return true otherwise , return false.
29
+ /// If ` Left` , return true. Otherwise , return false.
28
30
/// Exclusive version of [`has_left`](EitherOrBoth::has_left).
29
31
pub fn is_left ( & self ) -> bool {
30
32
match * self {
@@ -33,7 +35,7 @@ impl<A, B> EitherOrBoth<A, B> {
33
35
}
34
36
}
35
37
36
- /// If Right, return true otherwise , return false.
38
+ /// If ` Right` , return true. Otherwise , return false.
37
39
/// Exclusive version of [`has_right`](EitherOrBoth::has_right).
38
40
pub fn is_right ( & self ) -> bool {
39
41
match * self {
@@ -42,36 +44,107 @@ impl<A, B> EitherOrBoth<A, B> {
42
44
}
43
45
}
44
46
45
- /// If Right, return true otherwise, return false.
46
- /// Equivalent to `self.as_ref().both().is_some()`.
47
+ /// If `Both`, return true. Otherwise, return false.
47
48
pub fn is_both ( & self ) -> bool {
48
49
self . as_ref ( ) . both ( ) . is_some ( )
49
50
}
50
51
51
- /// If `Left`, or `Both`, return `Some` with the left value, otherwise , return `None`.
52
+ /// If `Left`, or `Both`, return `Some` with the left value. Otherwise , return `None`.
52
53
pub fn left ( self ) -> Option < A > {
53
54
match self {
54
55
Left ( left) | Both ( left, _) => Some ( left) ,
55
56
_ => None ,
56
57
}
57
58
}
58
59
59
- /// If `Right`, or `Both`, return `Some` with the right value, otherwise , return `None`.
60
+ /// If `Right`, or `Both`, return `Some` with the right value. Otherwise , return `None`.
60
61
pub fn right ( self ) -> Option < B > {
61
62
match self {
62
63
Right ( right) | Both ( _, right) => Some ( right) ,
63
64
_ => None ,
64
65
}
65
66
}
66
67
67
- /// If Both, return `Some` tuple containing left and right.
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`.
68
119
pub fn both ( self ) -> Option < ( A , B ) > {
69
120
match self {
70
121
Both ( a, b) => Some ( ( a, b) ) ,
71
122
_ => None ,
72
123
}
73
124
}
74
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
+
75
148
/// Converts from `&EitherOrBoth<A, B>` to `EitherOrBoth<&A, &B>`.
76
149
pub fn as_ref ( & self ) -> EitherOrBoth < & A , & B > {
77
150
match * self {
@@ -90,6 +163,32 @@ impl<A, B> EitherOrBoth<A, B> {
90
163
}
91
164
}
92
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
+
93
192
/// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
94
193
pub fn flip ( self ) -> EitherOrBoth < B , A > {
95
194
match self {
@@ -227,6 +326,139 @@ impl<A, B> EitherOrBoth<A, B> {
227
326
Both ( inner_l, inner_r) => ( inner_l, inner_r) ,
228
327
}
229
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
+ }
230
462
}
231
463
232
464
impl < T > EitherOrBoth < T , T > {
0 commit comments