aboutsummaryrefslogtreecommitdiff
path: root/src/zip/cp437.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/zip/cp437.rs')
-rw-r--r--src/zip/cp437.rs376
1 files changed, 376 insertions, 0 deletions
diff --git a/src/zip/cp437.rs b/src/zip/cp437.rs
new file mode 100644
index 0000000..e290ea6
--- /dev/null
+++ b/src/zip/cp437.rs
@@ -0,0 +1,376 @@
1pub trait FromCp437<T>: Sized {
2 type Value;
3
4 fn from_cp437(value: T) -> Self::Value;
5}
6
7pub fn to_char(byte: u8) -> char {
8 char::from_u32(match byte {
9 0..=127 => byte as u32,
10 128 => 199,
11 129 => 252,
12 130 => 233,
13 131 => 226,
14 132 => 228,
15 133 => 224,
16 134 => 229,
17 135 => 231,
18 136 => 234,
19 137 => 235,
20 138 => 232,
21 139 => 239,
22 140 => 238,
23 141 => 236,
24 142 => 196,
25 143 => 197,
26 144 => 201,
27 145 => 230,
28 146 => 198,
29 147 => 244,
30 148 => 246,
31 149 => 242,
32 150 => 251,
33 151 => 249,
34 152 => 255,
35 153 => 214,
36 154 => 220,
37 155 => 162,
38 156 => 163,
39 157 => 165,
40 158 => 8359,
41 159 => 402,
42 160 => 225,
43 161 => 237,
44 162 => 243,
45 163 => 250,
46 164 => 241,
47 165 => 209,
48 166 => 170,
49 167 => 186,
50 168 => 191,
51 169 => 8976,
52 170 => 172,
53 171 => 189,
54 172 => 188,
55 173 => 161,
56 174 => 171,
57 175 => 187,
58 176 => 9617,
59 177 => 9618,
60 178 => 9619,
61 179 => 9474,
62 180 => 9508,
63 181 => 9569,
64 182 => 9570,
65 183 => 9558,
66 184 => 9557,
67 185 => 9571,
68 186 => 9553,
69 187 => 9559,
70 188 => 9565,
71 189 => 9564,
72 190 => 9563,
73 191 => 9488,
74 192 => 9492,
75 193 => 9524,
76 194 => 9516,
77 195 => 9500,
78 196 => 9472,
79 197 => 9532,
80 198 => 9566,
81 199 => 9567,
82 200 => 9562,
83 201 => 9556,
84 202 => 9577,
85 203 => 9574,
86 204 => 9568,
87 205 => 9552,
88 206 => 9580,
89 207 => 9575,
90 208 => 9576,
91 209 => 9572,
92 210 => 9573,
93 211 => 9561,
94 212 => 9560,
95 213 => 9554,
96 214 => 9555,
97 215 => 9579,
98 216 => 9578,
99 217 => 9496,
100 218 => 9484,
101 219 => 9608,
102 220 => 9604,
103 221 => 9612,
104 222 => 9616,
105 223 => 9600,
106 224 => 945,
107 225 => 223,
108 226 => 915,
109 227 => 960,
110 228 => 931,
111 229 => 963,
112 230 => 181,
113 231 => 964,
114 232 => 934,
115 233 => 920,
116 234 => 937,
117 235 => 948,
118 236 => 8734,
119 237 => 966,
120 238 => 949,
121 239 => 8745,
122 240 => 8801,
123 241 => 177,
124 242 => 8805,
125 243 => 8804,
126 244 => 8992,
127 245 => 8993,
128 246 => 247,
129 247 => 8776,
130 248 => 176,
131 249 => 8729,
132 250 => 183,
133 251 => 8730,
134 252 => 8319,
135 253 => 178,
136 254 => 9632,
137 255 => 160,
138 })
139 .unwrap()
140}
141
142pub fn from_char(char: char) -> Option<u8> {
143 Some(match char as u32 {
144 0..=127 => char as u8,
145 160 => 255,
146 161 => 173,
147 162 => 155,
148 163 => 156,
149 165 => 157,
150 170 => 166,
151 171 => 174,
152 172 => 170,
153 176 => 248,
154 177 => 241,
155 178 => 253,
156 181 => 230,
157 183 => 250,
158 186 => 167,
159 187 => 175,
160 188 => 172,
161 189 => 171,
162 191 => 168,
163 196 => 142,
164 197 => 143,
165 198 => 146,
166 199 => 128,
167 201 => 144,
168 209 => 165,
169 214 => 153,
170 220 => 154,
171 223 => 225,
172 224 => 133,
173 225 => 160,
174 226 => 131,
175 228 => 132,
176 229 => 134,
177 230 => 145,
178 231 => 135,
179 232 => 138,
180 233 => 130,
181 234 => 136,
182 235 => 137,
183 236 => 141,
184 237 => 161,
185 238 => 140,
186 239 => 139,
187 241 => 164,
188 242 => 149,
189 243 => 162,
190 244 => 147,
191 246 => 148,
192 247 => 246,
193 249 => 151,
194 250 => 163,
195 251 => 150,
196 252 => 129,
197 255 => 152,
198 402 => 159,
199 915 => 226,
200 920 => 233,
201 931 => 228,
202 934 => 232,
203 937 => 234,
204 945 => 224,
205 948 => 235,
206 949 => 238,
207 960 => 227,
208 963 => 229,
209 964 => 231,
210 966 => 237,
211 8319 => 252,
212 8359 => 158,
213 8729 => 249,
214 8730 => 251,
215 8734 => 236,
216 8745 => 239,
217 8776 => 247,
218 8801 => 240,
219 8804 => 243,
220 8805 => 242,
221 8976 => 169,
222 8992 => 244,
223 8993 => 245,
224 9472 => 196,
225 9474 => 179,
226 9484 => 218,
227 9488 => 191,
228 9492 => 192,
229 9496 => 217,
230 9500 => 195,
231 9508 => 180,
232 9516 => 194,
233 9524 => 193,
234 9532 => 197,
235 9552 => 205,
236 9553 => 186,
237 9554 => 213,
238 9555 => 214,
239 9556 => 201,
240 9557 => 184,
241 9558 => 183,
242 9559 => 187,
243 9560 => 212,
244 9561 => 211,
245 9562 => 200,
246 9563 => 190,
247 9564 => 189,
248 9565 => 188,
249 9566 => 198,
250 9567 => 199,
251 9568 => 204,
252 9569 => 181,
253 9570 => 182,
254 9571 => 185,
255 9572 => 209,
256 9573 => 210,
257 9574 => 203,
258 9575 => 207,
259 9576 => 208,
260 9577 => 202,
261 9578 => 216,
262 9579 => 215,
263 9580 => 206,
264 9600 => 223,
265 9604 => 220,
266 9608 => 219,
267 9612 => 221,
268 9616 => 222,
269 9617 => 176,
270 9618 => 177,
271 9619 => 178,
272 9632 => 254,
273 _ => return None,
274 })
275}
276
277pub fn is_cp437(char: char) -> bool {
278 match char as u32 {
279 0..=127 => true,
280 160..=163 => true,
281 165 => true,
282 170..=172 => true,
283 176..=178 => true,
284 181 => true,
285 183 => true,
286 186..=189 => true,
287 191 => true,
288 196..=199 => true,
289 201 => true,
290 209 => true,
291 214 => true,
292 220 => true,
293 223..=226 => true,
294 228..=239 => true,
295 241..=244 => true,
296 246..=247 => true,
297 249..=252 => true,
298 255 => true,
299 402 => true,
300 915 => true,
301 920 => true,
302 931 => true,
303 934 => true,
304 937 => true,
305 945 => true,
306 948..=949 => true,
307 960 => true,
308 963..=964 => true,
309 966 => true,
310 8319 => true,
311 8359 => true,
312 8729..=8730 => true,
313 8734 => true,
314 8745 => true,
315 8776 => true,
316 8801 => true,
317 8804..=8805 => true,
318 8976 => true,
319 8992..=8993 => true,
320 9472 => true,
321 9474 => true,
322 9484 => true,
323 9488 => true,
324 9492 => true,
325 9496 => true,
326 9500 => true,
327 9508 => true,
328 9516 => true,
329 9524 => true,
330 9532 => true,
331 9552..=9580 => true,
332 9600 => true,
333 9604 => true,
334 9608 => true,
335 9612 => true,
336 9616..=9619 => true,
337 9632 => true,
338 _ => false,
339 }
340}
341
342impl FromCp437<Vec<u8>> for String {
343 type Value = Self;
344
345 fn from_cp437(bytes: Vec<u8>) -> Self {
346 Self::from_cp437(bytes.as_slice())
347 }
348}
349
350impl<const S: usize> FromCp437<[u8; S]> for String {
351 type Value = Self;
352
353 fn from_cp437(bytes: [u8; S]) -> Self {
354 Self::from_cp437(bytes.as_slice())
355 }
356}
357
358impl FromCp437<&[u8]> for String {
359 type Value = Self;
360
361 fn from_cp437(bytes: &[u8]) -> Self {
362 bytes.iter().copied().map(to_char).collect()
363 }
364}
365
366impl FromCp437<&str> for Vec<u8> {
367 type Value = Option<Self>;
368
369 fn from_cp437(text: &str) -> Option<Self> {
370 let mut bytes = Vec::with_capacity(text.chars().count());
371 for c in text.chars() {
372 bytes.push(from_char(c)?);
373 }
374 Some(bytes)
375 }
376}