Skip to main content

error_stack/
context.rs

1use alloc::string::{String, ToString as _};
2use core::{error::Error, fmt};
3
4use crate::Report;
5
6/// Captures an error message as the context of a [`Report`].
7pub(crate) struct SourceContext(String);
8
9impl SourceContext {
10    pub(crate) fn from_error(value: &dyn Error) -> Self {
11        Self(value.to_string())
12    }
13}
14
15impl fmt::Debug for SourceContext {
16    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
17        fmt::Debug::fmt(&self.0, fmt)
18    }
19}
20
21impl fmt::Display for SourceContext {
22    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
23        fmt::Display::fmt(&self.0, fmt)
24    }
25}
26
27impl Error for SourceContext {}
28
29impl<C> From<C> for Report<C>
30where
31    C: Error + Send + Sync + 'static,
32{
33    #[track_caller]
34    #[inline]
35    fn from(context: C) -> Self {
36        Self::new(context)
37    }
38}
39
40/// A trait for types that can be attached to a [`Report`] without being displayed.
41pub trait OpaqueAttachment: Send + Sync + 'static {}
42
43impl<T: Send + Sync + 'static> OpaqueAttachment for T {}
44
45/// A trait for types that can be attached to a [`Report`] and displayed.
46#[diagnostic::on_unimplemented(
47    message = "to attach this type to a `Report` it must implement `fmt::Display` and `fmt::Debug`",
48    note = "if you want to attach a type that is not printable, use `attach_opaque` instead"
49)]
50pub trait Attachment: OpaqueAttachment + fmt::Display + fmt::Debug {}
51
52impl<T: OpaqueAttachment + fmt::Display + fmt::Debug> Attachment for T {}