use super::arabic::JoiningForm;
pub fn presentation_form(base: char, form: JoiningForm) -> Option<char> {
let cp = base as u32;
let (isol, fina, init, medi) = forms_for(cp)?;
let chosen = match form {
JoiningForm::Isol => Some(isol),
JoiningForm::Fina => fina,
JoiningForm::Init => init,
JoiningForm::Medi => medi,
}?;
char::from_u32(chosen)
}
type PfFormSet = (u32, Option<u32>, Option<u32>, Option<u32>);
fn forms_for(cp: u32) -> Option<PfFormSet> {
match cp {
0x0621 => Some((0xFE80, None, None, None)),
0x0622 => Some((0xFE81, Some(0xFE82), None, None)),
0x0623 => Some((0xFE83, Some(0xFE84), None, None)),
0x0624 => Some((0xFE85, Some(0xFE86), None, None)),
0x0625 => Some((0xFE87, Some(0xFE88), None, None)),
0x0626 => Some((0xFE89, Some(0xFE8A), Some(0xFE8B), Some(0xFE8C))),
0x0627 => Some((0xFE8D, Some(0xFE8E), None, None)),
0x0628 => Some((0xFE8F, Some(0xFE90), Some(0xFE91), Some(0xFE92))),
0x0629 => Some((0xFE93, Some(0xFE94), None, None)),
0x062A => Some((0xFE95, Some(0xFE96), Some(0xFE97), Some(0xFE98))),
0x062B => Some((0xFE99, Some(0xFE9A), Some(0xFE9B), Some(0xFE9C))),
0x062C => Some((0xFE9D, Some(0xFE9E), Some(0xFE9F), Some(0xFEA0))),
0x062D => Some((0xFEA1, Some(0xFEA2), Some(0xFEA3), Some(0xFEA4))),
0x062E => Some((0xFEA5, Some(0xFEA6), Some(0xFEA7), Some(0xFEA8))),
0x062F => Some((0xFEA9, Some(0xFEAA), None, None)),
0x0630 => Some((0xFEAB, Some(0xFEAC), None, None)),
0x0631 => Some((0xFEAD, Some(0xFEAE), None, None)),
0x0632 => Some((0xFEAF, Some(0xFEB0), None, None)),
0x0633 => Some((0xFEB1, Some(0xFEB2), Some(0xFEB3), Some(0xFEB4))),
0x0634 => Some((0xFEB5, Some(0xFEB6), Some(0xFEB7), Some(0xFEB8))),
0x0635 => Some((0xFEB9, Some(0xFEBA), Some(0xFEBB), Some(0xFEBC))),
0x0636 => Some((0xFEBD, Some(0xFEBE), Some(0xFEBF), Some(0xFEC0))),
0x0637 => Some((0xFEC1, Some(0xFEC2), Some(0xFEC3), Some(0xFEC4))),
0x0638 => Some((0xFEC5, Some(0xFEC6), Some(0xFEC7), Some(0xFEC8))),
0x0639 => Some((0xFEC9, Some(0xFECA), Some(0xFECB), Some(0xFECC))),
0x063A => Some((0xFECD, Some(0xFECE), Some(0xFECF), Some(0xFED0))),
0x0641 => Some((0xFED1, Some(0xFED2), Some(0xFED3), Some(0xFED4))),
0x0642 => Some((0xFED5, Some(0xFED6), Some(0xFED7), Some(0xFED8))),
0x0643 => Some((0xFED9, Some(0xFEDA), Some(0xFEDB), Some(0xFEDC))),
0x0644 => Some((0xFEDD, Some(0xFEDE), Some(0xFEDF), Some(0xFEE0))),
0x0645 => Some((0xFEE1, Some(0xFEE2), Some(0xFEE3), Some(0xFEE4))),
0x0646 => Some((0xFEE5, Some(0xFEE6), Some(0xFEE7), Some(0xFEE8))),
0x0647 => Some((0xFEE9, Some(0xFEEA), Some(0xFEEB), Some(0xFEEC))),
0x0648 => Some((0xFEED, Some(0xFEEE), None, None)),
0x0649 => Some((0xFEEF, Some(0xFEF0), None, None)),
0x064A => Some((0xFEF1, Some(0xFEF2), Some(0xFEF3), Some(0xFEF4))),
0x0640 => Some((0x0640, None, None, None)),
_ => None,
}
}
#[cfg(test)]
#[allow(non_snake_case)] mod tests {
use super::*;
#[test]
fn beh_isolated_maps_to_FE8F() {
assert_eq!(
presentation_form('\u{0628}', JoiningForm::Isol),
Some('\u{FE8F}')
);
}
#[test]
fn beh_initial_maps_to_FE91() {
assert_eq!(
presentation_form('\u{0628}', JoiningForm::Init),
Some('\u{FE91}')
);
}
#[test]
fn beh_medial_maps_to_FE92() {
assert_eq!(
presentation_form('\u{0628}', JoiningForm::Medi),
Some('\u{FE92}')
);
}
#[test]
fn beh_final_maps_to_FE90() {
assert_eq!(
presentation_form('\u{0628}', JoiningForm::Fina),
Some('\u{FE90}')
);
}
#[test]
fn alef_initial_falls_back_to_isol_form() {
assert_eq!(presentation_form('\u{0627}', JoiningForm::Init), None);
}
#[test]
fn alef_final_maps_to_FE8E() {
assert_eq!(
presentation_form('\u{0627}', JoiningForm::Fina),
Some('\u{FE8E}')
);
}
#[test]
fn lam_all_four_forms() {
assert_eq!(
presentation_form('\u{0644}', JoiningForm::Isol),
Some('\u{FEDD}')
);
assert_eq!(
presentation_form('\u{0644}', JoiningForm::Fina),
Some('\u{FEDE}')
);
assert_eq!(
presentation_form('\u{0644}', JoiningForm::Init),
Some('\u{FEDF}')
);
assert_eq!(
presentation_form('\u{0644}', JoiningForm::Medi),
Some('\u{FEE0}')
);
}
#[test]
fn unmapped_codepoint_returns_none() {
assert_eq!(presentation_form('A', JoiningForm::Isol), None);
}
}