use crate::error::CompileErrorKind;
use crate::grapheme::JoiningForm;
use icu_properties::props::JoiningGroup;
use icu_properties::{PropertyNamesLong, PropertyParser};
pub(crate) struct RasmClass {
pub(crate) groups: &'static [JoiningGroup],
pub(crate) forms: &'static [JoiningForm],
}
pub(crate) const RASM_CLASSES: &[RasmClass] = &[
RasmClass {
groups: &[
JoiningGroup::Beh,
JoiningGroup::Noon,
JoiningGroup::AfricanNoon,
JoiningGroup::Nya,
JoiningGroup::Yeh,
JoiningGroup::FarsiYeh,
],
forms: &[JoiningForm::Initial, JoiningForm::Medial],
},
RasmClass {
groups: &[
JoiningGroup::Feh,
JoiningGroup::AfricanFeh,
JoiningGroup::Qaf,
JoiningGroup::AfricanQaf,
],
forms: &[JoiningForm::Initial, JoiningForm::Medial],
},
RasmClass {
groups: &[JoiningGroup::Feh, JoiningGroup::AfricanFeh],
forms: &[JoiningForm::Final, JoiningForm::Isolated],
},
RasmClass {
groups: &[JoiningGroup::Qaf, JoiningGroup::AfricanQaf],
forms: &[JoiningForm::Final, JoiningForm::Isolated],
},
RasmClass {
groups: &[
JoiningGroup::Heh,
JoiningGroup::HehGoal,
JoiningGroup::TehMarbuta,
JoiningGroup::TehMarbutaGoal,
],
forms: &[JoiningForm::Final, JoiningForm::Isolated],
},
RasmClass {
groups: &[
JoiningGroup::Noon,
JoiningGroup::AfricanNoon,
JoiningGroup::Nya,
],
forms: &[JoiningForm::Final, JoiningForm::Isolated],
},
RasmClass {
groups: &[
JoiningGroup::Yeh,
JoiningGroup::FarsiYeh,
JoiningGroup::YehWithTail,
],
forms: &[JoiningForm::Final, JoiningForm::Isolated],
},
RasmClass {
groups: &[JoiningGroup::YehBarree, JoiningGroup::BurushaskiYehBarree],
forms: &[JoiningForm::Final, JoiningForm::Isolated],
},
RasmClass {
groups: &[JoiningGroup::Kaf, JoiningGroup::Gaf],
forms: &[JoiningForm::Initial, JoiningForm::Medial],
},
];
pub(crate) fn rasm_matches(
token_group: JoiningGroup,
grapheme_group: JoiningGroup,
form: JoiningForm,
) -> bool {
if token_group == grapheme_group {
return true;
}
for cls in RASM_CLASSES {
if !cls.forms.contains(&form) {
continue;
}
if cls.groups.contains(&token_group) && cls.groups.contains(&grapheme_group) {
return true;
}
}
false
}
pub(crate) fn resolve_group_name(name: &str) -> Result<JoiningGroup, CompileErrorKind> {
let unknown = || CompileErrorKind::UnknownGroupName(name.to_string());
let bare = name.strip_prefix(['@', '=']).ok_or_else(unknown)?;
let parser = PropertyParser::<JoiningGroup>::new();
let long = PropertyNamesLong::<JoiningGroup>::new();
match parser.get_strict(bare) {
Some(group) if group != JoiningGroup::NoJoiningGroup && long.get(group) == Some(bare) => {
Ok(group)
}
_ => Err(unknown()),
}
}