radicle_std_ext/result.rs
1pub trait ResultExt<T, E> {
2 /// Calls `f` if the result is [`Err`], **and** the predicate `pred` on the
3 /// error value returns true. Otherwise returns the [`Ok`] value of
4 /// `self`. Note that `f` may change the error type, so as long as the
5 /// target type can be converted from the original one.
6 ///
7 /// # Examples
8 ///
9 /// ```
10 /// use std::io;
11 /// use radicle_std_ext::result::ResultExt as _;
12 ///
13 /// let res = Err(io::Error::new(io::ErrorKind::Other, "crashbug"))
14 /// .or_matches::<io::Error, _, _>(|e| matches!(e.kind(), io::ErrorKind::Other), || Ok(()))
15 /// .unwrap();
16 ///
17 /// assert_eq!((), res)
18 /// ```
19 fn or_matches<E2, P, F>(self, pred: P, f: F) -> Result<T, E2>
20 where
21 E2: From<E>,
22 P: FnOnce(&E) -> bool,
23 F: FnOnce() -> Result<T, E2>;
24}
25
26impl<T, E> ResultExt<T, E> for Result<T, E> {
27 fn or_matches<E2, P, F>(self, pred: P, f: F) -> Result<T, E2>
28 where
29 E2: From<E>,
30 P: FnOnce(&E) -> bool,
31 F: FnOnce() -> Result<T, E2>,
32 {
33 self.or_else(|e| if pred(&e) { f() } else { Err(e.into()) })
34 }
35}