1pub trait ResultExt<T, E>: Sized {
3 fn bind<R>(self, f: impl FnOnce(T) -> Result<R, E>) -> Result<R, E>;
5
6 fn swap(self) -> Result<E, T>;
8
9 fn recover<R>(self, f: impl FnOnce(E) -> Result<T, R>) -> Result<T, R>;
11
12 fn try_perform(self, f: impl FnOnce(&T) -> Result<(), E>) -> Result<T, E>;
14
15 fn perform_err(self, f: impl FnOnce(&E) -> ()) -> Result<T, E>;
17
18 fn perform(self, f: impl FnOnce(&T) -> ()) -> Result<T, E>;
20
21 fn perform_mut(self, f: impl FnOnce(&mut T) -> ()) -> Result<T, E>;
23
24 fn filter(self, pred: impl FnOnce(&T) -> bool, on_fail: impl FnOnce(&T) -> E) -> Result<T, E>;
26
27 fn tupled<R>(self, f: impl FnOnce(&T) -> Result<R, E>) -> Result<(T, R), E> {
29 self.bind(|t| f(&t).map(|r| (t, r)))
30 }
31
32 fn two<B>(a: Result<T, E>, b: Result<B, E>) -> Result<(T, B), E> {
34 a.and_then(|a| b.map(|b| (a, b)))
35 }
36}
37
38impl<T, E> ResultExt<T, E> for Result<T, E> {
39 fn bind<R>(self, f: impl FnOnce(T) -> Result<R, E>) -> Result<R, E> {
40 self.and_then(f)
41 }
42
43 fn recover<R>(self, f: impl FnOnce(E) -> Result<T, R>) -> Result<T, R> {
44 match self {
45 | Ok(t) => Ok(t),
46 | Err(e) => f(e),
47 }
48 }
49
50 fn try_perform(self, f: impl FnOnce(&T) -> Result<(), E>) -> Result<T, E> {
51 self.and_then(|t| f(&t).map(|_| t))
52 }
53
54 fn perform(self, f: impl FnOnce(&T) -> ()) -> Result<T, E> {
55 self.map(|t| {
56 f(&t);
57 t
58 })
59 }
60
61 fn perform_err(self, f: impl FnOnce(&E) -> ()) -> Result<T, E> {
62 self.map_err(|t| {
63 f(&t);
64 t
65 })
66 }
67
68 fn perform_mut(self, f: impl FnOnce(&mut T) -> ()) -> Result<T, E> {
69 self.map(|mut t| {
70 f(&mut t);
71 t
72 })
73 }
74
75 fn filter(self, pred: impl FnOnce(&T) -> bool, on_fail: impl FnOnce(&T) -> E) -> Result<T, E> {
76 self.bind(|t| if pred(&t) { Err(on_fail(&t)) } else { Ok(t) })
77 }
78
79 fn swap(self) -> Result<E, T> {
80 match self {
81 | Ok(err) => Err(err),
82 | Err(ok) => Ok(ok),
83 }
84 }
85}