use std::borrow::Cow;
pub fn decode_html_entities(s: &str) -> Cow<'_, str> {
html_escape::decode_html_entities(s)
}
pub fn find_ascii_case_insensitive(haystack: &str, needle: &str) -> Option<usize> {
let n_bytes = needle.as_bytes();
if n_bytes.is_empty() {
return Some(0);
}
if haystack.len() < n_bytes.len() {
return None;
}
haystack
.as_bytes()
.windows(n_bytes.len())
.position(|window| window.eq_ignore_ascii_case(n_bytes))
}
pub fn contains_ascii_case_insensitive(haystack: &str, lowercase_needle: &str) -> bool {
lowercase_needle.is_empty() || find_ascii_case_insensitive(haystack, lowercase_needle).is_some()
}
pub fn ends_with_ascii_case_insensitive(haystack: &str, lowercase_suffix: &str) -> bool {
let h_bytes = haystack.as_bytes();
let s_bytes = lowercase_suffix.as_bytes();
if h_bytes.len() < s_bytes.len() {
return false;
}
h_bytes[h_bytes.len() - s_bytes.len()..].eq_ignore_ascii_case(s_bytes)
}
pub fn is_http_url(s: &str) -> bool {
s.starts_with("http://") || s.starts_with("https://")
}
pub fn format_hex(bytes: &[u8]) -> String {
use std::fmt::Write;
let mut hex = String::with_capacity(bytes.len() * 2);
for b in bytes {
let _ = write!(hex, "{:02x}", b);
}
hex
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_decode_html_entities() {
assert_eq!(decode_html_entities("Hello world"), "Hello world");
assert!(matches!(
decode_html_entities("Hello world"),
Cow::Borrowed(_)
));
assert_eq!(
decode_html_entities("<div>"Hello & welcome"</div>"),
"<div>\"Hello & welcome\"</div>"
);
assert_eq!(
decode_html_entities("It's sunny & warm"),
"It's sunny & warm"
);
}
#[test]
fn test_ascii_case_insensitive() {
assert_eq!(find_ascii_case_insensitive("Hello World", "world"), Some(6));
assert_eq!(find_ascii_case_insensitive("Hello World", "WORLD"), Some(6));
assert_eq!(find_ascii_case_insensitive("Hello", "xyz"), None);
assert!(contains_ascii_case_insensitive("Hello World", "world"));
assert!(!contains_ascii_case_insensitive("Hello World", "xyz"));
assert!(ends_with_ascii_case_insensitive("test.RSS", ".rss"));
assert!(ends_with_ascii_case_insensitive("test.rss", ".RSS"));
assert!(!ends_with_ascii_case_insensitive("test.xml", ".rss"));
assert!(!ends_with_ascii_case_insensitive("rss", ".rss"));
}
#[test]
fn test_is_http_url() {
assert!(is_http_url("http://example.com"));
assert!(is_http_url("https://example.com/feed"));
assert!(!is_http_url("ftp://example.com"));
assert!(!is_http_url("example.com"));
assert!(!is_http_url("/path/to/file"));
}
#[test]
fn test_format_hex() {
assert_eq!(format_hex(&[]), "");
assert_eq!(format_hex(&[0x00, 0x0f, 0x10, 0xff]), "000f10ff");
}
}