use std::fmt;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct Esc<T: AsRef<str>>(pub T);
impl<T: AsRef<str>> fmt::Display for Esc<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = self.0.as_ref();
while let Some(pos) = s
.as_bytes()
.iter()
.position(|b| [b'&', b'<', b'>', b'"', b'\''].contains(b))
{
f.write_str(&s[..pos])?;
let escaped = match s.as_bytes()[pos] {
b'&' => "&",
b'<' => "<",
b'>' => ">",
b'"' => """,
b'\'' => "'",
_ => unreachable!("We covered all patterns that match this position"),
};
f.write_str(escaped)?;
s = &s[pos + 1..];
}
f.write_str(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn only_special_chars() {
assert_eq!(Esc("&<>\"'").to_string(), "&<>"'");
}
}