misc_conf/
lexer.rs

1//! Common lexer utils
2
3#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
4pub struct Literal<'a> {
5    pub raw: &'a str,
6    pub quote: u8,
7}
8
9impl<'a> std::fmt::Display for Literal<'a> {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        write!(f, "{}", Into::<String>::into(*self))
12    }
13}
14
15// TODO: performance
16
17impl<'a> From<Literal<'a>> for String {
18    fn from(value: Literal<'a>) -> Self {
19        let Literal { raw, quote } = value;
20        let mut s = raw.replace(r#"\\"#, "\\");
21        if quote == b'"' {
22            s = s.replace(r#"\""#, "\"");
23        } else if quote == b'\'' {
24            s = s.replace(r#"\'"#, "'");
25        }
26        s.replace("\\\n", "\n")
27    }
28}
29
30pub fn line_column(data: &[u8], pos: usize) -> (usize, usize) {
31    let mut ln = 1;
32    for line in data.split(|&b| b == b'\n') {
33        let lp = (line.as_ptr() as usize)
34            .checked_sub(data.as_ptr() as usize)
35            .expect("sub ptr");
36        if (lp..=lp + line.len()).contains(&pos) {
37            return (ln, pos - lp);
38        }
39        ln += 1;
40    }
41    (ln, 0)
42}
43
44pub fn line_column2(data: &[u8], err: &[u8]) -> Option<((usize, usize), usize)> {
45    let pos = (err.as_ptr() as usize).checked_sub(data.as_ptr() as usize)?;
46    Some((line_column(data, pos), pos))
47}