1use crate::handled::IntoValue;
4use crate::Result;
5
6pub trait HandleExt<T> {
8 fn then<U, F>(self, f: F) -> Result<U>
10 where
11 F: FnOnce(T) -> Result<U>;
12
13 fn then_with<U, F>(self, ctx: impl Into<String>, f: F) -> Result<U>
15 where
16 F: FnOnce(T) -> Result<U>;
17
18 fn context(self, ctx: impl Into<String>) -> Self;
20
21 fn attach(self, key: &'static str, val: impl IntoValue) -> Self;
23}
24
25impl<T> HandleExt<T> for Result<T> {
26 #[track_caller]
27 fn then<U, F>(self, f: F) -> Result<U>
28 where
29 F: FnOnce(T) -> Result<U>,
30 {
31 let loc = core::panic::Location::caller();
32 match self {
33 Ok(v) => f(v).map_err(|e| e.frame(loc.file(), loc.line(), loc.column())),
34 Err(e) => Err(e),
35 }
36 }
37
38 #[track_caller]
39 fn then_with<U, F>(self, ctx: impl Into<String>, f: F) -> Result<U>
40 where
41 F: FnOnce(T) -> Result<U>,
42 {
43 let loc = core::panic::Location::caller();
44 let ctx = ctx.into();
45 match self {
46 Ok(v) => f(v).map_err(|e| e.frame(loc.file(), loc.line(), loc.column()).ctx(ctx)),
47 Err(e) => Err(e),
48 }
49 }
50
51 #[track_caller]
52 fn context(self, ctx: impl Into<String>) -> Self {
53 let loc = core::panic::Location::caller();
54 self.map_err(|e| e.frame(loc.file(), loc.line(), loc.column()).ctx(ctx))
55 }
56
57 #[track_caller]
58 fn attach(self, key: &'static str, val: impl IntoValue) -> Self {
59 let loc = core::panic::Location::caller();
60 self.map_err(|e| e.frame(loc.file(), loc.line(), loc.column()).kv(key, val))
61 }
62}