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