Skip to main content

handle_this/
ext.rs

1//! Extension trait for Result types.
2
3use crate::handled::IntoValue;
4use crate::Result;
5
6/// Extension trait for adding context to `Result<T, Handled>`.
7pub trait HandleExt<T> {
8    /// Chain another operation, adding a frame on error.
9    fn then<U, F>(self, f: F) -> Result<U>
10    where
11        F: FnOnce(T) -> Result<U>;
12
13    /// Chain another operation with context message.
14    fn then_with<U, F>(self, ctx: impl Into<String>, f: F) -> Result<U>
15    where
16        F: FnOnce(T) -> Result<U>;
17
18    /// Add context message to error.
19    fn context(self, ctx: impl Into<String>) -> Self;
20
21    /// Add key-value attachment to error with typed value.
22    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}