spade_diagnostics/
diag_list.rs

1use crate::Diagnostic;
2
3#[derive(Debug, Clone, Default)]
4pub struct DiagList {
5    pub errors: Vec<Diagnostic>,
6}
7
8impl DiagList {
9    pub fn new() -> Self {
10        Self { errors: vec![] }
11    }
12
13    pub fn drain(&mut self) -> Vec<Diagnostic> {
14        let mut result = vec![];
15        std::mem::swap(&mut self.errors, &mut result);
16        result
17    }
18
19    pub fn drain_to_new(&mut self) -> Self {
20        Self {
21            errors: self.drain(),
22        }
23    }
24
25    pub fn extend(&mut self, other: &mut Self) {
26        self.errors.extend(other.drain())
27    }
28}
29
30impl Drop for DiagList {
31    fn drop(&mut self) {
32        if !self.errors.is_empty() {
33            println!("WARNING: Dropped a DiagList without draining the errors");
34            println!(
35                "Backtrace:\n{}",
36                std::backtrace::Backtrace::capture().to_string()
37            )
38        }
39    }
40}
41
42pub trait ResultExt<T> {
43    fn handle_in(self, diag: &mut DiagList) -> Option<T>;
44}
45
46impl<T> ResultExt<T> for Result<T, Diagnostic> {
47    fn handle_in(self, diag: &mut DiagList) -> Option<T> {
48        match self {
49            Ok(val) => Some(val),
50            Err(err) => {
51                diag.errors.push(err);
52                None
53            }
54        }
55    }
56}