predawn_core/
error_ext.rs

1use 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}