]> git.lizzy.rs Git - rust.git/blob - src/tools/unicode-table-generator/src/case_mapping.rs
Merge commit 'd822110d3b5625b9dc80ccc442e06fc3cc851d76' into clippyup
[rust.git] / src / tools / unicode-table-generator / src / case_mapping.rs
1 use crate::{fmt_list, UnicodeData};
2 use std::fmt;
3
4 pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String {
5     let mut file = String::new();
6
7     file.push_str(HEADER.trim_start());
8
9     let decl_type = "&[(char, [char; 3])]";
10
11     file.push_str(&format!(
12         "static LOWERCASE_TABLE: {} = &[{}];",
13         decl_type,
14         fmt_list(data.to_lower.iter().map(to_mapping))
15     ));
16     file.push_str("\n\n");
17     file.push_str(&format!(
18         "static UPPERCASE_TABLE: {} = &[{}];",
19         decl_type,
20         fmt_list(data.to_upper.iter().map(to_mapping))
21     ));
22     file
23 }
24
25 fn to_mapping((key, (a, b, c)): (&u32, &(u32, u32, u32))) -> (CharEscape, [CharEscape; 3]) {
26     (
27         CharEscape(std::char::from_u32(*key).unwrap()),
28         [
29             CharEscape(std::char::from_u32(*a).unwrap()),
30             CharEscape(std::char::from_u32(*b).unwrap()),
31             CharEscape(std::char::from_u32(*c).unwrap()),
32         ],
33     )
34 }
35
36 struct CharEscape(char);
37
38 impl fmt::Debug for CharEscape {
39     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40         write!(f, "'{}'", self.0.escape_default())
41     }
42 }
43
44 static HEADER: &str = r"
45 pub fn to_lower(c: char) -> [char; 3] {
46     if c.is_ascii() {
47         [(c as u8).to_ascii_lowercase() as char, '\0', '\0']
48     } else {
49         match bsearch_case_table(c, LOWERCASE_TABLE) {
50             None => [c, '\0', '\0'],
51             Some(index) => LOWERCASE_TABLE[index].1,
52         }
53     }
54 }
55
56 pub fn to_upper(c: char) -> [char; 3] {
57     if c.is_ascii() {
58         [(c as u8).to_ascii_uppercase() as char, '\0', '\0']
59     } else {
60         match bsearch_case_table(c, UPPERCASE_TABLE) {
61             None => [c, '\0', '\0'],
62             Some(index) => UPPERCASE_TABLE[index].1,
63         }
64     }
65 }
66
67 fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option<usize> {
68     table.binary_search_by(|&(key, _)| key.cmp(&c)).ok()
69 }
70 ";