Skip to main content

mazer_core/
pretty_err.rs

1use colored::*;
2
3#[derive(Debug, Clone)]
4pub struct DebugContext {
5    file_path: String,
6    err_kind: Option<ErrorKind>,
7    src: String,
8    err_pos: usize,
9}
10
11impl DebugContext {
12    pub fn new(file_path: &str) -> Self {
13        DebugContext {
14            file_path: file_path.to_string(),
15            err_kind: None,
16            src: String::new(),
17            err_pos: 0,
18        }
19    }
20
21    pub fn reset(&mut self) -> Self {
22        self.err_kind = None;
23        self.src = String::new();
24        self.err_pos = 0;
25
26        self.clone()
27    }
28
29    pub fn is_err(&self) -> bool {
30        self.err_kind.is_some()
31    }
32
33    pub fn set_source_code(&mut self, src: String) {
34        self.src = src;
35    }
36
37    pub fn set_error(&mut self, kind: ErrorKind) {
38        self.err_kind = Some(kind);
39    }
40
41    pub fn get_position(&self) -> usize {
42        self.err_pos
43    }
44
45    pub fn set_position(&mut self, err_pos: usize) {
46        self.err_pos = err_pos;
47    }
48
49    pub fn display(&self) {
50        if let Some(err_kind) = &self.err_kind {
51            eprintln!("src: {}", self.file_path);
52            eprintln!("{} {}", "[ERROR]".red().bold(), err_kind.error().red());
53            eprintln!("{} At position = {} ", "  -->".blue().bold(), self.err_pos);
54            eprintln!("{}", "  |".blue().bold());
55            eprintln!("{}", self.src.trim().dimmed());
56            eprintln!("{}", "  |".blue().bold());
57            eprint!("{}", "  =".blue().bold());
58            eprintln!(" {}: {:?}", "help".bold(), err_kind.message());
59            let mazer_colour = Color::TrueColor {
60                r: 236,
61                g: 166,
62                b: 124,
63            };
64            eprintln!(
65                "\n{} {}",
66                "  Mazer says".color(mazer_colour),
67                err_kind.name().bold().white()
68            );
69        } else {
70            eprintln!(
71                "{}",
72                "Oh no! something went terribly wrong, but we don't know what!"
73                    .red()
74                    .italic()
75            );
76            eprintln!(
77                "{}",
78                "Please report this issue to the Mazer project on GitHub."
79                    .red()
80                    .italic()
81            );
82        }
83    }
84}
85
86#[derive(Debug, Clone)]
87pub enum ErrorKind {
88    BrokenExpectations(String),
89    UnpleasantSurprise(String),
90    LonelyParenthesis(String),
91    GrammarGoblin(String),
92    NamelessNomad(String),
93    AbruptAdieu(String),
94}
95
96impl ErrorKind {
97    pub fn name(&self) -> String {
98        match self {
99            ErrorKind::BrokenExpectations(_) => "BrokenExpectations".to_string(),
100            ErrorKind::UnpleasantSurprise(_) => "UnpleasantSurprise".to_string(),
101            ErrorKind::LonelyParenthesis(_) => "LonelyParenthesis".to_string(),
102            ErrorKind::GrammarGoblin(_) => "GrammarGoblin".to_string(),
103            ErrorKind::NamelessNomad(_) => "NamelessNomad".to_string(),
104            ErrorKind::AbruptAdieu(_) => "AbruptAdieu".to_string(),
105        }
106    }
107
108    pub fn error(&self) -> String {
109        match self {
110            ErrorKind::BrokenExpectations(_) => format!("Expected token not found"),
111            ErrorKind::UnpleasantSurprise(_) => format!("Unexpected token found"),
112            ErrorKind::LonelyParenthesis(_) => format!("Unmatched parenthesis"),
113            ErrorKind::GrammarGoblin(_) => format!("Syntax error"),
114            ErrorKind::NamelessNomad(_) => format!("Unknown token found"),
115            ErrorKind::AbruptAdieu(_) => format!("Unexpected end of file"),
116        }
117    }
118
119    pub fn message(&self) -> String {
120        match self {
121            ErrorKind::BrokenExpectations(msg) => msg.clone(),
122            ErrorKind::UnpleasantSurprise(msg) => msg.clone(),
123            ErrorKind::LonelyParenthesis(msg) => msg.clone(),
124            ErrorKind::GrammarGoblin(msg) => msg.clone(),
125            ErrorKind::NamelessNomad(msg) => msg.clone(),
126            ErrorKind::AbruptAdieu(msg) => msg.clone(),
127        }
128    }
129}