pub(crate) fn escape_text(s: &str, output: &mut Vec<u8>) {
for b in s.bytes() {
match b {
b'&' => output.extend_from_slice(b"&"),
b'<' => output.extend_from_slice(b"<"),
b'>' => output.extend_from_slice(b">"),
b'\r' => output.extend_from_slice(b"
"),
_ => output.push(b),
}
}
}
pub(crate) fn escape_attr(s: &str, output: &mut Vec<u8>) {
for b in s.bytes() {
match b {
b'&' => output.extend_from_slice(b"&"),
b'<' => output.extend_from_slice(b"<"),
b'"' => output.extend_from_slice(b"""),
b'\t' => output.extend_from_slice(b"	"),
b'\n' => output.extend_from_slice(b"
"),
b'\r' => output.extend_from_slice(b"
"),
_ => output.push(b),
}
}
}
pub(crate) fn escape_cr(s: &str, output: &mut Vec<u8>) {
for b in s.bytes() {
match b {
b'\r' => output.extend_from_slice(b"
"),
_ => output.push(b),
}
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn text_escaping() {
let mut out = Vec::new();
escape_text("a < b & c > d\r\n", &mut out);
assert_eq!(
String::from_utf8(out).expect("valid utf8"),
"a < b & c > d
\n"
);
}
#[test]
fn attr_escaping() {
let mut out = Vec::new();
escape_attr("he said \"hi\" & \t\n\r", &mut out);
assert_eq!(
String::from_utf8(out).expect("valid utf8"),
"he said "hi" & 	

"
);
}
#[test]
fn passthrough_plain_text() {
let mut out = Vec::new();
escape_text("hello world", &mut out);
assert_eq!(String::from_utf8(out).expect("valid utf8"), "hello world");
}
}