codepage437 0.1.0

Tools for dealing with various bitmap fonts, specifically IBM Codepage 437
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
use crate::cp437::CP437Error;
use serde::{de, Deserialize, Serialize};
use std::fmt;

#[derive(Debug, Default, Clone, PartialEq)]
pub struct CP437Char {
    pub byte: u8,
    pub ch: char,
}

impl From<u8> for CP437Char {
    fn from(byte: u8) -> Self {
        let ch = match byte {
            1 => '\u{263A}',
            2 => '\u{263B}',
            3 => '\u{2665}',
            4 => '\u{2666}',
            5 => '\u{2663}',
            6 => '\u{2660}',
            7 => '\u{2022}',
            8 => '\u{25D8}',
            9 => '\u{25CB}',
            10 => '\u{25D9}',
            11 => '\u{2642}',
            12 => '\u{2640}',
            13 => '\u{266A}',
            14 => '\u{266B}',
            15 => '\u{263C}',
            16 => '\u{25BA}',
            17 => '\u{25C4}',
            18 => '\u{2195}',
            19 => '\u{203C}',
            20 => '\u{00B6}',
            21 => '\u{00A7}',
            22 => '\u{25AC}',
            23 => '\u{21A8}',
            24 => '\u{2191}',
            25 => '\u{2193}',
            26 => '\u{2192}',
            27 => '\u{2190}',
            28 => '\u{221F}',
            29 => '\u{2194}',
            30 => '\u{25B2}',
            31 => '\u{25BC}',
            127 => '\u{2302}',
            128 => '\u{00C7}',
            129 => '\u{00FC}',
            130 => '\u{00E9}',
            131 => '\u{00E2}',
            132 => '\u{00E4}',
            133 => '\u{00E0}',
            134 => '\u{00E5}',
            135 => '\u{00E7}',
            136 => '\u{00EA}',
            137 => '\u{00EB}',
            138 => '\u{00E8}',
            139 => '\u{00EF}',
            140 => '\u{00EE}',
            141 => '\u{00EC}',
            142 => '\u{00C4}',
            143 => '\u{00C5}',
            144 => '\u{00C9}',
            145 => '\u{00E6}',
            146 => '\u{00C6}',
            147 => '\u{00F4}',
            148 => '\u{00F6}',
            149 => '\u{00F2}',
            150 => '\u{00FB}',
            151 => '\u{00F9}',
            152 => '\u{00FF}',
            153 => '\u{00D6}',
            154 => '\u{00DC}',
            155 => '\u{00A2}',
            156 => '\u{00A3}',
            157 => '\u{00A5}',
            158 => '\u{20A7}',
            159 => '\u{0192}',
            160 => '\u{00E1}',
            161 => '\u{00ED}',
            162 => '\u{00F3}',
            163 => '\u{00FA}',
            164 => '\u{00F1}',
            165 => '\u{00D1}',
            166 => '\u{00AA}',
            167 => '\u{00BA}',
            168 => '\u{00BF}',
            169 => '\u{2310}',
            170 => '\u{00AC}',
            171 => '\u{00BD}',
            172 => '\u{00BC}',
            173 => '\u{00A1}',
            174 => '\u{00AB}',
            175 => '\u{00BB}',
            176 => '\u{2591}',
            177 => '\u{2592}',
            178 => '\u{2593}',
            179 => '\u{2502}',
            180 => '\u{2524}',
            181 => '\u{2561}',
            182 => '\u{2562}',
            183 => '\u{2556}',
            184 => '\u{2555}',
            185 => '\u{2563}',
            186 => '\u{2551}',
            187 => '\u{2557}',
            188 => '\u{255D}',
            189 => '\u{255C}',
            190 => '\u{255B}',
            191 => '\u{2510}',
            192 => '\u{2514}',
            193 => '\u{2534}',
            194 => '\u{252C}',
            195 => '\u{251C}',
            196 => '\u{2500}',
            197 => '\u{253C}',
            198 => '\u{255E}',
            199 => '\u{255F}',
            200 => '\u{255A}',
            201 => '\u{2554}',
            202 => '\u{2569}',
            203 => '\u{2566}',
            204 => '\u{2560}',
            205 => '\u{2550}',
            206 => '\u{256C}',
            207 => '\u{2567}',
            208 => '\u{2568}',
            209 => '\u{2564}',
            210 => '\u{2565}',
            211 => '\u{2559}',
            212 => '\u{2558}',
            213 => '\u{2552}',
            214 => '\u{2553}',
            215 => '\u{256B}',
            216 => '\u{256A}',
            217 => '\u{2518}',
            218 => '\u{250C}',
            219 => '\u{2588}',
            220 => '\u{2584}',
            221 => '\u{258C}',
            222 => '\u{2590}',
            223 => '\u{2580}',
            224 => '\u{03B1}',
            225 => '\u{00DF}',
            226 => '\u{0393}',
            227 => '\u{03C0}',
            228 => '\u{03A3}',
            229 => '\u{03C3}',
            230 => '\u{00B5}',
            231 => '\u{03C4}',
            232 => '\u{03A6}',
            233 => '\u{0398}',
            234 => '\u{03A9}',
            235 => '\u{03B4}',
            236 => '\u{221E}',
            237 => '\u{03C6}',
            238 => '\u{03B5}',
            239 => '\u{2229}',
            240 => '\u{2261}',
            241 => '\u{00B1}',
            242 => '\u{2265}',
            243 => '\u{2264}',
            244 => '\u{2320}',
            245 => '\u{2321}',
            246 => '\u{00F7}',
            247 => '\u{2248}',
            248 => '\u{00B0}',
            249 => '\u{2219}',
            250 => '\u{00B7}',
            251 => '\u{221A}',
            252 => '\u{207F}',
            253 => '\u{00B2}',
            254 => '\u{25A0}',
            0 | 255 => '\u{0020}',
            _ => byte as char,
        };
        CP437Char { byte, ch }
    }
}

