1pub use core::error::Error as ErrorTrait;
2use core::panic::Location;
3use core::fmt::{ self, Debug, Display };
4
5pub mod prelude;
6#[cfg(feature = "axum-0-8")]
7mod axum_0_8;
8#[path = "proc_macro_support.rs"]
9pub mod __proc_macro_support;
10
11pub struct Err<E> {
12 frame: Box<TypedFrame<E>>
14}
15
16impl<E> Err<E>
17where
18 E: ErrorTrait + Send + Sync + 'static
19{
20 #[inline]
21 #[track_caller]
22 pub fn from_err(err: E) -> Self {
23 let children = walk(&err);
24
25 Err {
26 frame: Box::new(TypedFrame {
27 err,
28 location: Location::caller(),
29 children
30 })
31 }
32 }
33
34 #[inline]
35 #[track_caller]
36 pub fn from_errs<C>(err: E, children: &mut dyn Iterator<Item = C>) -> Self
37 where
38 C: ErrorTrait + Send + Sync + 'static
39 {
40 let (len, _) = children.size_hint();
41 let mut processed_children = Vec::with_capacity(len);
42 for err in children {
43 let children = walk(&err);
44
45 processed_children.push(Frame {
46 err: Box::new(err),
47 location: Location::caller(),
48 children
49 });
50 }
51
52 Err {
53 frame: Box::new(TypedFrame {
54 err,
55 location: Location::caller(),
56 children: processed_children
57 })
58 }
59 }
60
61 #[inline]
62 #[track_caller]
63 pub fn raise<E2>(self, err: E2) -> Err<E2>
64 where
65 E2: ErrorTrait + Send + Sync + 'static
66 {
67 let mut new = Err::from_err(err);
68 new.frame.children.push((*self.frame).into());
69 new
70 }
71
72 #[inline]
73 pub fn as_inner(&self) -> &E {
74 &self.frame.err
75 }
76
77 #[inline]
78 pub fn simple_display(&self) -> SimpleDisplay<'_, E> {
79 SimpleDisplay { inner: self }
80 }
81
82 #[inline]
83 pub fn detailed_display(&self) -> DetailedDisplay<'_, E> {
84 DetailedDisplay { inner: self }
85 }
86
87 #[inline]
88 pub fn as_error(&self) -> ErrorImplementorBorrowed<'_, E> {
89 ErrorImplementorBorrowed { inner: self }
90 }
91
92 #[inline]
93 pub fn into_error(self) -> ErrorImplementorOwned<E> {
94 ErrorImplementorOwned { inner: self }
95 }
96}
97
98impl<E> Debug for Err<E>
99where
100 E: ErrorTrait + Send + Sync + 'static
101{
102 #[inline]
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 self.detailed_display().fmt(f)
105 }
106}
107
108struct TypedFrame<E> {
109 err: E,
110 location: &'static Location<'static>,
111 children: Vec<Frame>
112}
113
114struct Frame {
115 err: Box<dyn ErrorTrait + Send + Sync + 'static>,
116 location: &'static Location<'static>,
117 children: Vec<Frame>
118}
119
120impl<E> From<TypedFrame<E>> for Frame
121where
122 E: ErrorTrait + Send + Sync + 'static
123{
124 #[inline]
125 fn from(frame: TypedFrame<E>) -> Self {
126 let TypedFrame { err, location, children } = frame;
127 let err = Box::new(err);
128 Frame { err, location, children }
129 }
130}
131
132struct BorrowedFrame<'h> {
133 err: &'h (dyn ErrorTrait + Send + Sync + 'static),
134 location: &'static Location<'static>,
135 children: &'h [Frame]
136}
137
138impl<'h, E> From<&'h TypedFrame<E>> for BorrowedFrame<'h>
139where
140 E: ErrorTrait + Send + Sync + 'static
141{
142 #[inline]
143 fn from(frame: &'h TypedFrame<E>) -> Self {
144 let TypedFrame { err, location, children } = frame;
145 Self { err, location, children }
146 }
147}
148
149impl<'h> From<&'h Frame> for BorrowedFrame<'h> {
150 #[inline]
151 fn from(frame: &'h Frame) -> Self {
152 let Frame { err, location, children } = frame;
153 Self { err: &**err, location, children }
154 }
155}
156
157pub struct SimpleDisplay<'h, E> {
158 inner: &'h Err<E>
159}
160
161impl<'h, E> Display for SimpleDisplay<'h, E>
162where
163 E: ErrorTrait + Send + Sync + 'static
164{
165 #[inline]
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 Display::fmt(&self.inner.frame.err, f)
168 }
169}
170
171pub struct DetailedDisplay<'h, E> {
172 inner: &'h Err<E>
173}
174
175impl<'h, E> Display for DetailedDisplay<'h, E>
176where
177 E: ErrorTrait + Send + Sync + 'static
178{
179 #[inline]
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 print_err_dbg(
182 f,
183 (&*self.inner.frame).into(),
184 0,
185 &mut String::new()
186 )
187 }
188}
189
190pub struct ErrorImplementorBorrowed<'h, E> {
191 inner: &'h Err<E>
192}
193
194impl<'h, E> ErrorImplementorBorrowed<'h, E> {
195 #[inline]
196 pub fn as_err(&self) -> &Err<E> {
197 self.inner
198 }
199}
200
201impl<'h, E> Debug for ErrorImplementorBorrowed<'h, E>
202where
203 E: ErrorTrait + Send + Sync + 'static
204{
205 #[inline]
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 self.inner.detailed_display().fmt(f)
208 }
209}
210
211impl<'h, E> Display for ErrorImplementorBorrowed<'h, E>
212where
213 E: ErrorTrait + Send + Sync + 'static
214{
215 #[inline]
216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
217 self.inner.simple_display().fmt(f)
218 }
219}
220
221impl<'h, E> ErrorTrait for ErrorImplementorBorrowed<'h, E>
222where
223 E: ErrorTrait + Send + Sync + 'static
224{}
225
226pub struct ErrorImplementorOwned<E> {
227 inner: Err<E>
228}
229
230impl<E> ErrorImplementorOwned<E> {
231 #[inline]
232 pub fn as_err(&self) -> &Err<E> {
233 &self.inner
234 }
235
236 #[inline]
237 pub fn into_err(self) -> Err<E> {
238 self.inner
239 }
240}
241
242impl<E> Debug for ErrorImplementorOwned<E>
243where
244 E: ErrorTrait + Send + Sync + 'static
245{
246 #[inline]
247 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
248 self.inner.detailed_display().fmt(f)
249 }
250}
251
252impl<E> Display for ErrorImplementorOwned<E>
253where
254 E: ErrorTrait + Send + Sync + 'static
255{
256 #[inline]
257 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258 self.inner.simple_display().fmt(f)
259 }
260}
261
262impl<E> ErrorTrait for ErrorImplementorOwned<E>
263where
264 E: ErrorTrait + Send + Sync + 'static
265{}
266
267struct StringError {
268 debug: Box<str>,
269 display: Box<str>
270}
271
272impl Debug for StringError {
273 #[inline]
274 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275 f.write_str(&self.debug)
276 }
277}
278
279impl Display for StringError {
280 #[inline]
281 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282 f.write_str(&self.display)
283 }
284}
285
286impl ErrorTrait for StringError {}
287
288#[track_caller]
289fn walk(err: &dyn ErrorTrait) -> Vec<Frame> {
290 if let Some(err) = err.source() {
291 vec![Frame {
292 err: Box::new(StringError {
293 debug: format!("{err:?}").into_boxed_str(),
294 display: format!("{err}").into_boxed_str()
295 }),
296 location: Location::caller(),
297 children: walk(err)
298 }]
299 } else {
300 Vec::new()
301 }
302}
303
304fn print_err_dbg(
305 f: &mut fmt::Formatter<'_>,
306 frame: BorrowedFrame<'_>,
307 level: usize,
308 prefix_buf: &mut String
309) -> fmt::Result {
310 let prefix_buf_len = prefix_buf.len();
311 let level_in_spaces = level * 2;
312 if prefix_buf_len < level_in_spaces {
313 let additional = level_in_spaces - prefix_buf_len;
314
315 prefix_buf.reserve(additional);
316 (0..additional).for_each(|_| prefix_buf.push(' '));
317 }
318 let prefix = &prefix_buf[..level_in_spaces];
319
320 write!(
321 f,
322 "{prefix}- err in {file}, at {line}:{col}",
323 file = frame.location.file(),
324 line = frame.location.line(),
325 col = frame.location.column()
326 )?;
327
328 write!(f, "\n{prefix} {}", frame.err)?;
329
330 if !frame.children.is_empty() {
331 write!(f, "\n{prefix} caused by:")?;
332 }
333
334 for child in frame.children {
335 writeln!(f)?;
336 print_err_dbg(f, child.into(), level + 1, prefix_buf)?;
337 }
338
339 Ok(())
340}
341
342pub trait ErrorExt {
343 fn raise(self) -> Err<Self>
344 where
345 Self: Sized;
346}
347
348impl<E> ErrorExt for E
349where
350 E: ErrorTrait + Send + Sync + 'static
351{
352 #[inline]
353 #[track_caller]
354 fn raise(self) -> Err<Self> {
355 Err::from_err(self)
356 }
357}
358
359pub trait OptionExt {
360 type Ok;
361
362 fn or_raise<E>(self, err: impl FnOnce() -> E) -> Result<Self::Ok, Err<E>>
363 where
364 E: ErrorTrait + Send + Sync + 'static;
365}
366
367impl<T> OptionExt for Option<T> {
368 type Ok = T;
369
370 #[inline]
371 #[track_caller]
372 fn or_raise<E>(self, err: impl FnOnce() -> E) -> Result<T, Err<E>>
373 where
374 E: ErrorTrait + Send + Sync + 'static
375 {
376 match self {
377 Some(value) => { Ok(value) }
378 None => { Err(Err::from_err(err())) }
379 }
380 }
381}
382
383pub trait ResultExt {
384 type Ok;
385 type Err;
386
387 fn or_raise<E>(self, err: impl FnOnce() -> E) -> Result<Self::Ok, Err<E>>
388 where
389 E: ErrorTrait + Send + Sync + 'static;
390}
391
392impl<T, E> ResultExt for Result<T, E>
393where
394 E: ErrorTrait + Send + Sync + 'static
395{
396 type Ok = T;
397 type Err = E;
398
399 #[inline]
400 #[track_caller]
401 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
402 where
403 E2: ErrorTrait + Send + Sync + 'static
404 {
405 match self {
406 Ok(value) => { Ok(value) }
407 Err(prev_err) => { Err(Err::from_err(prev_err).raise(err())) }
408 }
409 }
410}
411
412impl<T, E> ResultExt for Result<T, Err<E>>
413where
414 E: ErrorTrait + Send + Sync + 'static
415{
416 type Ok = T;
417 type Err = E;
418
419 #[inline]
420 #[track_caller]
421 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
422 where
423 E2: ErrorTrait + Send + Sync + 'static
424 {
425 match self {
426 Ok(value) => { Ok(value) }
427 Err(prev_err) => { Err(prev_err.raise(err())) }
428 }
429 }
430}
431
432pub trait ResultManyExt {
433 type Ok;
434 type Err;
435
436 fn or_raise<E>(self, err: impl FnOnce() -> E) -> Result<Self::Ok, Err<E>>
437 where
438 E: ErrorTrait + Send + Sync + 'static;
439}
440
441impl<T, E> ResultManyExt for Result<T, Vec<E>>
442where
443 E: ErrorTrait + Send + Sync + 'static
444{
445 type Ok = T;
446 type Err = E;
447
448 #[inline]
449 #[track_caller]
450 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
451 where
452 E2: ErrorTrait + Send + Sync + 'static
453 {
454 match self {
455 Ok(value) => { Ok(value) }
456 Err(errors) => { Err(Err::from_errs(err(), &mut errors.into_iter())) }
457 }
458 }
459}
460
461impl<T, E> ResultManyExt for Result<T, Vec<Err<E>>>
462where
463 E: ErrorTrait + Send + Sync + 'static
464{
465 type Ok = T;
466 type Err = E;
467
468 #[inline]
469 #[track_caller]
470 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
471 where
472 E2: ErrorTrait + Send + Sync + 'static
473 {
474 match self {
475 Ok(value) => { Ok(value) }
476 Err(errors) => {
477 let mut errors = errors
478 .into_iter()
479 .map(Err::into_error);
480
481 Err(Err::from_errs(err(), &mut errors))
482 }
483 }
484 }
485}
486
487impl<T, E> ResultManyExt for Result<T, &[E]>
488where
489 E: ErrorTrait + Clone + Send + Sync + 'static
490{
491 type Ok = T;
492 type Err = E;
493
494 #[inline]
495 #[track_caller]
496 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
497 where
498 E2: ErrorTrait + Send + Sync + 'static
499 {
500 match self {
501 Ok(value) => { Ok(value) }
502 Err(errors) => { Err(Err::from_errs(err(), &mut errors.iter().cloned())) }
503 }
504 }
505}
506
507impl<T, E, const N: usize> ResultManyExt for Result<T, [E; N]>
508where
509 E: ErrorTrait + Send + Sync + 'static
510{
511 type Ok = T;
512 type Err = E;
513
514 #[inline]
515 #[track_caller]
516 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
517 where
518 E2: ErrorTrait + Send + Sync + 'static
519 {
520 match self {
521 Ok(value) => { Ok(value) }
522 Err(errors) => { Err(Err::from_errs(err(), &mut errors.into_iter())) }
523 }
524 }
525}
526
527impl<T, E, const N: usize> ResultManyExt for Result<T, [Err<E>; N]>
528where
529 E: ErrorTrait + Send + Sync + 'static
530{
531 type Ok = T;
532 type Err = E;
533
534 #[inline]
535 #[track_caller]
536 fn or_raise<E2>(self, err: impl FnOnce() -> E2) -> Result<T, Err<E2>>
537 where
538 E2: ErrorTrait + Send + Sync + 'static
539 {
540 match self {
541 Ok(value) => { Ok(value) }
542 Err(errors) => {
543 let mut errors = errors
544 .into_iter()
545 .map(Err::into_error);
546
547 Err(Err::from_errs(err(), &mut errors))
548 }
549 }
550 }
551}