#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub(crate) enum CharCase {
Uncased = 0,
Lower = 1,
Upper = 2,
TitleNonGreek = 3,
Digit = 4,
}
impl CharCase {
#[inline]
pub fn is_lowercase_compatible(c: char) -> bool {
!c.is_uppercase() && !Self::is_titlecase_any(c)
}
#[inline]
pub fn is_uppercase_compatible(c: char) -> bool {
!c.is_lowercase() && !Self::is_non_greek_titlecase(c)
}
#[inline]
pub fn is_uppercase_start_compatible(c: char) -> bool {
!c.is_lowercase()
}
pub fn new(c: char) -> Self {
if c.is_ascii_digit() {
Self::Digit
} else if c.is_uppercase() {
Self::Upper
} else if c.is_lowercase() {
Self::Lower
} else {
match Self::is_titlecase(c) {
Some(true) => Self::Upper,
Some(false) => Self::TitleNonGreek,
None => Self::Uncased,
}
}
}
#[inline]
pub fn is_cased(c: char) -> bool {
Self::new(c) != Self::Uncased
}
#[inline]
fn is_titlecase(c: char) -> Option<bool> {
match c {
'\u{01C5}' | '\u{01C8}' | '\u{01CB}' | '\u{01F2}' => Some(false),
'\u{1F88}' | '\u{1F89}' | '\u{1F8A}' | '\u{1F8B}' | '\u{1F8C}' | '\u{1F8D}'
| '\u{1F8E}' | '\u{1F8F}' | '\u{1F98}' | '\u{1F99}' | '\u{1F9A}' | '\u{1F9B}'
| '\u{1F9C}' | '\u{1F9D}' | '\u{1F9E}' | '\u{1F9F}' | '\u{1FA8}' | '\u{1FA9}'
| '\u{1FAA}' | '\u{1FAB}' | '\u{1FAC}' | '\u{1FAD}' | '\u{1FAE}' | '\u{1FAF}'
| '\u{1FBC}' | '\u{1FCC}' | '\u{1FFC}' => Some(true),
_ => None,
}
}
#[inline]
fn is_titlecase_any(c: char) -> bool {
Self::is_titlecase(c).is_some()
}
#[inline]
fn is_non_greek_titlecase(c: char) -> bool {
Self::is_titlecase(c).is_some_and(|g| !g)
}
}