Skip to main content

lextrail_test/
helpers.rs

1use std::collections::VecDeque;
2use std::{env, fmt};
3
4use crate::build::{SymbolGraph, UUId};
5
6pub struct TrailError(pub String);
7
8impl fmt::Debug for TrailError {
9    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10        write!(f, "\n{}", self.0)
11    }
12}
13
14impl fmt::Display for TrailError {
15    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16        write!(f, "{}", self.0)
17    }
18}
19
20impl std::error::Error for TrailError {}
21
22pub fn consume_lexeme(lexemes: &mut Vec<String>, accumulate: &mut Vec<char>) {
23    if accumulate.len() > 0 {
24        lexemes.push(accumulate.iter().collect());
25        accumulate.clear();
26    }
27}
28
29pub fn is_escaped(unicodes: &Vec<char>, index: usize) -> bool {
30    let mut count: i32 = 0;
31    let mut index: i32 = index as i32 - 1;
32
33    while index >= 0 && unicodes[index as usize] == '\\' {
34        count += 1;
35        index -= 1;
36    }
37
38    return count % 2 == 1;
39}
40
41pub fn peek(unicodes: &Vec<char>, index: usize, offset: i32) -> char {
42    let result = index as i32 + offset;
43    if 0 <= result && (result as usize) < unicodes.len() {
44        return unicodes[result as usize];
45    } else {
46        return '\0';
47    }
48}
49
50pub fn get_env(key: &str, default: bool) -> bool {
51    return env::var(key)
52        .ok()
53        .and_then(|s| s.parse::<i32>().ok())
54        .map(|n| n != 0)
55        .unwrap_or(default);
56}
57
58pub fn contains_special_characters(head: &str) -> bool {
59    return head.chars().any(|c| "[@!#$%^&*()<>?/\\|}~:".contains(c));
60}
61
62pub fn bfs<'a>(graph: &'a SymbolGraph, start: Vec<UUId>) -> Vec<UUId> {
63    let mut visited: Vec<UUId> = Vec::new();
64    let mut queue: VecDeque<UUId> = start.into_iter().collect();
65
66    while !queue.is_empty() {
67        let vertex = queue.pop_front().unwrap();
68
69        if !visited.contains(&vertex) {
70            visited.push(vertex);
71
72            let successors = graph.edges.get(&vertex).cloned().unwrap_or_default();
73            queue.extend(successors);
74        }
75    }
76
77    return visited;
78}
79
80pub fn format_error(header: &str, context: &str, source: &str) -> String {
81    const RED: &str = "\x1b[31m";
82    const BLUE: &str = "\x1b[34m";
83    const YELLOW: &str = "\x1b[33m";
84    const BOLD: &str = "\x1b[1m";
85    const RESET: &str = "\x1b[0m";
86
87    let markers = (".".repeat(context.len()), "^".repeat(source.len()));
88
89    format!(
90        "{BOLD}{RED}error{RESET}: {header}\n\
91         {BOLD}{BLUE}  |{RESET}\n\
92         {BOLD}{BLUE}  |{RESET} {context}{source}\n\
93         {BOLD}{BLUE}  |{RESET} {BOLD}{YELLOW}{}{BOLD}{RED}{}{RESET}",
94        markers.0, markers.1,
95    )
96}