1use std::borrow::Cow;
2
3use crate::ErrorChain;
4
5pub trait ResultChain<I, T, E, D> {
6 fn about(self, desc: D) -> Result<T, ErrorChain<I>>
7 where
8 Self: Sized,
9 E: Into<I>,
10 D: Into<Cow<'static, str>>;
11 fn about_else(self, f: impl FnOnce() -> D) -> Result<T, ErrorChain<I>>
12 where
13 Self: Sized,
14 E: Into<I>,
15 D: Into<Cow<'static, str>>;
16}
17
18impl<I, T, E> ResultChain<I, T, E, &'static str> for std::result::Result<T, E> {
19 fn about(self, desc: &'static str) -> Result<T, ErrorChain<I>>
20 where
21 Self: Sized,
22 E: Into<I>,
23 {
24 self.map_err(|e| ErrorChain::with_context(e, desc))
25 }
26 fn about_else(self, f: impl FnOnce() -> &'static str) -> Result<T, ErrorChain<I>>
27 where
28 Self: Sized,
29 E: Into<I>,
30 {
31 self.map_err(|e| ErrorChain::with_context(e, f()))
32 }
33}
34
35impl<I, T, E> ResultChain<I, T, E, String> for std::result::Result<T, E> {
36 fn about(self, desc: String) -> Result<T, ErrorChain<I>>
37 where
38 Self: Sized,
39 E: Into<I>,
40 {
41 self.map_err(|e| ErrorChain::with_context(e, desc))
42 }
43 fn about_else(self, f: impl FnOnce() -> String) -> Result<T, ErrorChain<I>>
44 where
45 Self: Sized,
46 E: Into<I>,
47 {
48 self.map_err(|e| ErrorChain::with_context(e, f()))
49 }
50}
51#[cfg(test)]
64mod tests {
65 use super::ResultChain;
66 use crate as resplus;
67 use crate::tests::{about, about_else};
68 use test_util::*;
69
70 #[test]
71 fn about() {
72 assert_result!(about!(f0()), "source: Error\n source");
73 assert_result!(about!(f1(1)), "source: Error\n source");
74 assert_result!(about!(f2(1, 1)), "source: Error\n source");
75 }
76
77 #[test]
78 fn about_else() {
79 assert_result!(about_else!(f0()), "source: Error\n source");
80 assert_result!(about_else!(f1(1)), "source: Error\n source");
81 assert_result!(about_else!(f2(1, 1)), "source: Error\n source");
82 }
83 }