1const ETHIOPIC_ONE: u16 = '፩' as u16;
2const ETHIOPIC_TEN: u16 = '፲' as u16;
3const ONE: u16 = '1' as u16;
4
5pub fn ethiopic(num: usize) -> String {
6 let mut num = num.to_string();
7 if num.len() % 2 != 0 {
8 num.insert(0, '0')
9 }
10
11 let mut num = num.chars().rev().peekable();
12
13 let mut ethiopic_num = String::new();
14 let mut pos = 0;
15 while let (Some(ascii_one), Some(ascii_ten)) = (num.next(), num.next()) {
16 let mut ethio_one: Option<char> = None;
17 let mut ethio_ten: Option<char> = None;
18
19 if ascii_one != '0' {
20 ethio_one = char::from_u32((ETHIOPIC_ONE + ((ascii_one as u16) - ONE)) as u32);
21 }
22
23 if ascii_ten != '0' {
24 ethio_ten = char::from_u32((ETHIOPIC_TEN + ((ascii_ten as u16) - ONE)) as u32);
25 }
26
27 let sep = if pos > 0 {
28 if pos % 2 == 0 {
29 "፼"
30 } else if ethio_one.is_some() || ethio_ten.is_some() {
31 "፻"
32 } else {
33 ""
34 }
35 } else {
36 ""
37 };
38
39 if ethio_one == Some('፩')
40 && sep != ""
41 && ethio_ten.is_none()
42 && (num.peek().is_none() || sep == "፻")
43 {
44 ethio_one = None;
45 }
46
47 let mut part = String::new();
48
49 if let Some(x) = ethio_ten {
50 part.push(x);
51 }
52 if let Some(x) = ethio_one {
53 part.push(x);
54 }
55
56 part.push_str(sep);
57 ethiopic_num = format!("{part}{ethiopic_num}");
58 pos += 1;
59 }
60
61 ethiopic_num
62}
63
64#[cfg(test)]
65mod tests {
66 use crate::ethiopic;
67
68 #[test]
69 fn test() {
70 let test_data = [
71 (0, ""),
72 (1, "፩"),
73 (2, "፪"),
74 (3, "፫"),
75 (4, "፬"),
76 (5, "፭"),
77 (6, "፮"),
78 (7, "፯"),
79 (8, "፰"),
80 (9, "፱"),
81 (10, "፲"),
82 (20, "፳"),
83 (30, "፴"),
84 (40, "፵"),
85 (50, "፶"),
86 (60, "፷"),
87 (70, "፸"),
88 (80, "፹"),
89 (90, "፺"),
90 (100, "፻"),
91 (500, "፭፻"),
92 (10_000, "፼"),
93 (42, "፵፪"),
94 (78, "፸፰"),
95 (18, "፲፰"),
96 (1000, "፲፻"),
97 (100_000, "፲፼"),
98 (111, "፻፲፩"),
99 (666, "፮፻፷፮"),
100 (1_000_000, "፻፼"),
101 (10_000_000, "፲፻፼"),
102 (123, "፻፳፫"),
103 (1111, "፲፩፻፲፩"),
104 (1234, "፲፪፻፴፬"),
105 (6666, "፷፮፻፷፮"),
106 (1001, "፲፻፩"),
107 (11111, "፼፲፩፻፲፩"),
108 (111111, "፲፩፼፲፩፻፲፩"),
109 ];
110
111 for (n, e) in test_data {
112 assert_eq!(ethiopic(n), e.to_owned());
113 }
114 }
115
116 #[test]
117 fn test_from_website() {
118 let test_data = [
119 (1, "፩"),
120 (10, "፲"),
121 (100, "፻"),
122 (1000, "፲፻"),
123 (10000, "፼"),
124 (100000, "፲፼"),
125 (1000000, "፻፼"),
126 (10000000, "፲፻፼"),
127 (100000000, "፼፼"),
128 (1000000000, "፲፼፼"),
129 (10000000000, "፻፼፼"),
130 (100000000000, "፲፻፼፼"),
131 (1000000000000, "፼፼፼"),
132 (100010000, "፼፩፼"),
133 (100100000, "፼፲፼"),
134 (100200000, "፼፳፼"),
135 (100110000, "፼፲፩፼"),
136 (1, "፩"),
137 (11, "፲፩"),
138 (111, "፻፲፩"),
139 (1111, "፲፩፻፲፩"),
140 (11111, "፼፲፩፻፲፩"),
141 (111111, "፲፩፼፲፩፻፲፩"),
142 (1111111, "፻፲፩፼፲፩፻፲፩"),
143 (11111111, "፲፩፻፲፩፼፲፩፻፲፩"),
144 (111111111, "፼፲፩፻፲፩፼፲፩፻፲፩"),
145 (1111111111, "፲፩፼፲፩፻፲፩፼፲፩፻፲፩"),
146 (11111111111, "፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩"),
147 (111111111111, "፲፩፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩"),
148 (1111111111111, "፼፲፩፻፲፩፼፲፩፻፲፩፼፲፩፻፲፩"),
149 (1, "፩"),
150 (12, "፲፪"),
151 (123, "፻፳፫"),
152 (1234, "፲፪፻፴፬"),
153 (12345, "፼፳፫፻፵፭"),
154 (7654321, "፯፻፷፭፼፵፫፻፳፩"),
155 (17654321, "፲፯፻፷፭፼፵፫፻፳፩"),
156 (51615131, "፶፩፻፷፩፼፶፩፻፴፩"),
157 (15161513, "፲፭፻፲፮፼፲፭፻፲፫"),
158 (10101011, "፲፻፲፼፲፻፲፩"),
159 (101, "፻፩"),
160 (1001, "፲፻፩"),
161 (1010, "፲፻፲"),
162 (1011, "፲፻፲፩"),
163 (1100, "፲፩፻"),
164 (1101, "፲፩፻፩"),
165 (1111, "፲፩፻፲፩"),
166 (10001, "፼፩"),
167 (10010, "፼፲"),
168 (10100, "፼፻"),
169 (10101, "፼፻፩"),
170 (10110, "፼፻፲"),
171 (10111, "፼፻፲፩"),
172 (100001, "፲፼፩"),
173 (100010, "፲፼፲"),
174 (100011, "፲፼፲፩"),
175 (100100, "፲፼፻"),
176 (101010, "፲፼፲፻፲"),
177 (1000001, "፻፼፩"),
178 (1000101, "፻፼፻፩"),
179 (1000100, "፻፼፻"),
180 (1010000, "፻፩፼"),
181 (1010001, "፻፩፼፩"),
182 (1100001, "፻፲፼፩"),
183 (1010101, "፻፩፼፻፩"),
184 (101010101, "፼፻፩፼፻፩"),
185 (100010000, "፼፩፼"),
186 (100010100, "፼፩፼፻"),
187 (101010100, "፼፻፩፼፻"),
188 (3, "፫"),
189 (30, "፴"),
190 (33, "፴፫"),
191 (303, "፫፻፫"),
192 (3003, "፴፻፫"),
193 (3030, "፴፻፴"),
194 (3033, "፴፻፴፫"),
195 (3300, "፴፫፻"),
196 (3303, "፴፫፻፫"),
197 (3333, "፴፫፻፴፫"),
198 (30003, "፫፼፫"),
199 (30303, "፫፼፫፻፫"),
200 (300003, "፴፼፫"),
201 (303030, "፴፼፴፻፴"),
202 (3000003, "፫፻፼፫"),
203 (3000303, "፫፻፼፫፻፫"),
204 (3030003, "፫፻፫፼፫"),
205 (3300003, "፫፻፴፼፫"),
206 (3030303, "፫፻፫፼፫፻፫"),
207 (303030303, "፫፼፫፻፫፼፫፻፫"),
208 (333333333, "፫፼፴፫፻፴፫፼፴፫፻፴፫"),
209 ];
210
211 for (n, e) in test_data {
212 assert_eq!(ethiopic(n), e.to_owned());
213 }
214 }
215}