Skip to main content

scoped_error/
context.rs

1// Copyright (C) 2026 Kan-Ru Chen <kanru@kanru.info>
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5use std::borrow::Cow;
6use std::error::Error as StdError;
7use std::panic::Location;
8
9use crate::{Error, Frame, WithContext};
10
11/// Provides the context method for Result.
12pub trait Context<T, E> {
13    /// Wrap the error value with additional context.
14    fn context<C>(self, context: C) -> Result<T, Error>
15    where
16        C: Into<Cow<'static, str>>;
17    /// Wrap the error value with additional context that is evaluated lazily only once an error does occur.
18    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}