1
1
use EitherOrBoth :: * ;
2
2
3
+ use either:: Either ;
4
+
3
5
/// Value that either holds a single A or B, or both.
4
6
#[ derive( Clone , PartialEq , Eq , Debug ) ]
5
7
pub enum EitherOrBoth < A , B > {
@@ -22,19 +24,51 @@ impl<A, B> EitherOrBoth<A, B> {
22
24
self . as_ref ( ) . right ( ) . is_some ( )
23
25
}
24
26
27
+ /// If Left, return true otherwise, return false.
28
+ /// Exclusive version of [`has_left`].
29
+ pub fn is_left ( & self ) -> bool {
30
+ match * self {
31
+ Left ( _) => true ,
32
+ _ => false ,
33
+ }
34
+ }
35
+
36
+ /// If Right, return true otherwise, return false.
37
+ /// Exclusive version of [`has_right`].
38
+ pub fn is_right ( & self ) -> bool {
39
+ match * self {
40
+ Right ( _) => true ,
41
+ _ => false ,
42
+ }
43
+ }
44
+
45
+ /// If Right, return true otherwise, return false.
46
+ /// Equivalent to `self.as_ref().both().is_some()`.
47
+ pub fn is_both ( & self ) -> bool {
48
+ self . as_ref ( ) . both ( ) . is_some ( )
49
+ }
50
+
25
51
/// If `Left`, or `Both`, return `Some` with the left value, otherwise, return `None`.
26
52
pub fn left ( self ) -> Option < A > {
27
53
match self {
28
54
Left ( left) | Both ( left, _) => Some ( left) ,
29
- _ => None
55
+ _ => None ,
30
56
}
31
57
}
32
58
33
59
/// If `Right`, or `Both`, return `Some` with the right value, otherwise, return `None`.
34
60
pub fn right ( self ) -> Option < B > {
35
61
match self {
36
62
Right ( right) | Both ( _, right) => Some ( right) ,
37
- _ => None
63
+ _ => None ,
64
+ }
65
+ }
66
+
67
+ /// If Both, return `Some` tuple containing left and right.
68
+ pub fn both ( self ) -> Option < ( A , B ) > {
69
+ match self {
70
+ Both ( a, b) => Some ( ( a, b) ) ,
71
+ _ => None ,
38
72
}
39
73
}
40
74
@@ -55,4 +89,102 @@ impl<A, B> EitherOrBoth<A, B> {
55
89
Both ( ref mut left, ref mut right) => Both ( left, right) ,
56
90
}
57
91
}
92
+
93
+ /// Convert `EitherOrBoth<A, B>` to `EitherOrBoth<B, A>`.
94
+ pub fn flip ( self ) -> EitherOrBoth < B , A > {
95
+ match self {
96
+ Left ( a) => Right ( a) ,
97
+ Right ( b) => Left ( b) ,
98
+ Both ( a, b) => Both ( b, a) ,
99
+ }
100
+ }
101
+
102
+ /// Apply the function `f` on the value `a` in `Left(a)` or `Both(a, b)` variants. If it is
103
+ /// present rewrapping the result in `self`'s original variant.
104
+ pub fn map_left < F , M > ( self , f : F ) -> EitherOrBoth < M , B >
105
+ where
106
+ F : FnOnce ( A ) -> M ,
107
+ {
108
+ match self {
109
+ Both ( a, b) => Both ( f ( a) , b) ,
110
+ Left ( a) => Left ( f ( a) ) ,
111
+ Right ( b) => Right ( b) ,
112
+ }
113
+ }
114
+
115
+ /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, b)` variants.
116
+ /// If it is present rewrapping the result in `self`'s original variant.
117
+ pub fn map_right < F , M > ( self , f : F ) -> EitherOrBoth < A , M >
118
+ where
119
+ F : FnOnce ( B ) -> M ,
120
+ {
121
+ match self {
122
+ Left ( a) => Left ( a) ,
123
+ Right ( b) => Right ( f ( b) ) ,
124
+ Both ( a, b) => Both ( a, f ( b) ) ,
125
+ }
126
+ }
127
+
128
+ /// Apply the functions `f` and `g` on the value `a` and `b` respectively;
129
+ /// found in `Left(a)`, `Right(b)`, or `Both(a, b)` variants.
130
+ /// The Result is rewrapped `self`'s original variant.
131
+ pub fn map_any < F , L , G , R > ( self , f : F , g : G ) -> EitherOrBoth < L , R >
132
+ where
133
+ F : FnOnce ( A ) -> L ,
134
+ G : FnOnce ( B ) -> R ,
135
+ {
136
+ match self {
137
+ Left ( a) => Left ( f ( a) ) ,
138
+ Right ( b) => Right ( g ( b) ) ,
139
+ Both ( a, b) => Both ( f ( a) , g ( b) ) ,
140
+ }
141
+ }
142
+
143
+ /// Apply the function `f` on the value `b` in `Right(b)` or `Both(a, _)` variants if it is
144
+ /// present.
145
+ pub fn left_and_then < F , L > ( self , f : F ) -> EitherOrBoth < L , B >
146
+ where
147
+ F : FnOnce ( A ) -> EitherOrBoth < L , B > ,
148
+ {
149
+ match self {
150
+ Left ( a) | Both ( a, _) => f ( a) ,
151
+ Right ( b) => Right ( b) ,
152
+ }
153
+ }
154
+
155
+ /// Apply the function `f` on the value `a`
156
+ /// in `Left(a)` or `Both(a, _)` variants if it is present.
157
+ pub fn right_and_then < F , R > ( self , f : F ) -> EitherOrBoth < A , R >
158
+ where
159
+ F : FnOnce ( B ) -> EitherOrBoth < A , R > ,
160
+ {
161
+ match self {
162
+ Left ( a) => Left ( a) ,
163
+ Right ( b) | Both ( _, b) => f ( b) ,
164
+ }
165
+ }
166
+ }
167
+
168
+ impl < T > EitherOrBoth < T , T > {
169
+ /// Return either value of left, right, or the product of `f` applied where `Both` are present.
170
+ pub fn reduce < F > ( self , f : F ) -> T
171
+ where
172
+ F : FnOnce ( T , T ) -> T ,
173
+ {
174
+ match self {
175
+ Left ( a) => a,
176
+ Right ( b) => b,
177
+ Both ( a, b) => f ( a, b) ,
178
+ }
179
+ }
180
+ }
181
+
182
+ impl < A , B > Into < Option < Either < A , B > > > for EitherOrBoth < A , B > {
183
+ fn into ( self ) -> Option < Either < A , B > > {
184
+ match self {
185
+ EitherOrBoth :: Left ( l) => Some ( Either :: Left ( l) ) ,
186
+ EitherOrBoth :: Right ( r) => Some ( Either :: Right ( r) ) ,
187
+ _ => None ,
188
+ }
189
+ }
58
190
}
0 commit comments