leap_lang/parser/
patherror.rs

1use std::fs;
2
3#[derive(Debug)]
4pub struct PathError {
5    pub error: String,
6    pub path: String,
7    pub position: usize,
8}
9
10impl PathError {
11    pub fn new(error: String, path: String, position: usize) -> Self {
12        Self {
13            error,
14            path,
15            position,
16        }
17    }
18
19    pub fn error_report(&self) -> String {
20        // file path, line number, position in line
21        let error_line = self.get_error_line();
22        match error_line {
23            Some((l, p, line)) => {
24                let arrow_padding = String::from_utf8(vec![b' '; p]).unwrap();
25                // use 1-based indexing for line number
26                let l = l + 1;
27                format!(
28                    "{}:{}:{}\n     |\n{:>4} |{}\n     |{}^---\n\n{}",
29                    self.path, l, p, l, line, arrow_padding, self.error
30                )
31            }
32            None => format!("{}\n{}", self.path, self.error),
33        }
34    }
35
36    fn get_error_line(&self) -> Option<(usize, usize, String)> {
37        if let Ok(s) = fs::read_to_string(&self.path) {
38            let mut position: usize = 0;
39
40            for (n, line) in s.split('\n').enumerate() {
41                if self.position <= position + line.len() + 1 {
42                    return Some((n, self.position - position, line.to_owned()));
43                }
44                position += line.len() + 1;
45            }
46        }
47        None
48    }
49}