pub enum EscapeStyle {
Trigraph,
XML,
}
pub fn xml_escape_str(s: &str) -> String {
let mut o = String::new();
for c in s.chars() {
match c {
'&' => o.push_str("&"),
'<' => o.push_str("<"),
'>' => o.push_str(">"),
'"' => o.push_str("""),
_ => o.push(c),
}
}
o
}
fn escape_trigraphs(p: &str) -> String {
let data = p.as_bytes();
let mut s = Vec::new();
let mut i = 0;
let len = data.len();
while i < len {
if i + 2 < len && data[i] == b'?' && data[i + 1] == b'?' {
match data[i + 2] {
b'!' | b'\'' | b'(' | b')' | b'-' | b'/' | b'<' | b'=' | b'>' => {
i += 2;
s.push(b'?');
s.push(b'"');
s.push(b'"');
s.push(b'?');
continue;
}
_ => {}
}
}
s.push(data[i]);
i += 1;
}
String::from_utf8(s).unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_escape() {
let s = "∃¬∩∪∀";
let p = escape_trigraphs(s);
assert_eq!(s, p);
let s = r#"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"#;
let expected = r#"\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081?""?!"#;
let p = escape_trigraphs(s);
assert_eq!(expected, p);
}
}