1use crate::token::Token;
8
9#[derive(Clone, Debug, PartialEq)]
11pub struct Error {
12 msg: String,
13}
14
15impl Error {
16 pub fn new(msg: String) -> Self {
17 Self { msg }
18 }
19
20 fn indexed_error(input: String, point: i32, err: String, expl: Vec<&str>) -> Self {
33 let mut message = err.clone();
34
35 let tab: String = String::from(" ");
36 let mut space: String = String::from("");
37 for _ in 0..point - 1 {
38 space.push_str(" ");
39 }
40
41 message.push_str(format!("{}\"{}\" \n", tab.clone(), input.trim_end()).as_str());
42 for exp in expl.iter() {
43 message.push_str(format!(" {}{}{}\n", tab.clone(), space.clone(), exp).as_str());
44 }
45
46 Self { msg: message }
47 }
48
49 pub fn empty_input() -> Self {
51 Self {
52 msg: String::from("error: cannot parse an empty input"),
53 }
54 }
55
56 pub fn empty_tokens() -> Self {
58 Self {
59 msg: String::from("error: cannot calculate result from an empty token list"),
60 }
61 }
62
63 pub fn missing_some_tokens(input: String, point: i32) -> Self {
77 let message = format!("error: missing some tokens to calculate result\n\n");
78
79 let mut inpt: String = input.clone().trim_end().to_string();
80 let pointer: String = String::from(" {X} ");
81
82 for i in 1..pointer.len() {
83 let p: usize = (point as usize) + i;
84 let pch: char = pointer.chars().nth(i - 1).unwrap();
85
86 let back_ch: char = match inpt.chars().nth(p - 1) {
87 Some(v) => v,
88 None => '0',
89 };
90 let next_ch: char = match inpt.chars().nth(p + 1) {
91 Some(v) => v,
92 None => '0',
93 };
94
95 if back_ch == ' ' && pch == ' ' || next_ch == ' ' && pch == ' ' {
96 continue;
97 }
98
99 inpt.insert(p, pch);
100 }
101
102 let explanation: Vec<&str> = Vec::from([
104 "|",
105 "| > Expected a token character.",
106 "| > hint: `42`, `+`, `-`, `/`, `*`, `%`, `^`.",
107 ]);
108
109 Error::indexed_error(inpt, point + 4, message, explanation)
110 }
111
112 pub fn cannot_parse_to_number(input: String, token: Token) -> Self {
124 let message = format!(
125 "error: cannot parse token literal: `{}` to a number\n\n",
126 token.clone().literal.clone()
127 );
128
129 let explanation: Vec<&str> = Vec::from([
131 "|",
132 "| > Cannot convert the character (that represented",
133 "| > as number) to the actual number representation.",
134 ]);
135
136 Error::indexed_error(input, token.index.1 + 1, message, explanation)
137 }
138
139 pub fn invalid_order() -> Self {
141 let space = " ";
142 let mut msg = String::from("error: invalid order of token characters\n");
143
144 msg.push_str(format!("{}A valid token/character order is:", space).as_str());
145 msg.push_str(format!("{}[Numerable], [Operation], [Numerable]", space).as_str());
146
147 Self { msg }
148 }
149
150 pub fn illeagal_token(input: String, token: Token) -> Self {
164 let message = format!(
165 "error: found an illegal character: `{}` \n\n",
166 token.clone().literal
167 );
168
169 let explanation: Vec<&str> = Vec::from([
171 "|",
172 "| > We do not know how to parse this character",
173 "| > If you think this is a bug or a practical feature",
174 "| > that we do not have yet, please open an issue:",
175 "| > -> https://github.com/theiskaa/mate/issues/new",
176 ]);
177
178 Error::indexed_error(input, token.index.1 + 1, message, explanation)
179 }
180
181 pub fn to_string(&self) -> String {
182 self.msg.clone()
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189
190 #[test]
191 fn new() {
192 let result: Error = Error::new(String::from("test message"));
193 assert_eq!(result.msg, String::from("test message"));
194 }
195
196 #[test]
197 fn empty_input() {
198 let result: Error = Error::empty_input();
199 assert_eq!(
200 result.msg,
201 String::from("error: cannot parse an empty input")
202 );
203 }
204
205 #[test]
206 fn empty_tokens() {
207 let result: Error = Error::empty_tokens();
208 assert_eq!(
209 result.msg,
210 String::from("error: cannot calculate result from an empty token list")
211 );
212 }
213
214 #[test]
215 fn to_string() {
216 let error: Error = Error::new(String::from("A new message"));
217 assert_eq!(error.to_string(), error.msg)
218 }
219}