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}