use std::fmt::{self, Display, Write};
pub struct HtmlEscaped<T>(pub T);
impl<T: Display> Display for HtmlEscaped<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = self.0.to_string();
for c in s.chars() {
match c {
'&' => f.write_str("&")?,
'<' => f.write_str("<")?,
'>' => f.write_str(">")?,
'"' => f.write_str(""")?,
'\'' => f.write_str("'")?,
_ => f.write_char(c)?,
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_escapes_html_characters() {
assert_eq!(
format!("{}", HtmlEscaped("User <admin> & \"root's\"")),
"User <admin> & "root's""
);
}
#[test]
fn test_escapes_script_tag() {
assert_eq!(
format!("{}", HtmlEscaped("<script>alert('xss')</script>")),
"<script>alert('xss')</script>"
);
}
#[test]
fn test_preserves_normal_text() {
assert_eq!(
format!("{}", HtmlEscaped("/path/to/file.txt")),
"/path/to/file.txt"
);
}
}