use unicode_normalization::char::is_combining_mark;
use unicode_normalization::UnicodeNormalization;
pub fn normalize(s: &str) -> String {
s.trim()
.to_lowercase()
.nfd()
.filter(|c| !is_combining_mark(*c))
.nfc()
.collect()
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_lowercase() {
assert_eq!(normalize("Hello"), "hello");
}
#[test]
fn test_trim() {
assert_eq!(normalize(" hello "), "hello");
}
#[test]
fn test_both() {
assert_eq!(normalize(" Hello World "), "hello world")
}
#[test]
fn test_strips_acute_accent() {
assert_eq!(normalize("café"), "cafe");
}
#[test]
fn test_strips_tilde() {
assert_eq!(normalize("Ñoño"), "nono");
}
#[test]
fn test_strips_umlaut() {
assert_eq!(normalize("Über"), "uber");
assert_eq!(normalize("naïve"), "naive");
}
#[test]
fn test_strips_multiple_diacritics() {
assert_eq!(normalize("Crème Brûlée"), "creme brulee");
}
#[test]
fn test_no_diacritics_unchanged() {
assert_eq!(normalize("hello world"), "hello world");
}
#[test]
fn test_precomposed_and_decomposed_match() {
let precomposed = "caf\u{00E9}";
let decomposed = "cafe\u{0301}";
assert_eq!(normalize(precomposed), normalize(decomposed));
assert_eq!(normalize(precomposed), "cafe");
}
}