Skip to main content

badterm_core/
codepage.rs

1//! The code pages behind CTerm's built-in fonts (IDs 1-31): what a byte in
2//! one is as Unicode, and back, for typing, pasting and copying text when
3//! the BBS shows its screen in one of them. Bytes below 0x80 are ASCII in
4//! all of them. Generated from Python's codec tables; haik8 (7), ARMSCII-8
5//! (15) and CP1131 (31) aren't among them, and stay CP437.
6
7/// A code page's upper half: the character each byte 0x80-0xFF is.
8#[derive(Debug)]
9pub struct CodePage {
10    pub name: &'static str,
11    upper: [char; 128],
12}
13
14impl CodePage {
15    /// A byte as Unicode (control bytes below 0x20 aren't characters here).
16    pub fn decode(&self, b: u8) -> char {
17        if b < 0x80 { b as char } else { self.upper[(b - 0x80) as usize] }
18    }
19
20    /// A character as a byte of this code page, if it has one.
21    pub fn encode(&self, c: char) -> Option<u8> {
22        if (c as u32) < 0x80 {
23            return Some(c as u8);
24        }
25        self.upper.iter().position(|&u| u == c).map(|i| 0x80 + i as u8)
26    }
27
28    pub fn encode_str(&self, s: &str) -> Vec<u8> {
29        s.chars().map(|c| self.encode(c).unwrap_or(b'?')).collect()
30    }
31}
32
33/// The code page a CTerm font ID shows, if BadTerm knows it.
34pub fn for_font(id: u8) -> Option<&'static CodePage> {
35    Some(match id {
36        1 | 20 => &CP1251,
37        2 | 12 | 22 => &KOI8_R,
38        3 => &ISO_8859_2,
39        4 | 11 | 13 | 23 => &ISO_8859_4,
40        5 | 25 | 27 => &CP866,
41        6 => &ISO_8859_9,
42        8 => &ISO_8859_8,
43        9 => &KOI8_U,
44        10 | 16 => &ISO_8859_15,
45        14 => &ISO_8859_5,
46        17 | 18 => &CP850,
47        19 | 28 => &CP865,
48        21 => &ISO_8859_7,
49        24 | 30 => &ISO_8859_1,
50        29 => &CP866U,
51        _ => return None,
52    })
53}
54
55static CP1251: CodePage = CodePage {
56    name: "Windows-1251, Cyrillic",
57    upper: [
58        '\u{402}', '\u{403}', '\u{201a}', '\u{453}', '\u{201e}', '\u{2026}', '\u{2020}', '\u{2021}', '\u{20ac}',
59        '\u{2030}', '\u{409}', '\u{2039}', '\u{40a}', '\u{40c}', '\u{40b}', '\u{40f}', '\u{452}', '\u{2018}',
60        '\u{2019}', '\u{201c}', '\u{201d}', '\u{2022}', '\u{2013}', '\u{2014}', '\u{fffd}', '\u{2122}', '\u{459}',
61        '\u{203a}', '\u{45a}', '\u{45c}', '\u{45b}', '\u{45f}', '\u{a0}', '\u{40e}', '\u{45e}', '\u{408}', '\u{a4}',
62        '\u{490}', '\u{a6}', '\u{a7}', '\u{401}', '\u{a9}', '\u{404}', '\u{ab}', '\u{ac}', '\u{ad}', '\u{ae}',
63        '\u{407}', '\u{b0}', '\u{b1}', '\u{406}', '\u{456}', '\u{491}', '\u{b5}', '\u{b6}', '\u{b7}', '\u{451}',
64        '\u{2116}', '\u{454}', '\u{bb}', '\u{458}', '\u{405}', '\u{455}', '\u{457}', '\u{410}', '\u{411}', '\u{412}',
65        '\u{413}', '\u{414}', '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}',
66        '\u{41d}', '\u{41e}', '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{424}', '\u{425}', '\u{426}',
67        '\u{427}', '\u{428}', '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}', '\u{42e}', '\u{42f}', '\u{430}',
68        '\u{431}', '\u{432}', '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}', '\u{438}', '\u{439}', '\u{43a}',
69        '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}',
70        '\u{445}', '\u{446}', '\u{447}', '\u{448}', '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}',
71        '\u{44f}',
72    ],
73};
74
75static KOI8_R: CodePage = CodePage {
76    name: "KOI8-R, Russian",
77    upper: [
78        '\u{2500}', '\u{2502}', '\u{250c}', '\u{2510}', '\u{2514}', '\u{2518}', '\u{251c}', '\u{2524}', '\u{252c}',
79        '\u{2534}', '\u{253c}', '\u{2580}', '\u{2584}', '\u{2588}', '\u{258c}', '\u{2590}', '\u{2591}', '\u{2592}',
80        '\u{2593}', '\u{2320}', '\u{25a0}', '\u{2219}', '\u{221a}', '\u{2248}', '\u{2264}', '\u{2265}', '\u{a0}',
81        '\u{2321}', '\u{b0}', '\u{b2}', '\u{b7}', '\u{f7}', '\u{2550}', '\u{2551}', '\u{2552}', '\u{451}', '\u{2553}',
82        '\u{2554}', '\u{2555}', '\u{2556}', '\u{2557}', '\u{2558}', '\u{2559}', '\u{255a}', '\u{255b}', '\u{255c}',
83        '\u{255d}', '\u{255e}', '\u{255f}', '\u{2560}', '\u{2561}', '\u{401}', '\u{2562}', '\u{2563}', '\u{2564}',
84        '\u{2565}', '\u{2566}', '\u{2567}', '\u{2568}', '\u{2569}', '\u{256a}', '\u{256b}', '\u{256c}', '\u{a9}',
85        '\u{44e}', '\u{430}', '\u{431}', '\u{446}', '\u{434}', '\u{435}', '\u{444}', '\u{433}', '\u{445}', '\u{438}',
86        '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{44f}', '\u{440}', '\u{441}',
87        '\u{442}', '\u{443}', '\u{436}', '\u{432}', '\u{44c}', '\u{44b}', '\u{437}', '\u{448}', '\u{44d}', '\u{449}',
88        '\u{447}', '\u{44a}', '\u{42e}', '\u{410}', '\u{411}', '\u{426}', '\u{414}', '\u{415}', '\u{424}', '\u{413}',
89        '\u{425}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{42f}',
90        '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{416}', '\u{412}', '\u{42c}', '\u{42b}', '\u{417}', '\u{428}',
91        '\u{42d}', '\u{429}', '\u{427}', '\u{42a}',
92    ],
93};
94
95static ISO_8859_2: CodePage = CodePage {
96    name: "ISO-8859-2, Central European",
97    upper: [
98        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
99        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
100        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
101        '\u{104}', '\u{2d8}', '\u{141}', '\u{a4}', '\u{13d}', '\u{15a}', '\u{a7}', '\u{a8}', '\u{160}', '\u{15e}',
102        '\u{164}', '\u{179}', '\u{ad}', '\u{17d}', '\u{17b}', '\u{b0}', '\u{105}', '\u{2db}', '\u{142}', '\u{b4}',
103        '\u{13e}', '\u{15b}', '\u{2c7}', '\u{b8}', '\u{161}', '\u{15f}', '\u{165}', '\u{17a}', '\u{2dd}', '\u{17e}',
104        '\u{17c}', '\u{154}', '\u{c1}', '\u{c2}', '\u{102}', '\u{c4}', '\u{139}', '\u{106}', '\u{c7}', '\u{10c}',
105        '\u{c9}', '\u{118}', '\u{cb}', '\u{11a}', '\u{cd}', '\u{ce}', '\u{10e}', '\u{110}', '\u{143}', '\u{147}',
106        '\u{d3}', '\u{d4}', '\u{150}', '\u{d6}', '\u{d7}', '\u{158}', '\u{16e}', '\u{da}', '\u{170}', '\u{dc}',
107        '\u{dd}', '\u{162}', '\u{df}', '\u{155}', '\u{e1}', '\u{e2}', '\u{103}', '\u{e4}', '\u{13a}', '\u{107}',
108        '\u{e7}', '\u{10d}', '\u{e9}', '\u{119}', '\u{eb}', '\u{11b}', '\u{ed}', '\u{ee}', '\u{10f}', '\u{111}',
109        '\u{144}', '\u{148}', '\u{f3}', '\u{f4}', '\u{151}', '\u{f6}', '\u{f7}', '\u{159}', '\u{16f}', '\u{fa}',
110        '\u{171}', '\u{fc}', '\u{fd}', '\u{163}', '\u{2d9}',
111    ],
112};
113
114static ISO_8859_4: CodePage = CodePage {
115    name: "ISO-8859-4, Baltic",
116    upper: [
117        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
118        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
119        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
120        '\u{104}', '\u{138}', '\u{156}', '\u{a4}', '\u{128}', '\u{13b}', '\u{a7}', '\u{a8}', '\u{160}', '\u{112}',
121        '\u{122}', '\u{166}', '\u{ad}', '\u{17d}', '\u{af}', '\u{b0}', '\u{105}', '\u{2db}', '\u{157}', '\u{b4}',
122        '\u{129}', '\u{13c}', '\u{2c7}', '\u{b8}', '\u{161}', '\u{113}', '\u{123}', '\u{167}', '\u{14a}', '\u{17e}',
123        '\u{14b}', '\u{100}', '\u{c1}', '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{12e}', '\u{10c}',
124        '\u{c9}', '\u{118}', '\u{cb}', '\u{116}', '\u{cd}', '\u{ce}', '\u{12a}', '\u{110}', '\u{145}', '\u{14c}',
125        '\u{136}', '\u{d4}', '\u{d5}', '\u{d6}', '\u{d7}', '\u{d8}', '\u{172}', '\u{da}', '\u{db}', '\u{dc}',
126        '\u{168}', '\u{16a}', '\u{df}', '\u{101}', '\u{e1}', '\u{e2}', '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}',
127        '\u{12f}', '\u{10d}', '\u{e9}', '\u{119}', '\u{eb}', '\u{117}', '\u{ed}', '\u{ee}', '\u{12b}', '\u{111}',
128        '\u{146}', '\u{14d}', '\u{137}', '\u{f4}', '\u{f5}', '\u{f6}', '\u{f7}', '\u{f8}', '\u{173}', '\u{fa}',
129        '\u{fb}', '\u{fc}', '\u{169}', '\u{16b}', '\u{2d9}',
130    ],
131};
132
133static CP866: CodePage = CodePage {
134    name: "CP866, Russian",
135    upper: [
136        '\u{410}', '\u{411}', '\u{412}', '\u{413}', '\u{414}', '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}',
137        '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}',
138        '\u{424}', '\u{425}', '\u{426}', '\u{427}', '\u{428}', '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}',
139        '\u{42e}', '\u{42f}', '\u{430}', '\u{431}', '\u{432}', '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}',
140        '\u{438}', '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{2591}', '\u{2592}',
141        '\u{2593}', '\u{2502}', '\u{2524}', '\u{2561}', '\u{2562}', '\u{2556}', '\u{2555}', '\u{2563}', '\u{2551}',
142        '\u{2557}', '\u{255d}', '\u{255c}', '\u{255b}', '\u{2510}', '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}',
143        '\u{2500}', '\u{253c}', '\u{255e}', '\u{255f}', '\u{255a}', '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}',
144        '\u{2550}', '\u{256c}', '\u{2567}', '\u{2568}', '\u{2564}', '\u{2565}', '\u{2559}', '\u{2558}', '\u{2552}',
145        '\u{2553}', '\u{256b}', '\u{256a}', '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}', '\u{258c}', '\u{2590}',
146        '\u{2580}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}', '\u{445}', '\u{446}', '\u{447}', '\u{448}',
147        '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}', '\u{44f}', '\u{401}', '\u{451}', '\u{404}',
148        '\u{454}', '\u{407}', '\u{457}', '\u{40e}', '\u{45e}', '\u{b0}', '\u{2219}', '\u{b7}', '\u{221a}', '\u{2116}',
149        '\u{a4}', '\u{25a0}', '\u{a0}',
150    ],
151};
152
153static ISO_8859_9: CodePage = CodePage {
154    name: "ISO-8859-9, Turkish",
155    upper: [
156        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
157        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
158        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
159        '\u{a1}', '\u{a2}', '\u{a3}', '\u{a4}', '\u{a5}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{aa}', '\u{ab}',
160        '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{b4}', '\u{b5}', '\u{b6}',
161        '\u{b7}', '\u{b8}', '\u{b9}', '\u{ba}', '\u{bb}', '\u{bc}', '\u{bd}', '\u{be}', '\u{bf}', '\u{c0}', '\u{c1}',
162        '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{c7}', '\u{c8}', '\u{c9}', '\u{ca}', '\u{cb}', '\u{cc}',
163        '\u{cd}', '\u{ce}', '\u{cf}', '\u{11e}', '\u{d1}', '\u{d2}', '\u{d3}', '\u{d4}', '\u{d5}', '\u{d6}', '\u{d7}',
164        '\u{d8}', '\u{d9}', '\u{da}', '\u{db}', '\u{dc}', '\u{130}', '\u{15e}', '\u{df}', '\u{e0}', '\u{e1}', '\u{e2}',
165        '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}', '\u{e7}', '\u{e8}', '\u{e9}', '\u{ea}', '\u{eb}', '\u{ec}', '\u{ed}',
166        '\u{ee}', '\u{ef}', '\u{11f}', '\u{f1}', '\u{f2}', '\u{f3}', '\u{f4}', '\u{f5}', '\u{f6}', '\u{f7}', '\u{f8}',
167        '\u{f9}', '\u{fa}', '\u{fb}', '\u{fc}', '\u{131}', '\u{15f}', '\u{ff}',
168    ],
169};
170
171static ISO_8859_8: CodePage = CodePage {
172    name: "ISO-8859-8, Hebrew",
173    upper: [
174        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
175        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
176        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
177        '\u{fffd}', '\u{a2}', '\u{a3}', '\u{a4}', '\u{a5}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{d7}', '\u{ab}',
178        '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{b4}', '\u{b5}', '\u{b6}',
179        '\u{b7}', '\u{b8}', '\u{b9}', '\u{f7}', '\u{bb}', '\u{bc}', '\u{bd}', '\u{be}', '\u{fffd}', '\u{fffd}',
180        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}',
181        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}',
182        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}',
183        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{2017}', '\u{5d0}', '\u{5d1}', '\u{5d2}', '\u{5d3}', '\u{5d4}',
184        '\u{5d5}', '\u{5d6}', '\u{5d7}', '\u{5d8}', '\u{5d9}', '\u{5da}', '\u{5db}', '\u{5dc}', '\u{5dd}', '\u{5de}',
185        '\u{5df}', '\u{5e0}', '\u{5e1}', '\u{5e2}', '\u{5e3}', '\u{5e4}', '\u{5e5}', '\u{5e6}', '\u{5e7}', '\u{5e8}',
186        '\u{5e9}', '\u{5ea}', '\u{fffd}', '\u{fffd}', '\u{200e}', '\u{200f}', '\u{fffd}',
187    ],
188};
189
190static KOI8_U: CodePage = CodePage {
191    name: "KOI8-U, Ukrainian",
192    upper: [
193        '\u{2500}', '\u{2502}', '\u{250c}', '\u{2510}', '\u{2514}', '\u{2518}', '\u{251c}', '\u{2524}', '\u{252c}',
194        '\u{2534}', '\u{253c}', '\u{2580}', '\u{2584}', '\u{2588}', '\u{258c}', '\u{2590}', '\u{2591}', '\u{2592}',
195        '\u{2593}', '\u{2320}', '\u{25a0}', '\u{2219}', '\u{221a}', '\u{2248}', '\u{2264}', '\u{2265}', '\u{a0}',
196        '\u{2321}', '\u{b0}', '\u{b2}', '\u{b7}', '\u{f7}', '\u{2550}', '\u{2551}', '\u{2552}', '\u{451}', '\u{454}',
197        '\u{2554}', '\u{456}', '\u{457}', '\u{2557}', '\u{2558}', '\u{2559}', '\u{255a}', '\u{255b}', '\u{491}',
198        '\u{255d}', '\u{255e}', '\u{255f}', '\u{2560}', '\u{2561}', '\u{401}', '\u{404}', '\u{2563}', '\u{406}',
199        '\u{407}', '\u{2566}', '\u{2567}', '\u{2568}', '\u{2569}', '\u{256a}', '\u{490}', '\u{256c}', '\u{a9}',
200        '\u{44e}', '\u{430}', '\u{431}', '\u{446}', '\u{434}', '\u{435}', '\u{444}', '\u{433}', '\u{445}', '\u{438}',
201        '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{44f}', '\u{440}', '\u{441}',
202        '\u{442}', '\u{443}', '\u{436}', '\u{432}', '\u{44c}', '\u{44b}', '\u{437}', '\u{448}', '\u{44d}', '\u{449}',
203        '\u{447}', '\u{44a}', '\u{42e}', '\u{410}', '\u{411}', '\u{426}', '\u{414}', '\u{415}', '\u{424}', '\u{413}',
204        '\u{425}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{42f}',
205        '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{416}', '\u{412}', '\u{42c}', '\u{42b}', '\u{417}', '\u{428}',
206        '\u{42d}', '\u{429}', '\u{427}', '\u{42a}',
207    ],
208};
209
210static ISO_8859_15: CodePage = CodePage {
211    name: "ISO-8859-15, West European",
212    upper: [
213        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
214        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
215        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
216        '\u{a1}', '\u{a2}', '\u{a3}', '\u{20ac}', '\u{a5}', '\u{160}', '\u{a7}', '\u{161}', '\u{a9}', '\u{aa}',
217        '\u{ab}', '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{17d}', '\u{b5}',
218        '\u{b6}', '\u{b7}', '\u{17e}', '\u{b9}', '\u{ba}', '\u{bb}', '\u{152}', '\u{153}', '\u{178}', '\u{bf}',
219        '\u{c0}', '\u{c1}', '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{c7}', '\u{c8}', '\u{c9}', '\u{ca}',
220        '\u{cb}', '\u{cc}', '\u{cd}', '\u{ce}', '\u{cf}', '\u{d0}', '\u{d1}', '\u{d2}', '\u{d3}', '\u{d4}', '\u{d5}',
221        '\u{d6}', '\u{d7}', '\u{d8}', '\u{d9}', '\u{da}', '\u{db}', '\u{dc}', '\u{dd}', '\u{de}', '\u{df}', '\u{e0}',
222        '\u{e1}', '\u{e2}', '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}', '\u{e7}', '\u{e8}', '\u{e9}', '\u{ea}', '\u{eb}',
223        '\u{ec}', '\u{ed}', '\u{ee}', '\u{ef}', '\u{f0}', '\u{f1}', '\u{f2}', '\u{f3}', '\u{f4}', '\u{f5}', '\u{f6}',
224        '\u{f7}', '\u{f8}', '\u{f9}', '\u{fa}', '\u{fb}', '\u{fc}', '\u{fd}', '\u{fe}', '\u{ff}',
225    ],
226};
227
228static ISO_8859_5: CodePage = CodePage {
229    name: "ISO-8859-5, Cyrillic",
230    upper: [
231        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
232        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
233        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
234        '\u{401}', '\u{402}', '\u{403}', '\u{404}', '\u{405}', '\u{406}', '\u{407}', '\u{408}', '\u{409}', '\u{40a}',
235        '\u{40b}', '\u{40c}', '\u{ad}', '\u{40e}', '\u{40f}', '\u{410}', '\u{411}', '\u{412}', '\u{413}', '\u{414}',
236        '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}',
237        '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{424}', '\u{425}', '\u{426}', '\u{427}', '\u{428}',
238        '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}', '\u{42e}', '\u{42f}', '\u{430}', '\u{431}', '\u{432}',
239        '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}', '\u{438}', '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}',
240        '\u{43d}', '\u{43e}', '\u{43f}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}', '\u{445}', '\u{446}',
241        '\u{447}', '\u{448}', '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}', '\u{44f}', '\u{2116}',
242        '\u{451}', '\u{452}', '\u{453}', '\u{454}', '\u{455}', '\u{456}', '\u{457}', '\u{458}', '\u{459}', '\u{45a}',
243        '\u{45b}', '\u{45c}', '\u{a7}', '\u{45e}', '\u{45f}',
244    ],
245};
246
247static CP850: CodePage = CodePage {
248    name: "CP850, Latin I",
249    upper: [
250        '\u{c7}', '\u{fc}', '\u{e9}', '\u{e2}', '\u{e4}', '\u{e0}', '\u{e5}', '\u{e7}', '\u{ea}', '\u{eb}', '\u{e8}',
251        '\u{ef}', '\u{ee}', '\u{ec}', '\u{c4}', '\u{c5}', '\u{c9}', '\u{e6}', '\u{c6}', '\u{f4}', '\u{f6}', '\u{f2}',
252        '\u{fb}', '\u{f9}', '\u{ff}', '\u{d6}', '\u{dc}', '\u{f8}', '\u{a3}', '\u{d8}', '\u{d7}', '\u{192}', '\u{e1}',
253        '\u{ed}', '\u{f3}', '\u{fa}', '\u{f1}', '\u{d1}', '\u{aa}', '\u{ba}', '\u{bf}', '\u{ae}', '\u{ac}', '\u{bd}',
254        '\u{bc}', '\u{a1}', '\u{ab}', '\u{bb}', '\u{2591}', '\u{2592}', '\u{2593}', '\u{2502}', '\u{2524}', '\u{c1}',
255        '\u{c2}', '\u{c0}', '\u{a9}', '\u{2563}', '\u{2551}', '\u{2557}', '\u{255d}', '\u{a2}', '\u{a5}', '\u{2510}',
256        '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}', '\u{2500}', '\u{253c}', '\u{e3}', '\u{c3}', '\u{255a}',
257        '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}', '\u{2550}', '\u{256c}', '\u{a4}', '\u{f0}', '\u{d0}', '\u{ca}',
258        '\u{cb}', '\u{c8}', '\u{131}', '\u{cd}', '\u{ce}', '\u{cf}', '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}',
259        '\u{a6}', '\u{cc}', '\u{2580}', '\u{d3}', '\u{df}', '\u{d4}', '\u{d2}', '\u{f5}', '\u{d5}', '\u{b5}', '\u{fe}',
260        '\u{de}', '\u{da}', '\u{db}', '\u{d9}', '\u{fd}', '\u{dd}', '\u{af}', '\u{b4}', '\u{ad}', '\u{b1}', '\u{2017}',
261        '\u{be}', '\u{b6}', '\u{a7}', '\u{f7}', '\u{b8}', '\u{b0}', '\u{a8}', '\u{b7}', '\u{b9}', '\u{b3}', '\u{b2}',
262        '\u{25a0}', '\u{a0}',
263    ],
264};
265
266static CP865: CodePage = CodePage {
267    name: "CP865, Nordic",
268    upper: [
269        '\u{c7}', '\u{fc}', '\u{e9}', '\u{e2}', '\u{e4}', '\u{e0}', '\u{e5}', '\u{e7}', '\u{ea}', '\u{eb}', '\u{e8}',
270        '\u{ef}', '\u{ee}', '\u{ec}', '\u{c4}', '\u{c5}', '\u{c9}', '\u{e6}', '\u{c6}', '\u{f4}', '\u{f6}', '\u{f2}',
271        '\u{fb}', '\u{f9}', '\u{ff}', '\u{d6}', '\u{dc}', '\u{f8}', '\u{a3}', '\u{d8}', '\u{20a7}', '\u{192}',
272        '\u{e1}', '\u{ed}', '\u{f3}', '\u{fa}', '\u{f1}', '\u{d1}', '\u{aa}', '\u{ba}', '\u{bf}', '\u{2310}', '\u{ac}',
273        '\u{bd}', '\u{bc}', '\u{a1}', '\u{ab}', '\u{a4}', '\u{2591}', '\u{2592}', '\u{2593}', '\u{2502}', '\u{2524}',
274        '\u{2561}', '\u{2562}', '\u{2556}', '\u{2555}', '\u{2563}', '\u{2551}', '\u{2557}', '\u{255d}', '\u{255c}',
275        '\u{255b}', '\u{2510}', '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}', '\u{2500}', '\u{253c}', '\u{255e}',
276        '\u{255f}', '\u{255a}', '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}', '\u{2550}', '\u{256c}', '\u{2567}',
277        '\u{2568}', '\u{2564}', '\u{2565}', '\u{2559}', '\u{2558}', '\u{2552}', '\u{2553}', '\u{256b}', '\u{256a}',
278        '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}', '\u{258c}', '\u{2590}', '\u{2580}', '\u{3b1}', '\u{df}',
279        '\u{393}', '\u{3c0}', '\u{3a3}', '\u{3c3}', '\u{b5}', '\u{3c4}', '\u{3a6}', '\u{398}', '\u{3a9}', '\u{3b4}',
280        '\u{221e}', '\u{3c6}', '\u{3b5}', '\u{2229}', '\u{2261}', '\u{b1}', '\u{2265}', '\u{2264}', '\u{2320}',
281        '\u{2321}', '\u{f7}', '\u{2248}', '\u{b0}', '\u{2219}', '\u{b7}', '\u{221a}', '\u{207f}', '\u{b2}', '\u{25a0}',
282        '\u{a0}',
283    ],
284};
285
286static ISO_8859_7: CodePage = CodePage {
287    name: "ISO-8859-7, Greek",
288    upper: [
289        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
290        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
291        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
292        '\u{2018}', '\u{2019}', '\u{a3}', '\u{20ac}', '\u{20af}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{37a}',
293        '\u{ab}', '\u{ac}', '\u{ad}', '\u{fffd}', '\u{2015}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{384}',
294        '\u{385}', '\u{386}', '\u{b7}', '\u{388}', '\u{389}', '\u{38a}', '\u{bb}', '\u{38c}', '\u{bd}', '\u{38e}',
295        '\u{38f}', '\u{390}', '\u{391}', '\u{392}', '\u{393}', '\u{394}', '\u{395}', '\u{396}', '\u{397}', '\u{398}',
296        '\u{399}', '\u{39a}', '\u{39b}', '\u{39c}', '\u{39d}', '\u{39e}', '\u{39f}', '\u{3a0}', '\u{3a1}', '\u{fffd}',
297        '\u{3a3}', '\u{3a4}', '\u{3a5}', '\u{3a6}', '\u{3a7}', '\u{3a8}', '\u{3a9}', '\u{3aa}', '\u{3ab}', '\u{3ac}',
298        '\u{3ad}', '\u{3ae}', '\u{3af}', '\u{3b0}', '\u{3b1}', '\u{3b2}', '\u{3b3}', '\u{3b4}', '\u{3b5}', '\u{3b6}',
299        '\u{3b7}', '\u{3b8}', '\u{3b9}', '\u{3ba}', '\u{3bb}', '\u{3bc}', '\u{3bd}', '\u{3be}', '\u{3bf}', '\u{3c0}',
300        '\u{3c1}', '\u{3c2}', '\u{3c3}', '\u{3c4}', '\u{3c5}', '\u{3c6}', '\u{3c7}', '\u{3c8}', '\u{3c9}', '\u{3ca}',
301        '\u{3cb}', '\u{3cc}', '\u{3cd}', '\u{3ce}', '\u{fffd}',
302    ],
303};
304
305static ISO_8859_1: CodePage = CodePage {
306    name: "ISO-8859-1, West European",
307    upper: [
308        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
309        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
310        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
311        '\u{a1}', '\u{a2}', '\u{a3}', '\u{a4}', '\u{a5}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{aa}', '\u{ab}',
312        '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{b4}', '\u{b5}', '\u{b6}',
313        '\u{b7}', '\u{b8}', '\u{b9}', '\u{ba}', '\u{bb}', '\u{bc}', '\u{bd}', '\u{be}', '\u{bf}', '\u{c0}', '\u{c1}',
314        '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{c7}', '\u{c8}', '\u{c9}', '\u{ca}', '\u{cb}', '\u{cc}',
315        '\u{cd}', '\u{ce}', '\u{cf}', '\u{d0}', '\u{d1}', '\u{d2}', '\u{d3}', '\u{d4}', '\u{d5}', '\u{d6}', '\u{d7}',
316        '\u{d8}', '\u{d9}', '\u{da}', '\u{db}', '\u{dc}', '\u{dd}', '\u{de}', '\u{df}', '\u{e0}', '\u{e1}', '\u{e2}',
317        '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}', '\u{e7}', '\u{e8}', '\u{e9}', '\u{ea}', '\u{eb}', '\u{ec}', '\u{ed}',
318        '\u{ee}', '\u{ef}', '\u{f0}', '\u{f1}', '\u{f2}', '\u{f3}', '\u{f4}', '\u{f5}', '\u{f6}', '\u{f7}', '\u{f8}',
319        '\u{f9}', '\u{fa}', '\u{fb}', '\u{fc}', '\u{fd}', '\u{fe}', '\u{ff}',
320    ],
321};
322
323static CP866U: CodePage = CodePage {
324    name: "CP866U (CP1125), Ukrainian",
325    upper: [
326        '\u{410}', '\u{411}', '\u{412}', '\u{413}', '\u{414}', '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}',
327        '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}',
328        '\u{424}', '\u{425}', '\u{426}', '\u{427}', '\u{428}', '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}',
329        '\u{42e}', '\u{42f}', '\u{430}', '\u{431}', '\u{432}', '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}',
330        '\u{438}', '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{2591}', '\u{2592}',
331        '\u{2593}', '\u{2502}', '\u{2524}', '\u{2561}', '\u{2562}', '\u{2556}', '\u{2555}', '\u{2563}', '\u{2551}',
332        '\u{2557}', '\u{255d}', '\u{255c}', '\u{255b}', '\u{2510}', '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}',
333        '\u{2500}', '\u{253c}', '\u{255e}', '\u{255f}', '\u{255a}', '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}',
334        '\u{2550}', '\u{256c}', '\u{2567}', '\u{2568}', '\u{2564}', '\u{2565}', '\u{2559}', '\u{2558}', '\u{2552}',
335        '\u{2553}', '\u{256b}', '\u{256a}', '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}', '\u{258c}', '\u{2590}',
336        '\u{2580}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}', '\u{445}', '\u{446}', '\u{447}', '\u{448}',
337        '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}', '\u{44f}', '\u{401}', '\u{451}', '\u{490}',
338        '\u{491}', '\u{404}', '\u{454}', '\u{406}', '\u{456}', '\u{407}', '\u{457}', '\u{b7}', '\u{221a}', '\u{2116}',
339        '\u{a4}', '\u{25a0}', '\u{a0}',
340    ],
341};
342
343#[cfg(test)]
344mod tests {
345    use super::*;
346
347    #[test]
348    fn cyrillic_both_ways() {
349        let cp866 = for_font(25).unwrap();
350        assert_eq!(cp866.encode_str("Привет!"), [0x8F, 0xE0, 0xA8, 0xA2, 0xA5, 0xE2, b'!']);
351        assert_eq!(cp866.decode(0x8F), 'П');
352        let koi = for_font(2).unwrap();
353        assert_eq!(koi.encode_str("Да"), [0xE4, 0xC1]);
354        assert_eq!(koi.decode(0xC1), 'а');
355        // Not in the code page: a question mark.
356        assert_eq!(for_font(21).unwrap().encode_str("Ω€Ж"), [0xD9, 0xA4, b'?']);
357        assert!(for_font(7).is_none() && for_font(0).is_none());
358    }
359}