1#[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
15impl<'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}