1use std::borrow::Cow;
6use std::error::Error as StdError;
7use std::panic::Location;
8
9use crate::{Error, Frame, WithContext};
10
11pub trait Context<T, E> {
13 fn context<C>(self, context: C) -> Result<T, Error>
15 where
16 C: Into<Cow<'static, str>>;
17 fn with_context<C, F>(self, f: F) -> Result<T, Error>
19 where
20 C: Into<Cow<'static, str>>,
21 F: FnOnce() -> C;
22}
23
24impl<T, E> Context<T, E> for Result<T, E>
25where
26 E: StdError + Send + Sync + 'static,
27{
28 #[track_caller]
29 fn context<C>(self, context: C) -> Result<T, Error>
30 where
31 C: Into<Cow<'static, str>>,
32 {
33 let location = Location::caller();
34 self.map_err(|e| {
35 let source = e.into();
36 let frame = Frame { source, location };
37 Error::new(context).with_context(frame)
38 })
39 }
40
41 #[track_caller]
42 fn with_context<C, F>(self, f: F) -> Result<T, Error>
43 where
44 C: Into<Cow<'static, str>>,
45 F: FnOnce() -> C,
46 {
47 let location = Location::caller();
48 self.map_err(|e| {
49 let source = e.into();
50 let frame = Frame { source, location };
51 Error::new(f()).with_context(frame)
52 })
53 }
54}