use std::cmp::Ordering;
use composition::canonical_decomposition;
use hangul;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(missing_docs)]
pub enum DecompositionType {
Canonical, Compat, Circle, Final, Font, Fraction, Initial, Isolated, Medial, Narrow, Nobreak, None, Small, Square, Sub, Super, Vertical, Wide, }
use self::DecompositionType::*;
const COMPATIBILITY_DECOMPOSITION_TYPE_TABLE: &'static [(char, char, DecompositionType)] =
include!("tables/compatibility_decomposition_type_values.rsv");
impl DecompositionType {
pub fn of(ch: char) -> Option<DecompositionType> {
if hangul::is_syllable(ch) || canonical_decomposition(ch).is_some() {
return Some(Canonical);
}
bsearch_range_value_table(ch, COMPATIBILITY_DECOMPOSITION_TYPE_TABLE)
}
}
fn bsearch_range_value_table(
c: char,
r: &'static [(char, char, DecompositionType)],
) -> Option<DecompositionType> {
match r.binary_search_by(|&(lo, hi, _)| if lo <= c && c <= hi {
Ordering::Equal
} else if hi < c {
Ordering::Less
} else {
Ordering::Greater
}) {
Ok(idx) => {
let (_, _, dt) = r[idx];
Some(dt)
}
Err(_) => Option::None,
}
}
#[cfg(test)]
mod tests {
use super::DecompositionType as DT;
#[test]
fn test_ascii() {
assert_eq!(DT::of('\u{0000}'), None);
assert_eq!(DT::of('\u{0040}'), None);
assert_eq!(DT::of('\u{0041}'), None);
assert_eq!(DT::of('\u{0062}'), None);
assert_eq!(DT::of('\u{007F}'), None);
}
#[test]
fn test_bmp() {
assert_eq!(DT::of('\u{a0}'), Some(DT::Nobreak));
assert_eq!(DT::of('\u{a8}'), Some(DT::Compat));
assert_eq!(DT::of('\u{aa}'), Some(DT::Super));
assert_eq!(DT::of('\u{af}'), Some(DT::Compat));
assert_eq!(DT::of('\u{b2}'), Some(DT::Super));
assert_eq!(DT::of('\u{b3}'), Some(DT::Super));
assert_eq!(DT::of('\u{b4}'), Some(DT::Compat));
assert_eq!(DT::of('\u{b5}'), Some(DT::Compat));
assert_eq!(DT::of('\u{b8}'), Some(DT::Compat));
assert_eq!(DT::of('\u{b9}'), Some(DT::Super));
assert_eq!(DT::of('\u{ba}'), Some(DT::Super));
assert_eq!(DT::of('\u{bc}'), Some(DT::Fraction));
assert_eq!(DT::of('\u{bd}'), Some(DT::Fraction));
assert_eq!(DT::of('\u{be}'), Some(DT::Fraction));
assert_eq!(DT::of('\u{c0}'), Some(DT::Canonical));
assert_eq!(DT::of('\u{c1}'), Some(DT::Canonical));
assert_eq!(DT::of('\u{d6}'), Some(DT::Canonical));
assert_eq!(DT::of('\u{d9}'), Some(DT::Canonical));
assert_eq!(DT::of('\u{10f}'), Some(DT::Canonical));
assert_eq!(DT::of('\u{0300}'), None);
assert_eq!(DT::of('\u{0314}'), None);
assert_eq!(DT::of('\u{0315}'), None);
assert_eq!(DT::of('\u{0316}'), None);
assert_eq!(DT::of('\u{0319}'), None);
assert_eq!(DT::of('\u{0590}'), None);
assert_eq!(DT::of('\u{05D0}'), None);
assert_eq!(DT::of('\u{05D1}'), None);
assert_eq!(DT::of('\u{05FF}'), None);
assert_eq!(DT::of('\u{0600}'), None);
assert_eq!(DT::of('\u{0627}'), None);
assert_eq!(DT::of('\u{064B}'), None);
assert_eq!(DT::of('\u{064C}'), None);
assert_eq!(DT::of('\u{064D}'), None);
assert_eq!(DT::of('\u{064E}'), None);
assert_eq!(DT::of('\u{064F}'), None);
assert_eq!(DT::of('\u{0650}'), None);
assert_eq!(DT::of('\u{0651}'), None);
assert_eq!(DT::of('\u{0652}'), None);
assert_eq!(DT::of('\u{07BF}'), None);
assert_eq!(DT::of('\u{07C0}'), None);
assert_eq!(DT::of('\u{085F}'), None);
assert_eq!(DT::of('\u{0860}'), None);
assert_eq!(DT::of('\u{0870}'), None);
assert_eq!(DT::of('\u{089F}'), None);
assert_eq!(DT::of('\u{08A0}'), None);
assert_eq!(DT::of('\u{089F}'), None);
assert_eq!(DT::of('\u{08FF}'), None);
assert_eq!(DT::of('\u{20A0}'), None);
assert_eq!(DT::of('\u{20CF}'), None);
assert_eq!(DT::of('\u{FB1D}'), Some(DT::Canonical));
assert_eq!(DT::of('\u{FB4F}'), Some(DT::Compat));
assert_eq!(DT::of('\u{FB50}'), Some(DT::Isolated));
assert_eq!(DT::of('\u{FDCF}'), None);
assert_eq!(DT::of('\u{FDF0}'), Some(DT::Isolated));
assert_eq!(DT::of('\u{FDFF}'), None);
assert_eq!(DT::of('\u{FE70}'), Some(DT::Isolated));
assert_eq!(DT::of('\u{FEFE}'), None);
assert_eq!(DT::of('\u{FEFF}'), None);
assert_eq!(DT::of('\u{FDD0}'), None);
assert_eq!(DT::of('\u{FDD1}'), None);
assert_eq!(DT::of('\u{FDEE}'), None);
assert_eq!(DT::of('\u{FDEF}'), None);
assert_eq!(DT::of('\u{FFFE}'), None);
assert_eq!(DT::of('\u{FFFF}'), None);
}
#[test]
fn test_smp() {
assert_eq!(DT::of('\u{10000}'), None);
assert_eq!(DT::of('\u{101fc}'), None);
assert_eq!(DT::of('\u{101fd}'), None);
assert_eq!(DT::of('\u{101fe}'), None);
assert_eq!(DT::of('\u{1e000}'), None);
assert_eq!(DT::of('\u{1e949}'), None);
assert_eq!(DT::of('\u{1e94a}'), None);
assert_eq!(DT::of('\u{1e94b}'), None);
assert_eq!(DT::of('\u{1efff}'), None);
assert_eq!(DT::of('\u{1fffe}'), None);
assert_eq!(DT::of('\u{1ffff}'), None);
}
#[test]
fn test_unassigned_planes() {
assert_eq!(DT::of('\u{30000}'), None);
assert_eq!(DT::of('\u{40000}'), None);
assert_eq!(DT::of('\u{50000}'), None);
assert_eq!(DT::of('\u{60000}'), None);
assert_eq!(DT::of('\u{70000}'), None);
assert_eq!(DT::of('\u{80000}'), None);
assert_eq!(DT::of('\u{90000}'), None);
assert_eq!(DT::of('\u{a0000}'), None);
}
}