1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use crate::AST;
use std::{char, iter::Iterator, str};
pub fn string_refine(h: &str, text: &str) -> AST {
let data = text.to_string();
return match h {
"" => AST::String(data),
_ => AST::StringLiteral { handler: h.to_string(), data },
};
}
pub fn unescape(s: &str) -> String {
let mut chars = s.chars().enumerate();
let mut res = String::with_capacity(s.len());
while let Some((_, c)) = chars.next() {
if c == '\\' {
match chars.next() {
None => ' ',
Some((_, c2)) => {
res.push(match c2 {
'a' => '\u{07}',
'b' => '\u{08}',
'v' => '\u{0B}',
'f' => '\u{0C}',
'n' => '\n',
'r' => '\r',
't' => '\t',
'e' | 'E' => '\u{1B}',
'\\' => '\\',
'\'' => '\'',
'"' => '"',
'$' => '$',
'`' => '`',
' ' => ' ',
'u' => match parse_unicode(&mut chars) {
Ok(c3) => c3,
Err(_) => ' ',
},
_ => ' ',
});
continue;
}
};
}
res.push(c);
}
return res;
}
#[rustfmt::skip]
pub fn parse_unicode<I>(chars: &mut I) -> Result<char, String>
where
I: Iterator<Item = (usize, char)>,
{
match chars.next() {
Some((_, '{')) => {}
_ => {
return Err("expected '{{' character in unicode escape".to_string());
}
}
let unicode_seq: String = chars
.take_while(|&(_, c)| c != '}')
.map(|(_, c)| c)
.collect();
u32::from_str_radix(&unicode_seq, 16)
.map_err(|e| format!("could not parse {} as u32 hex: {}", unicode_seq, e))
.and_then(|u| char::from_u32(u).ok_or_else(|| format!("could not parse {} as a unicode char", u)))
}