use unicode_general_category::{GeneralCategory, get_general_category};
pub fn is_alpha(c: char) -> bool {
matches!(
get_general_category(c),
GeneralCategory::UppercaseLetter
| GeneralCategory::LowercaseLetter
| GeneralCategory::TitlecaseLetter
| GeneralCategory::ModifierLetter
| GeneralCategory::OtherLetter
)
}
pub fn is_upper(c: char) -> bool {
matches!(
get_general_category(c),
GeneralCategory::UppercaseLetter | GeneralCategory::TitlecaseLetter
)
}
pub fn is_lower(c: char) -> bool {
get_general_category(c) == GeneralCategory::LowercaseLetter
}
pub fn is_alpha_num(c: char) -> bool {
is_alpha(c)
|| matches!(
get_general_category(c),
GeneralCategory::DecimalNumber
| GeneralCategory::LetterNumber
| GeneralCategory::OtherNumber
)
}
pub const fn is_oct_digit(c: char) -> bool {
matches!(c, '0'..='7')
}
pub fn is_space(c: char) -> bool {
let u = c as u32;
if u <= 0x377 {
u == 32 || (9..=13).contains(&u) || u == 0xa0
} else {
get_general_category(c) == GeneralCategory::SpaceSeparator
}
}
pub fn is_print(c: char) -> bool {
!matches!(
get_general_category(c),
GeneralCategory::Control
| GeneralCategory::Format
| GeneralCategory::LineSeparator
| GeneralCategory::ParagraphSeparator
| GeneralCategory::Surrogate
| GeneralCategory::PrivateUse
| GeneralCategory::Unassigned
)
}
pub fn to_lower(c: char) -> char {
let mut it = c.to_lowercase();
match (it.next(), it.next()) {
(Some(l), None) => l,
(Some(l), Some(_)) if c == '\u{130}' => l,
_ => c,
}
}
pub fn to_upper(c: char) -> char {
let mut it = c.to_uppercase();
match (it.next(), it.next()) {
(Some(u), None) => u,
_ => c,
}
}
pub fn lower_string(s: &str) -> String {
s.chars().map(to_lower).collect()
}