predawn_core/
error_ext.rs1use std::error::Error;
2
3use crate::location::Location;
4
5pub enum NextError<'a> {
6 Ext(&'a dyn ErrorExt),
7 Std(&'a dyn Error),
8 None,
9}
10
11pub trait ErrorExt: Error {
12 fn entry(&self) -> (Location, NextError<'_>);
13
14 fn error_stack(&self) -> Box<[Box<str>]> {
15 let mut stack = Vec::new();
16
17 let mut next_error = {
18 let (location, next_error) = self.entry();
19 stack.push(format!("0: {self}, at {location}").into_boxed_str());
20 next_error
21 };
22
23 loop {
24 let idx = stack.len();
25
26 match next_error {
27 NextError::Ext(e) => {
28 next_error = {
29 let (location, next_error) = e.entry();
30 stack.push(format!("{idx}: {e}, at {location}").into_boxed_str());
31 next_error
32 };
33 continue;
34 }
35 NextError::Std(e) => {
36 stack.push(format!("{idx}: {e}").into_boxed_str());
37 break;
38 }
39 NextError::None => break,
40 }
41 }
42
43 stack.into_boxed_slice()
44 }
45}