#[cfg(feature = "i18n")]
pub fn fold_case(s: &str) -> String {
use icu_casemap::CaseMapper;
let cm = CaseMapper::new();
cm.fold_string(s).into_owned()
}
#[cfg(not(feature = "i18n"))]
pub fn fold_case(s: &str) -> String {
s.to_ascii_lowercase()
}
#[cfg(feature = "i18n")]
pub fn normalize_nfc(s: &str) -> String {
use icu_normalizer::ComposingNormalizer;
let normalizer = ComposingNormalizer::new_nfc();
normalizer.normalize(s).into_owned()
}
#[cfg(not(feature = "i18n"))]
pub fn normalize_nfc(s: &str) -> String {
s.to_string()
}
#[must_use]
pub fn is_cjk(ch: char) -> bool {
matches!(
ch,
'\u{4E00}'..='\u{9FFF}'
| '\u{3400}'..='\u{4DBF}'
| '\u{F900}'..='\u{FAFF}'
| '\u{3040}'..='\u{309F}'
| '\u{30A0}'..='\u{30FF}'
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn fold_case_ascii_unchanged() {
assert_eq!(fold_case("Hello"), "hello");
assert_eq!(fold_case("PARSE"), "parse");
}
#[cfg(feature = "i18n")]
#[test]
fn fold_case_german_sharp_s() {
assert_eq!(fold_case("Straße"), "strasse");
}
#[cfg(feature = "i18n")]
#[test]
fn fold_case_turkish_i_with_dot() {
let result = fold_case("İ");
assert_eq!(result, "i\u{0307}");
}
#[test]
fn fold_case_empty_string() {
assert_eq!(fold_case(""), "");
}
#[test]
fn fold_case_already_lowercase() {
assert_eq!(fold_case("hello"), "hello");
}
#[test]
fn fold_case_cjk_unchanged() {
assert_eq!(fold_case("你好"), "你好");
assert_eq!(fold_case("こんにちは"), "こんにちは");
}
#[test]
fn normalize_nfc_already_normalized() {
assert_eq!(normalize_nfc("hello"), "hello");
}
#[cfg(feature = "i18n")]
#[test]
fn normalize_nfc_decomposed_to_composed() {
let nfd = "e\u{0301}";
let nfc = normalize_nfc(nfd);
assert_eq!(nfc, "\u{00E9}");
assert_ne!(nfd, nfc);
}
#[test]
fn normalize_nfc_empty_string() {
assert_eq!(normalize_nfc(""), "");
}
#[test]
fn normalize_nfc_ascii_unchanged() {
assert_eq!(normalize_nfc("parse_file"), "parse_file");
}
#[test]
fn normalize_nfc_cjk_unchanged() {
assert_eq!(normalize_nfc("你好"), "你好");
}
#[test]
fn is_cjk_basic_ideograph() {
assert!(is_cjk('你'));
assert!(is_cjk('好'));
assert!(is_cjk('世'));
assert!(is_cjk('界'));
}
#[test]
fn is_cjk_extension_a() {
assert!(is_cjk('\u{3500}'));
assert!(is_cjk('\u{3400}'));
assert!(is_cjk('\u{4DBF}'));
}
#[test]
fn is_cjk_hiragana() {
assert!(is_cjk('あ')); assert!(is_cjk('い')); }
#[test]
fn is_cjk_ascii_false() {
assert!(!is_cjk('a'));
assert!(!is_cjk('Z'));
assert!(!is_cjk('0'));
assert!(!is_cjk('_'));
}
}