#[must_use]
pub fn html_escape(s: &str) -> String {
s.replace('&', "&")
.replace('<', "<")
.replace('>', ">")
.replace('"', """)
.replace('\'', "'")
}
#[must_use]
pub fn slugify(text: &str) -> String {
text.to_lowercase()
.chars()
.map(|c| {
if c.is_alphanumeric() {
c
} else if c.is_whitespace() || c == '-' || c == '_' {
'-'
} else {
'\0'
}
})
.filter(|c| *c != '\0')
.collect::<String>()
.split('-')
.filter(|s| !s.is_empty())
.collect::<Vec<_>>()
.join("-")
}
#[must_use]
pub fn strip_html(html: &str) -> String {
let mut result = String::with_capacity(html.len());
let mut in_tag = false;
let mut in_script = false;
let mut in_style = false;
let html_lower = html.to_lowercase();
let chars: Vec<char> = html.chars().collect();
let chars_lower: Vec<char> = html_lower.chars().collect();
let mut i = 0;
while i < chars.len() {
let c = chars[i];
if i + 7 < chars.len() {
let next_7: String = chars_lower[i..i + 7].iter().collect();
if next_7 == "<script" {
in_script = true;
} else if next_7 == "</scrip" {
in_script = false;
}
}
if i + 6 < chars.len() {
let next_6: String = chars_lower[i..i + 6].iter().collect();
if next_6 == "<style" {
in_style = true;
} else if next_6 == "</styl" {
in_style = false;
}
}
if c == '<' {
in_tag = true;
} else if c == '>' {
in_tag = false;
} else if !in_tag && !in_script && !in_style {
result.push(c);
}
i += 1;
}
result = result
.replace(" ", " ")
.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace(""", "\"")
.replace("'", "'");
let mut collapsed = String::with_capacity(result.len());
let mut prev_space = false;
for c in result.chars() {
if c.is_whitespace() {
if !prev_space {
collapsed.push(' ');
prev_space = true;
}
} else {
collapsed.push(c);
prev_space = false;
}
}
collapsed.trim().to_string()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_html_escape() {
assert_eq!(html_escape("a & b"), "a & b");
assert_eq!(html_escape("<div>"), "<div>");
assert_eq!(html_escape(r#"a "b" c"#), "a "b" c");
assert_eq!(html_escape("it's"), "it's");
}
#[test]
fn test_slugify() {
assert_eq!(slugify("Hello World"), "hello-world");
assert_eq!(slugify("foo_bar"), "foo-bar");
assert_eq!(slugify(" multiple spaces "), "multiple-spaces");
assert_eq!(slugify("special!@#chars"), "specialchars");
}
#[test]
fn test_strip_html() {
assert_eq!(strip_html("<p>Hello</p>"), "Hello");
assert_eq!(strip_html("<script>alert(1)</script>"), "");
assert_eq!(
strip_html("<b>bold</b> and <i>italic</i>"),
"bold and italic"
);
assert_eq!(strip_html("a & b"), "a & b");
assert_eq!(
strip_html(" multiple <br> spaces "),
"multiple spaces"
);
}
}