use std::sync::OnceLock;
use icu_properties::props::{GeneralCategory, Script};
use icu_properties::{
props, CodePointMapData, CodePointMapDataBorrowed, CodePointSetData, CodePointSetDataBorrowed,
};
static DEFAULT_IGNORABLES: OnceLock<CodePointSetDataBorrowed<'static>> = OnceLock::new();
static EMOJI_SET: OnceLock<CodePointSetDataBorrowed<'static>> = OnceLock::new();
static SCRIPT_MAP: OnceLock<CodePointMapDataBorrowed<'static, Script>> = OnceLock::new();
static GENERAL_CATEGORY_MAP: OnceLock<CodePointMapDataBorrowed<'static, GeneralCategory>> =
OnceLock::new();
fn script(c: char) -> Script {
SCRIPT_MAP
.get_or_init(CodePointMapData::<Script>::new)
.get(c)
}
fn general_category(c: char) -> GeneralCategory {
GENERAL_CATEGORY_MAP
.get_or_init(CodePointMapData::<GeneralCategory>::new)
.get(c)
}
pub(crate) fn is_latin_script(c: char) -> bool {
script(c) == Script::Latin
}
pub(crate) fn is_control_char(c: char) -> bool {
general_category(c) == GeneralCategory::Control
}
pub(crate) fn is_common_symbol_or_punctuation(c: char) -> bool {
matches!(script(c), Script::Common | Script::Inherited)
&& matches!(
general_category(c),
GeneralCategory::MathSymbol
| GeneralCategory::CurrencySymbol
| GeneralCategory::ModifierSymbol
| GeneralCategory::OtherSymbol
| GeneralCategory::DashPunctuation
| GeneralCategory::OpenPunctuation
| GeneralCategory::ClosePunctuation
| GeneralCategory::InitialPunctuation
| GeneralCategory::FinalPunctuation
| GeneralCategory::OtherPunctuation
| GeneralCategory::OtherNumber
| GeneralCategory::ModifierLetter
| GeneralCategory::SpaceSeparator
| GeneralCategory::LineSeparator
| GeneralCategory::ParagraphSeparator
)
}
pub fn is_hidden_char(c: char) -> bool {
DEFAULT_IGNORABLES
.get_or_init(CodePointSetData::new::<props::DefaultIgnorableCodePoint>)
.contains(c)
}
pub fn is_keyboard_ascii(c: char) -> bool {
matches!(c, '\n' | '\r' | '\t') || (c.is_ascii() && !c.is_ascii_control())
}
pub fn is_extended_keyboard_char(c: char) -> bool {
matches!(
c,
'€' | '£' | '¥' | '¢' | '§' | '°' | '±' | '×' | '÷' | '–' | '—' | '…' | '•' | '·'
)
}
pub fn is_emoji(c: char) -> bool {
EMOJI_SET
.get_or_init(CodePointSetData::new::<props::Emoji>)
.contains(c)
}