error_stack/frame/
frame_impl.rs1#![expect(deprecated, reason = "We use `Context` to maintain compatibility")]
2
3use alloc::boxed::Box;
4#[cfg(nightly)]
5use core::error::Request;
6use core::{any::Any, error::Error, fmt};
7
8use crate::{AttachmentKind, Context, Frame, FrameKind};
9
10pub(super) trait FrameImpl: Send + Sync + 'static {
12 fn kind(&self) -> FrameKind<'_>;
13
14 fn as_any(&self) -> &dyn Any;
15
16 fn as_any_mut(&mut self) -> &mut dyn Any;
17
18 #[cfg(nightly)]
20 fn provide<'a>(&'a self, request: &mut Request<'a>);
21}
22
23impl fmt::Debug for Box<dyn FrameImpl> {
24 fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
25 unreachable!()
26 }
27}
28
29impl fmt::Display for Box<dyn FrameImpl> {
30 fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
31 unreachable!()
32 }
33}
34
35impl Error for Box<dyn FrameImpl> {
36 #[cfg(nightly)]
37 fn provide<'a>(&'a self, request: &mut Request<'a>) {
38 (**self).provide(request);
39 }
40}
41
42struct ContextFrame<C> {
43 context: C,
44}
45
46impl<C: Context> FrameImpl for ContextFrame<C> {
47 fn kind(&self) -> FrameKind<'_> {
48 FrameKind::Context(&self.context)
49 }
50
51 fn as_any(&self) -> &dyn Any {
52 &self.context
53 }
54
55 fn as_any_mut(&mut self) -> &mut dyn Any {
56 &mut self.context
57 }
58
59 #[cfg(nightly)]
60 fn provide<'a>(&'a self, request: &mut Request<'a>) {
61 Context::provide(&self.context, request);
62 }
63}
64
65struct AttachmentFrame<A> {
66 attachment: A,
67}
68
69impl<A: 'static + Send + Sync> FrameImpl for AttachmentFrame<A> {
70 fn kind(&self) -> FrameKind<'_> {
71 FrameKind::Attachment(AttachmentKind::Opaque(&self.attachment))
72 }
73
74 fn as_any(&self) -> &dyn Any {
75 &self.attachment
76 }
77
78 fn as_any_mut(&mut self) -> &mut dyn Any {
79 &mut self.attachment
80 }
81
82 #[cfg(nightly)]
83 fn provide<'a>(&'a self, request: &mut Request<'a>) {
84 request.provide_ref(&self.attachment);
85 }
86}
87
88struct PrintableAttachmentFrame<A> {
89 attachment: A,
90}
91
92impl<A: 'static + fmt::Debug + fmt::Display + Send + Sync> FrameImpl
93 for PrintableAttachmentFrame<A>
94{
95 fn kind(&self) -> FrameKind<'_> {
96 FrameKind::Attachment(AttachmentKind::Printable(&self.attachment))
97 }
98
99 fn as_any(&self) -> &dyn Any {
100 &self.attachment
101 }
102
103 fn as_any_mut(&mut self) -> &mut dyn Any {
104 &mut self.attachment
105 }
106
107 #[cfg(nightly)]
108 fn provide<'a>(&'a self, request: &mut Request<'a>) {
109 request.provide_ref(&self.attachment);
110 }
111}
112
113#[cfg(feature = "anyhow")]
114struct AnyhowContext(anyhow::Error);
115
116#[cfg(feature = "anyhow")]
117impl fmt::Debug for AnyhowContext {
118 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
119 fmt::Debug::fmt(&self.0, fmt)
120 }
121}
122
123#[cfg(feature = "anyhow")]
124impl fmt::Display for AnyhowContext {
125 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
126 fmt::Display::fmt(&self.0, fmt)
127 }
128}
129
130#[cfg(feature = "anyhow")]
131impl Context for AnyhowContext {
132 #[cfg(all(nightly, feature = "std"))]
133 #[inline]
134 fn provide<'a>(&'a self, request: &mut Request<'a>) {
135 request.provide_ref(self.0.backtrace());
136 }
137}
138
139#[cfg(feature = "anyhow")]
140impl FrameImpl for AnyhowContext {
141 fn kind(&self) -> FrameKind<'_> {
142 FrameKind::Context(self)
143 }
144
145 fn as_any(&self) -> &dyn Any {
146 &self.0
147 }
148
149 fn as_any_mut(&mut self) -> &mut dyn Any {
150 &mut self.0
151 }
152
153 #[cfg(nightly)]
154 #[inline]
155 fn provide<'a>(&'a self, request: &mut Request<'a>) {
156 Context::provide(self, request);
157 }
158}
159
160#[cfg(feature = "eyre")]
161struct EyreContext(eyre::Report);
162
163#[cfg(feature = "eyre")]
164impl fmt::Debug for EyreContext {
165 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
166 fmt::Debug::fmt(&self.0, fmt)
167 }
168}
169
170#[cfg(feature = "eyre")]
171impl fmt::Display for EyreContext {
172 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
173 fmt::Display::fmt(&self.0, fmt)
174 }
175}
176
177#[cfg(feature = "eyre")]
178impl Context for EyreContext {
179 #[cfg(nightly)]
180 #[inline]
181 fn provide<'a>(&'a self, request: &mut Request<'a>) {
182 Error::provide(self.0.as_ref() as &dyn Error, request);
183 }
184}
185
186#[cfg(feature = "eyre")]
187impl FrameImpl for EyreContext {
188 fn kind(&self) -> FrameKind<'_> {
189 FrameKind::Context(self)
190 }
191
192 fn as_any(&self) -> &dyn Any {
193 &self.0
194 }
195
196 fn as_any_mut(&mut self) -> &mut dyn Any {
197 &mut self.0
198 }
199
200 #[cfg(nightly)]
201 #[inline]
202 fn provide<'a>(&'a self, request: &mut Request<'a>) {
203 Context::provide(self, request);
204 }
205}
206
207impl Frame {
208 pub(crate) fn from_context<C>(context: C, sources: Box<[Self]>) -> Self
210 where
211 C: Context,
212 {
213 Self {
214 frame: Box::new(ContextFrame { context }),
215 sources,
216 }
217 }
218
219 pub(crate) fn from_attachment<A>(attachment: A, sources: Box<[Self]>) -> Self
221 where
222 A: Send + Sync + 'static,
223 {
224 Self {
225 frame: Box::new(AttachmentFrame { attachment }),
226 sources,
227 }
228 }
229
230 pub(crate) fn from_printable_attachment<A>(attachment: A, sources: Box<[Self]>) -> Self
235 where
236 A: fmt::Display + fmt::Debug + Send + Sync + 'static,
237 {
238 Self {
239 frame: Box::new(PrintableAttachmentFrame { attachment }),
240 sources,
241 }
242 }
243
244 #[cfg(feature = "anyhow")]
246 pub(crate) fn from_anyhow(error: anyhow::Error, sources: Box<[Self]>) -> Self {
247 Self {
248 frame: Box::new(AnyhowContext(error)),
249 sources,
250 }
251 }
252
253 #[cfg(feature = "eyre")]
255 pub(crate) fn from_eyre(report: eyre::Report, sources: Box<[Self]>) -> Self {
256 Self {
257 frame: Box::new(EyreContext(report)),
258 sources,
259 }
260 }
261}