chinese_number_uppercase/
lib.rs1const SYMBOL_TABLE: [char; 10] = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];
2const UNIT_TABLE: [char; 4] = ['\0', '拾', '佰', '仟'];
3const STEP_UNIT_TABLE: [char; 5] = ['\0', '万', '亿', '兆', '京'];
4
5pub fn to_uppercase(number: u64) -> String {
6 if number < 10 {
7 return SYMBOL_TABLE[number as usize].to_string();
8 }
9
10 let mut chars: Vec<char> = Vec::new();
11 let mut copy_number = number;
12 let mut step: usize = 0;
13 while copy_number > 0 {
14 let r = copy_number % 10000;
15
16 if step > 0 {
17 if r > 0 {
18 chars.push(STEP_UNIT_TABLE[step]);
19 } else {
20 if let Some(&'零') = chars.last() {
21 chars.pop();
22 }
23 chars.push('零');
24 }
25 }
26
27 if r > 0 {
28 chars.append(&mut number_slice_to_uppercase(pad_number(r).as_str()));
29 }
30
31 copy_number /= 10000;
32 step += 1;
33 }
34
35 if let Some(&'零') = chars.first() {
36 chars.remove(0);
37 }
38
39 if let Some(&'零') = chars.last() {
40 chars.pop();
41 }
42
43 return String::from_iter(chars.iter().rev());
44}
45
46fn pad_number(number: u64) -> String {
47 format!("{:04}", number)
48}
49
50fn number_slice_to_uppercase(number: &str) -> Vec<char> {
51 let mut chars: Vec<char> = Vec::new();
52 for (i, c) in number
53 .chars()
54 .map(|x| x.to_digit(10).unwrap())
55 .rev()
56 .enumerate()
57 {
58 if let (Some(&'零'), true) = (chars.last(), c == 0) {
59 continue;
60 }
61 if c != 0 && i > 0 {
62 chars.push(UNIT_TABLE[i]);
63 }
64 chars.push(SYMBOL_TABLE[c as usize]);
65 }
66
67 if let Some(&'零') = chars.first() {
68 chars.remove(0);
69 }
70
71 chars
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77
78 #[test]
79 fn test_to_uppercase() {
80 assert_eq!(to_uppercase(0), "零");
81 assert_eq!(to_uppercase(1), "壹");
82 assert_eq!(to_uppercase(9), "玖");
83 assert_eq!(to_uppercase(10), "壹拾");
84 assert_eq!(to_uppercase(20), "贰拾");
85 assert_eq!(to_uppercase(100), "壹佰");
86 assert_eq!(to_uppercase(101), "壹佰零壹");
87 assert_eq!(to_uppercase(1010), "壹仟零壹拾");
88 assert_eq!(to_uppercase(10000), "壹万");
89 assert_eq!(to_uppercase(10101), "壹万零壹佰零壹");
90 assert_eq!(to_uppercase(1000000), "壹佰万");
91 assert_eq!(to_uppercase(1000100), "壹佰万零壹佰");
92 assert_eq!(to_uppercase(10000100), "壹仟万零壹佰");
93 assert_eq!(to_uppercase(100001000), "壹亿零壹仟");
94 assert_eq!(to_uppercase(1010001001), "壹拾亿壹仟万壹仟零壹");
95 assert_eq!(to_uppercase(1011000101), "壹拾亿壹仟壹佰万零壹佰零壹");
96 assert_eq!(
97 to_uppercase(999999999999),
98 "玖仟玖佰玖拾玖亿玖仟玖佰玖拾玖万玖仟玖佰玖拾玖"
99 );
100 assert_eq!(to_uppercase(1000000000000), "壹兆");
101 assert_eq!(to_uppercase(1000000000001), "壹兆零壹");
102 assert_eq!(
103 to_uppercase(18446744073709551615),
104 "壹仟捌佰肆拾肆京陆仟柒佰肆拾肆兆零柒佰叁拾柒亿零玖佰伍拾伍万壹仟陆佰壹拾伍"
105 );
106 }
107
108 #[test]
109 fn test_number_slice_to_uppercase() {
110 assert_eq!(
111 number_slice_to_uppercase("0001").iter().collect::<String>(),
112 "壹零"
113 );
114 assert_eq!(
115 number_slice_to_uppercase("0123").iter().collect::<String>(),
116 "叁拾贰佰壹零"
117 );
118 assert_eq!(
119 number_slice_to_uppercase("0120").iter().collect::<String>(),
120 "拾贰佰壹零"
121 );
122 assert_eq!(
123 number_slice_to_uppercase("1230").iter().collect::<String>(),
124 "拾叁佰贰仟壹"
125 );
126 assert_eq!(
127 number_slice_to_uppercase("1000").iter().collect::<String>(),
128 "仟壹"
129 );
130 }
131}