karpal_recursion/
either.rs1pub enum Either<L, R> {
9 Left(L),
10 Right(R),
11}
12
13impl<L, R> Either<L, R> {
14 pub fn either<T>(self, f: impl FnOnce(L) -> T, g: impl FnOnce(R) -> T) -> T {
16 match self {
17 Either::Left(l) => f(l),
18 Either::Right(r) => g(r),
19 }
20 }
21
22 pub fn map_left<L2>(self, f: impl FnOnce(L) -> L2) -> Either<L2, R> {
24 match self {
25 Either::Left(l) => Either::Left(f(l)),
26 Either::Right(r) => Either::Right(r),
27 }
28 }
29
30 pub fn map_right<R2>(self, f: impl FnOnce(R) -> R2) -> Either<L, R2> {
32 match self {
33 Either::Left(l) => Either::Left(l),
34 Either::Right(r) => Either::Right(f(r)),
35 }
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn either_left() {
45 let e: Either<i32, &str> = Either::Left(42);
46 let result = e.either(|x| x.to_string(), |s| s.to_string());
47 assert_eq!(result, "42");
48 }
49
50 #[test]
51 fn either_right() {
52 let e: Either<i32, &str> = Either::Right("hello");
53 let result = e.either(|x| x.to_string(), |s| s.to_string());
54 assert_eq!(result, "hello");
55 }
56
57 #[test]
58 fn map_left() {
59 let e: Either<i32, &str> = Either::Left(10);
60 let mapped = e.map_left(|x| x * 2);
61 match mapped {
62 Either::Left(v) => assert_eq!(v, 20),
63 Either::Right(_) => panic!("expected Left"),
64 }
65 }
66
67 #[test]
68 fn map_right() {
69 let e: Either<i32, i32> = Either::Right(5);
70 let mapped = e.map_right(|x| x + 1);
71 match mapped {
72 Either::Right(v) => assert_eq!(v, 6),
73 Either::Left(_) => panic!("expected Right"),
74 }
75 }
76
77 #[test]
78 fn map_left_on_right_is_noop() {
79 let e: Either<i32, &str> = Either::Right("hi");
80 let mapped = e.map_left(|x| x * 100);
81 match mapped {
82 Either::Right(s) => assert_eq!(s, "hi"),
83 Either::Left(_) => panic!("expected Right"),
84 }
85 }
86
87 #[test]
88 fn map_right_on_left_is_noop() {
89 let e: Either<i32, i32> = Either::Left(7);
90 let mapped = e.map_right(|x| x * 100);
91 match mapped {
92 Either::Left(v) => assert_eq!(v, 7),
93 Either::Right(_) => panic!("expected Left"),
94 }
95 }
96}