unicode_case_mapping/case_mapping.rs
1use std::num::NonZeroU32;
2
3use crate::case_folding_simple;
4
5include!(concat!(env!("OUT_DIR"), "/case_mapping.rs")); // generated by build.rs
6
7const MASK: usize = BLOCK_SIZE - 1;
8const SHIFT: usize = MASK.count_ones() as usize;
9
10/// Map the supplied character to its lowercase equivalent.
11///
12/// The lowercase equivalent may be more than one code point. Unused elements in the returned
13/// array are set to 0.
14///
15/// **Note:** A result of all zeros indicates the codepoint maps to itself.
16pub fn to_lowercase(chr: char) -> [u32; 2] {
17 lookup(chr as u32).0
18}
19
20/// Map the supplied character to its uppercase equivalent.
21///
22/// The uppercase equivalent may be more than one code point. Unused elements in the returned
23/// array are set to 0.
24///
25/// **Note:** A result of all zeros indicates the codepoint maps to itself.
26pub fn to_uppercase(chr: char) -> [u32; 3] {
27 lookup(chr as u32).1
28}
29
30/// Map the supplied character to its titlecase equivalent.
31///
32/// The titlecase equivalent may be more than one code point. Unused elements in the returned
33/// array are set to 0.
34///
35/// **Note:** A result of all zeros indicates the codepoint maps to itself.
36pub fn to_titlecase(chr: char) -> [u32; 3] {
37 lookup(chr as u32).2
38}
39
40/// Map the supplied character to its case-folded equivalent.
41pub fn case_folded(chr: char) -> Option<NonZeroU32> {
42 case_folding_simple::case_folding_simple(chr as u32)
43}
44
45fn lookup(u: u32) -> &'static Row {
46 if u <= LAST_CODEPOINT {
47 let index = CASE_MAPPING_BLOCKS
48 [CASE_MAPPING_BLOCK_OFFSETS[u as usize >> SHIFT] as usize + (u as usize & MASK)];
49 &CASE_MAPPING_RECORDS[usize::from(index)]
50 } else {
51 &([0; 2], [0; 3], [0; 3])
52 }
53}