text_fx/
escape.rs

1pub enum EscapeStyle {
2    Trigraph,
3    XML,
4}
5
6pub fn xml_escape_str(s: &str) -> String {
7    let mut o = String::new();
8    for c in s.chars() {
9        match c {
10            '&' => o.push_str("&"),
11            '<' => o.push_str("&lt;"),
12            '>' => o.push_str("&gt;"),
13            '"' => o.push_str("&quot;"),
14            _ => o.push(c),
15        }
16    }
17    o
18}
19
20fn escape_trigraphs(p: &str) -> String {
21    let data = p.as_bytes();
22    let mut s = Vec::new();
23    let mut i = 0;
24    let len = data.len();
25    while i < len {
26        if i + 2 < len && data[i] == b'?' && data[i + 1] == b'?' {
27            match data[i + 2] {
28                b'!' | b'\'' | b'(' | b')' | b'-' | b'/' | b'<' | b'=' | b'>' => {
29                    i += 2;
30                    s.push(b'?');
31                    s.push(b'"');
32                    s.push(b'"');
33                    s.push(b'?');
34                    continue;
35                }
36                _ => {}
37            }
38        }
39        s.push(data[i]);
40        i += 1;
41    }
42    String::from_utf8(s).unwrap()
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn test_escape() {
51        let s = "∃¬∩∪∀";
52        let p = escape_trigraphs(s);
53        assert_eq!(s, p);
54        let s = r#"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"#;
55        let expected = r#"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081?""?!"#;
56        let p = escape_trigraphs(s);
57        assert_eq!(expected, p);
58    }
59}