#[allow(unused_imports)] use std::ascii::AsciiExt;
#[inline]
pub fn matches(needle: &str, haystack: &str) -> bool {
if needle == "" || needle == haystack {
return true;
}
let mut hchars = haystack.chars();
needle.chars().all(|n| {
hchars.any(|h| eq(n, h))
})
}
#[inline(always)]
pub fn eq(a: char, b: char) -> bool {
match a {
_ if a == b => true,
_ if a.is_ascii() || b.is_ascii() => a.eq_ignore_ascii_case(&b),
_ => a.to_lowercase().eq(b.to_lowercase())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_eq() {
assert!(eq('a', 'A'));
assert!(eq('山', '山'));
assert!(!eq('a', 'b'));
}
#[test]
fn test_matches() {
assert!(matches("a", "a"));
assert!(matches("a", "abc"));
assert!(matches("abc", "abc"));
assert!(matches("ABC", "abc"));
assert!(matches("abc", "a1b2c3"));
assert!(matches("abc", "a1b2c3"));
assert!(matches("test", "t/e/s/t"));
assert!(matches("test", "t💣e💣s💣t"));
assert!(matches("💣💣💣", "t💣e💣s💣t"));
assert!(!matches("abc", "ab"));
assert!(!matches("abc", "cab"));
assert!(!matches("abc", ""));
assert!(matches("", ""));
assert!(matches("", "ab"));
assert!(matches("a", "A"));
assert!(matches("A", "a"));
assert!(matches("山", "山"));
assert!(matches("café", "CAFÉ"));
assert!(matches("weiß", "WEIẞ"));
assert!(matches("хди́ь", "ХОДИ́ТЬ"));
}
}