1use std::fmt::{self, Display, Formatter};
2
3pub struct Fmt(pub i64);
4
5#[derive(Debug)]
6struct ZeroFlag {
7 flag : Option<bool>,
8}
9impl ZeroFlag {
10 fn new() -> ZeroFlag {
11 return ZeroFlag { flag: None };
12 }
13 fn should_output(&self) -> bool {
14 return match self.flag {
15 Some(f) => f,
16 None => false,
17 }
18 }
19 fn did_output_some_character(&mut self) {
20 self.flag = Some(false);
21 }
22 fn reset(&mut self) {
23 match self.flag {
24 Some(_) => {
25 self.flag = Some(true)
26 },
27 None => {},
28 }
29 }
30}
31
32fn digit_str(n : i64) -> &'static str
33{
34 return match n {
35 1 => "一",
36 2 => "二",
37 3 => "三",
38 4 => "四",
39 5 => "五",
40 6 => "六",
41 7 => "七",
42 8 => "八",
43 9 => "九",
44 _ => "",
45 }
46}
47
48fn get_max_unit_index(val: i64) -> i8 {
49 let mut max_index : i8 = 0;
50 let mut temp = val / 10000;
51 while temp > 0 {
52 max_index += 1;
53 temp /= 10000;
54 }
55 return max_index;
56}
57
58impl Display for Fmt {
59 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
60 if self.0 == 0 {
61 return f.write_str("零");
62 }
63
64 if self.0 < 0 {
66 f.write_str("负")?;
67 }
68 let val = i64::abs(self.0);
69
70 let mut max_index = get_max_unit_index(val);
71 let units : [&str; 5] = ["", "万", "亿", "兆", "京"];
72
73 let mut temp = val;
74 let mut need_zero = ZeroFlag::new();
75 while temp > 0 {
76 let base = i64::pow(10000, max_index as u32);
77 let mut part = temp / base;
78 let not_empty : bool = part != 0;
79
80 if part >= 1000 {
82 if need_zero.should_output() {
83 f.write_str("零")?;
84 }
85 need_zero.did_output_some_character();
86
87 f.write_str(digit_str(part/1000))?;
88 f.write_str("千")?;
89 part %= 1000;
90 } else {
91 need_zero.reset();
92 }
93
94 if part >= 100 {
95 if need_zero.should_output() {
96 f.write_str("零")?;
97 }
98 need_zero.did_output_some_character();
99
100 f.write_str(digit_str(part/100))?;
101 f.write_str("百")?;
102 part %= 100;
103 } else {
104 need_zero.reset();
105 }
106
107 if part >= 10 {
108 if need_zero.should_output() {
109 f.write_str("零")?;
110 }
111 need_zero.did_output_some_character();
112
113 if part >= 20 {
114 f.write_str(digit_str(part/10))?;
115 }
116 f.write_str("十")?;
117 part %= 10;
118 } else {
119 need_zero.reset();
120 }
121 if part > 0 {
122 if need_zero.should_output() {
123 f.write_str("零")?;
124 }
125 need_zero.did_output_some_character();
126
127 f.write_str(digit_str(part))?;
128 } else {
129 need_zero.reset();
130 }
131
132 if not_empty {
133 f.write_str(units[max_index as usize])?;
134 }
135
136 max_index -= 1;
137 temp %= base;
138 }
139
140 Ok(())
141 }
142}
143
144pub fn convert_all_fmt(val: i64) -> String {
145 Fmt(val).to_string()
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151 #[test]
152 fn it_works() {
153 assert_eq!(get_max_unit_index(0), 0);
154 assert_eq!(get_max_unit_index(1), 0);
155 assert_eq!(get_max_unit_index(10), 0);
156 assert_eq!(get_max_unit_index(100), 0);
157 assert_eq!(get_max_unit_index(1000), 0);
158 assert_eq!(get_max_unit_index(10000), 1);
159 assert_eq!(get_max_unit_index(100000), 1);
160 assert_eq!(get_max_unit_index(1000000), 1);
161 assert_eq!(get_max_unit_index(10000000), 1);
162 assert_eq!(get_max_unit_index(100000000), 2);
163 assert_eq!(get_max_unit_index(1000000000), 2);
164 assert_eq!(get_max_unit_index(10000000000), 2);
165 assert_eq!(get_max_unit_index(100000000000), 2);
166 assert_eq!(get_max_unit_index(1000000000000), 3);
167 assert_eq!(get_max_unit_index(10000000000000), 3);
168 assert_eq!(get_max_unit_index(100000000000000), 3);
169 assert_eq!(get_max_unit_index(1000000000000000), 3);
170 assert_eq!(get_max_unit_index(10000000000000000), 4);
171 assert_eq!(get_max_unit_index(100000000000000000), 4);
172 assert_eq!(get_max_unit_index(1000000000000000000), 4);
173 assert_eq!(get_max_unit_index(9223372036854775807), 4);
174
175 assert_eq!(convert_all_fmt(0), "零");
176 assert_eq!(convert_all_fmt(1), "一");
177 assert_eq!(convert_all_fmt(9), "九");
178 assert_eq!(convert_all_fmt(10), "十");
179 assert_eq!(convert_all_fmt(11), "十一");
180 assert_eq!(convert_all_fmt(111), "一百十一");
181 assert_eq!(convert_all_fmt(101), "一百零一");
182 assert_eq!(convert_all_fmt(100), "一百");
183 assert_eq!(convert_all_fmt(2000), "二千");
184 assert_eq!(convert_all_fmt(20000), "二万");
185 assert_eq!(convert_all_fmt(200000), "二十万");
186 assert_eq!(convert_all_fmt(20000000), "二千万");
187 assert_eq!(convert_all_fmt(200000000), "二亿");
188 assert_eq!(convert_all_fmt(2000000000), "二十亿");
189 assert_eq!(convert_all_fmt(12345), "一万二千三百四十五");
190 assert_eq!(convert_all_fmt(10345), "一万零三百四十五");
191 assert_eq!(convert_all_fmt(10045), "一万零四十五");
192 assert_eq!(convert_all_fmt(10005), "一万零五");
193 assert_eq!(convert_all_fmt(10000), "一万");
194 assert_eq!(convert_all_fmt(100450), "十万零四百五十");
195 assert_eq!(convert_all_fmt(9223372036854775807), "九百二十二京三千三百七十二兆零三百六十八亿五千四百七十七万五千八百零七");
196
197 assert_eq!(convert_all_fmt(0), "零");
198 assert_eq!(convert_all_fmt(-1), "负一");
199 assert_eq!(convert_all_fmt(-9), "负九");
200 assert_eq!(convert_all_fmt(-10), "负十");
201 assert_eq!(convert_all_fmt(-11), "负十一");
202 assert_eq!(convert_all_fmt(-111), "负一百十一");
203 assert_eq!(convert_all_fmt(-101), "负一百零一");
204 assert_eq!(convert_all_fmt(-100), "负一百");
205 assert_eq!(convert_all_fmt(-12345), "负一万二千三百四十五");
206 assert_eq!(convert_all_fmt(-10345), "负一万零三百四十五");
207 assert_eq!(convert_all_fmt(-10045), "负一万零四十五");
208 assert_eq!(convert_all_fmt(-10005), "负一万零五");
209 assert_eq!(convert_all_fmt(-10000), "负一万");
210 assert_eq!(convert_all_fmt(-100450), "负十万零四百五十");
211 assert_eq!(convert_all_fmt(-9223372036854775807), "负九百二十二京三千三百七十二兆零三百六十八亿五千四百七十七万五千八百零七");
212 }
213}