1 use crate::{fmt_list, UnicodeData};
4 pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String {
5 let mut file = String::new();
7 file.push_str(HEADER.trim_start());
9 let decl_type = "&[(char, [char; 3])]";
11 file.push_str(&format!(
12 "static LOWERCASE_TABLE: {} = &[{}];",
14 fmt_list(data.to_lower.iter().map(to_mapping))
16 file.push_str("\n\n");
17 file.push_str(&format!(
18 "static UPPERCASE_TABLE: {} = &[{}];",
20 fmt_list(data.to_upper.iter().map(to_mapping))
25 fn to_mapping((key, (a, b, c)): (&u32, &(u32, u32, u32))) -> (CharEscape, [CharEscape; 3]) {
27 CharEscape(std::char::from_u32(*key).unwrap()),
29 CharEscape(std::char::from_u32(*a).unwrap()),
30 CharEscape(std::char::from_u32(*b).unwrap()),
31 CharEscape(std::char::from_u32(*c).unwrap()),
36 struct CharEscape(char);
38 impl fmt::Debug for CharEscape {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "'{}'", self.0.escape_default())
44 static HEADER: &str = r"
45 pub fn to_lower(c: char) -> [char; 3] {
47 [(c as u8).to_ascii_lowercase() as char, '\0', '\0']
49 match bsearch_case_table(c, LOWERCASE_TABLE) {
50 None => [c, '\0', '\0'],
51 Some(index) => LOWERCASE_TABLE[index].1,
56 pub fn to_upper(c: char) -> [char; 3] {
58 [(c as u8).to_ascii_uppercase() as char, '\0', '\0']
60 match bsearch_case_table(c, UPPERCASE_TABLE) {
61 None => [c, '\0', '\0'],
62 Some(index) => UPPERCASE_TABLE[index].1,
67 fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option<usize> {
68 table.binary_search_by(|&(key, _)| key.cmp(&c)).ok()