use std::borrow::Cow;
pub fn attribute(raw: &[u8]) -> Cow<'_, [u8]> {
_escape(raw, |ch| matches!(ch, b'<' | b'>' | b'&' | b'\'' | b'\"'))
}
pub fn text(raw: &[u8]) -> Cow<'_, [u8]> {
_escape(raw, |ch| matches!(ch, b'<' | b'>' | b'&'))
}
pub(crate) fn _escape<F: Fn(u8) -> bool>(bytes: &[u8], escape_chars: F) -> Cow<'_, [u8]> {
let mut escaped = None;
let mut iter = bytes.iter();
let mut pos = 0;
while let Some(i) = iter.position(|&b| escape_chars(b)) {
if escaped.is_none() {
escaped = Some(Vec::with_capacity(bytes.len() + 20));
}
let escaped = escaped.as_mut().expect("initialized");
let new_pos = pos + i;
escaped.extend_from_slice(&bytes[pos..new_pos]);
match bytes[new_pos] {
b'<' => escaped.extend_from_slice(b"<"),
b'>' => escaped.extend_from_slice(b">"),
b'\'' => escaped.extend_from_slice(b"'"),
b'&' => escaped.extend_from_slice(b"&"),
b'"' => escaped.extend_from_slice(b"""),
b'\t' => escaped.extend_from_slice(b"	"),
b'\n' => escaped.extend_from_slice(b" "),
b'\r' => escaped.extend_from_slice(b" "),
b' ' => escaped.extend_from_slice(b" "),
_ => unreachable!("Only '<', '>','\', '&', '\"', '\\t', '\\r', '\\n', and ' ' are escaped"),
}
pos = new_pos + 1;
}
if let Some(mut escaped) = escaped {
if let Some(raw) = bytes.get(pos..) {
escaped.extend_from_slice(raw);
}
Cow::Owned(escaped)
} else {
Cow::Borrowed(bytes)
}
}