use std::borrow::Cow;
const fn is_non_ascii_zs(c: char) -> bool {
matches!(
c,
'\u{00A0}' | '\u{1680}' | '\u{2000}'
..='\u{200A}' | '\u{202F}' | '\u{205F}' | '\u{3000}' )
}
pub fn normalize_space_separators(s: &str) -> Cow<'_, str> {
if !s.chars().any(is_non_ascii_zs) {
return Cow::Borrowed(s);
}
Cow::Owned(
s.chars()
.map(|c| if is_non_ascii_zs(c) { ' ' } else { c })
.collect(),
)
}
pub fn remove_space_separators(s: &str) -> Cow<'_, str> {
if !s.chars().any(is_non_ascii_zs) {
return Cow::Borrowed(s);
}
Cow::Owned(s.chars().filter(|&c| !is_non_ascii_zs(c)).collect())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_change_when_no_zs() {
let s = "C D\n\t";
let c = normalize_space_separators(s);
assert!(matches!(c, Cow::Borrowed(_)));
assert_eq!(c.as_ref(), s);
}
#[test]
fn nnbsp_nbsp_ideograph_space_to_ascii() {
let s = format!("A\u{00A0}B\u{202F}C\u{3000}D");
let t = normalize_space_separators(&s);
assert_eq!(t.as_ref(), "A B C D");
}
#[test]
fn medium_mathematical_space() {
assert_eq!(normalize_space_separators("So\u{205f}pl").as_ref(), "So pl");
}
#[test]
fn remove_mms_between_letters() {
assert_eq!(remove_space_separators("C\u{205F}#"), "C#");
}
}