impl TryFrom<char> for CP437Char {
    type Error = CP437Error;

    fn try_from(ch: char) -> Result<Self, Self::Error> {
        let unicode = ch as u32;
        match unicode {
            0x263A => Ok(CP437Char { byte: 1, ch }),
            0x263B => Ok(CP437Char { byte: 2, ch }),
            0x2665 => Ok(CP437Char { byte: 3, ch }),
            0x2666 => Ok(CP437Char { byte: 4, ch }),
            0x2663 => Ok(CP437Char { byte: 5, ch }),
            0x2660 => Ok(CP437Char { byte: 6, ch }),
            0x2022 => Ok(CP437Char { byte: 7, ch }),
            0x25D8 => Ok(CP437Char { byte: 8, ch }),
            0x25CB => Ok(CP437Char { byte: 9, ch }),
            0x25D9 => Ok(CP437Char { byte: 10, ch }),
            0x2642 => Ok(CP437Char { byte: 11, ch }),
            0x2640 => Ok(CP437Char { byte: 12, ch }),
            0x266A => Ok(CP437Char { byte: 13, ch }),
            0x266B => Ok(CP437Char { byte: 14, ch }),
            0x263C => Ok(CP437Char { byte: 15, ch }),
            0x25BA => Ok(CP437Char { byte: 16, ch }),
            0x25C4 => Ok(CP437Char { byte: 17, ch }),
            0x2195 => Ok(CP437Char { byte: 18, ch }),
            0x203C => Ok(CP437Char { byte: 19, ch }),
            0x00B6 => Ok(CP437Char { byte: 20, ch }),
            0x00A7 => Ok(CP437Char { byte: 21, ch }),
            0x25AC => Ok(CP437Char { byte: 22, ch }),
            0x21A8 => Ok(CP437Char { byte: 23, ch }),
            0x2191 => Ok(CP437Char { byte: 24, ch }),
            0x2193 => Ok(CP437Char { byte: 25, ch }),
            0x2192 => Ok(CP437Char { byte: 26, ch }),
            0x2190 => Ok(CP437Char { byte: 27, ch }),
            0x221F => Ok(CP437Char { byte: 28, ch }),
            0x2194 => Ok(CP437Char { byte: 29, ch }),
            0x25B2 => Ok(CP437Char { byte: 30, ch }),
            0x25BC => Ok(CP437Char { byte: 31, ch }),
            0x2302 => Ok(CP437Char { byte: 127, ch }),
            0x00C7 => Ok(CP437Char { byte: 128, ch }),
            0x00FC => Ok(CP437Char { byte: 129, ch }),
            0x00E9 => Ok(CP437Char { byte: 130, ch }),
            0x00E2 => Ok(CP437Char { byte: 131, ch }),
            0x00E4 => Ok(CP437Char { byte: 132, ch }),
            0x00E0 => Ok(CP437Char { byte: 133, ch }),
            0x00E5 => Ok(CP437Char { byte: 134, ch }),
            0x00E7 => Ok(CP437Char { byte: 135, ch }),
            0x00EA => Ok(CP437Char { byte: 136, ch }),
            0x00EB => Ok(CP437Char { byte: 137, ch }),
            0x00E8 => Ok(CP437Char { byte: 138, ch }),
            0x00EF => Ok(CP437Char { byte: 139, ch }),
            0x00EE => Ok(CP437Char { byte: 140, ch }),
            0x00EC => Ok(CP437Char { byte: 141, ch }),
            0x00C4 => Ok(CP437Char { byte: 142, ch }),
            0x00C5 => Ok(CP437Char { byte: 143, ch }),
            0x00C9 => Ok(CP437Char { byte: 144, ch }),
            0x00E6 => Ok(CP437Char { byte: 145, ch }),
            0x00C6 => Ok(CP437Char { byte: 146, ch }),
            0x00F4 => Ok(CP437Char { byte: 147, ch }),
            0x00F6 => Ok(CP437Char { byte: 148, ch }),
            0x00F2 => Ok(CP437Char { byte: 149, ch }),
            0x00FB => Ok(CP437Char { byte: 150, ch }),
            0x00F9 => Ok(CP437Char { byte: 151, ch }),
            0x00FF => Ok(CP437Char { byte: 152, ch }),
            0x00D6 => Ok(CP437Char { byte: 153, ch }),
            0x00DC => Ok(CP437Char { byte: 154, ch }),
            0x00A2 => Ok(CP437Char { byte: 155, ch }),
            0x00A3 => Ok(CP437Char { byte: 156, ch }),
            0x00A5 => Ok(CP437Char { byte: 157, ch }),
            0x20A7 => Ok(CP437Char { byte: 158, ch }),
            0x0192 => Ok(CP437Char { byte: 159, ch }),
            0x00E1 => Ok(CP437Char { byte: 160, ch }),
            0x00ED => Ok(CP437Char { byte: 161, ch }),
            0x00F3 => Ok(CP437Char { byte: 162, ch }),
            0x00FA => Ok(CP437Char { byte: 163, ch }),
            0x00F1 => Ok(CP437Char { byte: 164, ch }),
            0x00D1 => Ok(CP437Char { byte: 165, ch }),
            0x00AA => Ok(CP437Char { byte: 166, ch }),
            0x00BA => Ok(CP437Char { byte: 167, ch }),
            0x00BF => Ok(CP437Char { byte: 168, ch }),
            0x2310 => Ok(CP437Char { byte: 169, ch }),
            0x00AC => Ok(CP437Char { byte: 170, ch }),
            0x00BD => Ok(CP437Char { byte: 171, ch }),
            0x00BC => Ok(CP437Char { byte: 172, ch }),
            0x00A1 => Ok(CP437Char { byte: 173, ch }),
            0x00AB => Ok(CP437Char { byte: 174, ch }),
            0x00BB => Ok(CP437Char { byte: 175, ch }),
            0x2591 => Ok(CP437Char { byte: 176, ch }),
            0x2592 => Ok(CP437Char { byte: 177, ch }),
            0x2593 => Ok(CP437Char { byte: 178, ch }),
            0x2502 => Ok(CP437Char { byte: 179, ch }),
            0x2524 => Ok(CP437Char { byte: 180, ch }),
            0x2561 => Ok(CP437Char { byte: 181, ch }),
            0x2562 => Ok(CP437Char { byte: 182, ch }),
            0x2556 => Ok(CP437Char { byte: 183, ch }),
            0x2555 => Ok(CP437Char { byte: 184, ch }),
            0x2563 => Ok(CP437Char { byte: 185, ch }),
            0x2551 => Ok(CP437Char { byte: 186, ch }),
            0x2557 => Ok(CP437Char { byte: 187, ch }),
            0x255D => Ok(CP437Char { byte: 188, ch }),
            0x255C => Ok(CP437Char { byte: 189, ch }),
            0x255B => Ok(CP437Char { byte: 190, ch }),
            0x2510 => Ok(CP437Char { byte: 191, ch }),
            0x2514 => Ok(CP437Char { byte: 192, ch }),
            0x2534 => Ok(CP437Char { byte: 193, ch }),
            0x252C => Ok(CP437Char { byte: 194, ch }),
            0x251C => Ok(CP437Char { byte: 195, ch }),
            0x2500 => Ok(CP437Char { byte: 196, ch }),
            0x253C => Ok(CP437Char { byte: 197, ch }),
            0x255E => Ok(CP437Char { byte: 198, ch }),
            0x255F => Ok(CP437Char { byte: 199, ch }),
            0x255A => Ok(CP437Char { byte: 200, ch }),
            0x2554 => Ok(CP437Char { byte: 201, ch }),
            0x2569 => Ok(CP437Char { byte: 202, ch }),
            0x2566 => Ok(CP437Char { byte: 203, ch }),
            0x2560 => Ok(CP437Char { byte: 204, ch }),
            0x2550 => Ok(CP437Char { byte: 205, ch }),
            0x256C => Ok(CP437Char { byte: 206, ch }),
            0x2567 => Ok(CP437Char { byte: 207, ch }),
            0x2568 => Ok(CP437Char { byte: 208, ch }),
            0x2564 => Ok(CP437Char { byte: 209, ch }),
            0x2565 => Ok(CP437Char { byte: 210, ch }),
            0x2559 => Ok(CP437Char { byte: 211, ch }),
            0x2558 => Ok(CP437Char { byte: 212, ch }),
            0x2552 => Ok(CP437Char { byte: 213, ch }),
            0x2553 => Ok(CP437Char { byte: 214, ch }),
            0x256B => Ok(CP437Char { byte: 215, ch }),
            0x256A => Ok(CP437Char { byte: 216, ch }),
            0x2518 => Ok(CP437Char { byte: 217, ch }),
            0x250C => Ok(CP437Char { byte: 218, ch }),
            0x2588 => Ok(CP437Char { byte: 219, ch }),
            0x2584 => Ok(CP437Char { byte: 220, ch }),
            0x258C => Ok(CP437Char { byte: 221, ch }),
            0x2590 => Ok(CP437Char { byte: 222, ch }),
            0x2580 => Ok(CP437Char { byte: 223, ch }),
            0x03B1 => Ok(CP437Char { byte: 224, ch }),
            0x00DF => Ok(CP437Char { byte: 225, ch }),
            0x0393 => Ok(CP437Char { byte: 226, ch }),
            0x03C0 => Ok(CP437Char { byte: 227, ch }),
            0x03A3 => Ok(CP437Char { byte: 228, ch }),
            0x03C3 => Ok(CP437Char { byte: 229, ch }),
            0x00B5 => Ok(CP437Char { byte: 230, ch }),
            0x03C4 => Ok(CP437Char { byte: 231, ch }),
            0x03A6 => Ok(CP437Char { byte: 232, ch }),
            0x0398 => Ok(CP437Char { byte: 233, ch }),
            0x03A9 => Ok(CP437Char { byte: 234, ch }),
            0x03B4 => Ok(CP437Char { byte: 235, ch }),
            0x221E => Ok(CP437Char { byte: 236, ch }),
            0x03C6 => Ok(CP437Char { byte: 237, ch }),
            0x03B5 => Ok(CP437Char { byte: 238, ch }),
            0x2229 => Ok(CP437Char { byte: 239, ch }),
            0x2261 => Ok(CP437Char { byte: 240, ch }),
            0x00B1 => Ok(CP437Char { byte: 241, ch }),
            0x2265 => Ok(CP437Char { byte: 242, ch }),
            0x2264 => Ok(CP437Char { byte: 243, ch }),
            0x2320 => Ok(CP437Char { byte: 244, ch }),
            0x2321 => Ok(CP437Char { byte: 245, ch }),
            0x00F7 => Ok(CP437Char { byte: 246, ch }),
            0x2248 => Ok(CP437Char { byte: 247, ch }),
            0x00B0 => Ok(CP437Char { byte: 248, ch }),
            0x2219 => Ok(CP437Char { byte: 249, ch }),
            0x00B7 => Ok(CP437Char { byte: 250, ch }),
            0x221A => Ok(CP437Char { byte: 251, ch }),
            0x207F => Ok(CP437Char { byte: 252, ch }),
            0x00B2 => Ok(CP437Char { byte: 253, ch }),
            0x25A0 => Ok(CP437Char { byte: 254, ch }),
            _ if unicode < 128 => Ok(CP437Char {
                byte: unicode as u8,
                ch,
            }),
            _ => Err(CP437Error::NoEquivalentGlyph),
        }
    }
}

impl fmt::Display for CP437Char {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.ch)
    }
}

impl Serialize for CP437Char {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_char(self.ch)
    }
}

struct CharVisitor;

impl<'de> de::Visitor<'de> for CharVisitor {
    type Value = CP437Char;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str("expecting a char")
    }

    fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
    where
        E: de::Error,
    {
        match CP437Char::try_from(value) {
            Ok(cp437) => Ok(cp437),
            Err(err) => Err(E::custom(err)),
        }
    }
}

impl<'de> Deserialize<'de> for CP437Char {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_char(CharVisitor)
    }
}

#[cfg(test)]
mod test {
    use crate::cp437::CP437Char;
    use serde_json::to_string;
    #[test]
    fn test() {
        let a = CP437Char::try_from('').expect("cp437 string");
        let b = CP437Char::from(1);
        assert_eq!(a, b);
        assert_eq!(to_string(&a).unwrap(), "\"\"")
    }
}