Skip to main content

nexcore_error/
context.rs

1//! Context trait for error chaining.
2
3use crate::{NexError, Result};
4use core::fmt;
5
6/// Extension trait to add context to errors.
7pub trait Context<T> {
8    /// Adds context to an error.
9    ///
10    /// # Errors
11    /// Returns the original error with the new context attached.
12    fn context<C: fmt::Display + Send + Sync + 'static>(self, ctx: C) -> Result<T>;
13
14    /// Adds lazy context to an error.
15    ///
16    /// # Errors
17    /// Returns the original error with the new context attached.
18    fn with_context<C, F>(self, f: F) -> Result<T>
19    where
20        C: fmt::Display + Send + Sync + 'static,
21        F: FnOnce() -> C;
22}
23
24impl<T, E> Context<T> for core::result::Result<T, E>
25where
26    NexError: From<E>,
27{
28    fn context<C: fmt::Display + Send + Sync + 'static>(self, ctx: C) -> Result<T> {
29        self.map_err(|e| NexError::from(e).context(ctx))
30    }
31
32    fn with_context<C, F>(self, f: F) -> Result<T>
33    where
34        C: fmt::Display + Send + Sync + 'static,
35        F: FnOnce() -> C,
36    {
37        self.map_err(|e| NexError::from(e).context(f()))
38    }
39}
40
41impl<T> Context<T> for core::option::Option<T> {
42    fn context<C: fmt::Display + Send + Sync + 'static>(self, ctx: C) -> Result<T> {
43        self.ok_or_else(|| NexError::msg(ctx))
44    }
45
46    fn with_context<C, F>(self, f: F) -> Result<T>
47    where
48        C: fmt::Display + Send + Sync + 'static,
49        F: FnOnce() -> C,
50    {
51        self.ok_or_else(|| NexError::msg(f()))
52    }
53}