-
Notifications
You must be signed in to change notification settings - Fork 15
/
escape.rs
48 lines (45 loc) · 1.26 KB
/
escape.rs
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
pub fn escape(str: &str, writer: &mut impl std::fmt::Write) -> std::fmt::Result {
let mut last = 0;
for (index, byte) in str.bytes().enumerate() {
macro_rules! go {
($expr:expr) => {{
writer.write_str(&str[last..index])?;
writer.write_str($expr)?;
last = index + 1;
}};
}
match byte {
b'&' => go!("&"),
b'<' => go!("<"),
b'>' => go!(">"),
b'"' => go!("""),
_ => {}
}
}
writer.write_str(&str[last..])
}
#[test]
fn test() {
t("", "");
t("<", "<");
t("a<", "a<");
t("<b", "<b");
t("a<b", "a<b");
t("a<>b", "a<>b");
t("<>", "<>");
t("≤", "≤");
t("a≤", "a≤");
t("≤b", "≤b");
t("a≤b", "a≤b");
t("a≤≥b", "a≤≥b");
t("≤≥", "≤≥");
t(
r#"foo &<>" bar&bar<bar>bar"bar baz&&<<baz>>""baz"#,
r#"foo &<>" bar&bar<bar>bar"bar baz&&<<baz>>""baz"#,
);
fn t(input: &str, output: &str) {
let mut string = String::new();
escape(input, &mut string).unwrap();
assert_eq!(string, output);
}
}