toad_common/
result.rs

1/// Extensions to Result
2pub trait ResultExt<T, E>: Sized {
3  /// Alias for [`Result.and_then`]
4  fn bind<R>(self, f: impl FnOnce(T) -> Result<R, E>) -> Result<R, E>;
5
6  /// Swap the Ok and Err variants
7  fn swap(self) -> Result<E, T>;
8
9  /// Allows turning an Err back into Ok by binding on the Err variant
10  fn recover<R>(self, f: impl FnOnce(E) -> Result<T, R>) -> Result<T, R>;
11
12  /// Attempt to perform some fallible IO
13  fn try_perform(self, f: impl FnOnce(&T) -> Result<(), E>) -> Result<T, E>;
14
15  /// Perform some IO when this Result is Err
16  fn perform_err(self, f: impl FnOnce(&E) -> ()) -> Result<T, E>;
17
18  /// Perform some IO when this Result is Ok
19  fn perform(self, f: impl FnOnce(&T) -> ()) -> Result<T, E>;
20
21  /// Perform some IO mutating the data contained in the Ok of this Result
22  fn perform_mut(self, f: impl FnOnce(&mut T) -> ()) -> Result<T, E>;
23
24  /// Test the data in Ok and turn it into an Err if it doesn't pass a predicate
25  fn filter(self, pred: impl FnOnce(&T) -> bool, on_fail: impl FnOnce(&T) -> E) -> Result<T, E>;
26
27  /// Do some fallible IO that resolves in a value and combine Oks
28  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  /// Boolean AND
33  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}