badterm-core 0.3.4

Terminal emulation, telnet protocol and dialing directory for the BadTerm BBS client
Documentation
//! The code pages behind CTerm's built-in fonts (IDs 1-31): what a byte in
//! one is as Unicode, and back, for typing, pasting and copying text when
//! the BBS shows its screen in one of them. Bytes below 0x80 are ASCII in
//! all of them. Generated from Python's codec tables; haik8 (7), ARMSCII-8
//! (15) and CP1131 (31) aren't among them, and stay CP437.

/// A code page's upper half: the character each byte 0x80-0xFF is.
#[derive(Debug)]
pub struct CodePage {
    pub name: &'static str,
    upper: [char; 128],
}

impl CodePage {
    /// A byte as Unicode (control bytes below 0x20 aren't characters here).
    pub fn decode(&self, b: u8) -> char {
        if b < 0x80 { b as char } else { self.upper[(b - 0x80) as usize] }
    }

    /// A character as a byte of this code page, if it has one.
    pub fn encode(&self, c: char) -> Option<u8> {
        if (c as u32) < 0x80 {
            return Some(c as u8);
        }
        self.upper.iter().position(|&u| u == c).map(|i| 0x80 + i as u8)
    }

    pub fn encode_str(&self, s: &str) -> Vec<u8> {
        s.chars().map(|c| self.encode(c).unwrap_or(b'?')).collect()
    }
}

/// The code page a CTerm font ID shows, if BadTerm knows it.
pub fn for_font(id: u8) -> Option<&'static CodePage> {
    Some(match id {
        1 | 20 => &CP1251,
        2 | 12 | 22 => &KOI8_R,
        3 => &ISO_8859_2,
        4 | 11 | 13 | 23 => &ISO_8859_4,
        5 | 25 | 27 => &CP866,
        6 => &ISO_8859_9,
        8 => &ISO_8859_8,
        9 => &KOI8_U,
        10 | 16 => &ISO_8859_15,
        14 => &ISO_8859_5,
        17 | 18 => &CP850,
        19 | 28 => &CP865,
        21 => &ISO_8859_7,
        24 | 30 => &ISO_8859_1,
        29 => &CP866U,
        _ => return None,
    })
}

static CP1251: CodePage = CodePage {
    name: "Windows-1251, Cyrillic",
    upper: [
        '\u{402}', '\u{403}', '\u{201a}', '\u{453}', '\u{201e}', '\u{2026}', '\u{2020}', '\u{2021}', '\u{20ac}',
        '\u{2030}', '\u{409}', '\u{2039}', '\u{40a}', '\u{40c}', '\u{40b}', '\u{40f}', '\u{452}', '\u{2018}',
        '\u{2019}', '\u{201c}', '\u{201d}', '\u{2022}', '\u{2013}', '\u{2014}', '\u{fffd}', '\u{2122}', '\u{459}',
        '\u{203a}', '\u{45a}', '\u{45c}', '\u{45b}', '\u{45f}', '\u{a0}', '\u{40e}', '\u{45e}', '\u{408}', '\u{a4}',
        '\u{490}', '\u{a6}', '\u{a7}', '\u{401}', '\u{a9}', '\u{404}', '\u{ab}', '\u{ac}', '\u{ad}', '\u{ae}',
        '\u{407}', '\u{b0}', '\u{b1}', '\u{406}', '\u{456}', '\u{491}', '\u{b5}', '\u{b6}', '\u{b7}', '\u{451}',
        '\u{2116}', '\u{454}', '\u{bb}', '\u{458}', '\u{405}', '\u{455}', '\u{457}', '\u{410}', '\u{411}', '\u{412}',
        '\u{413}', '\u{414}', '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}',
        '\u{41d}', '\u{41e}', '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{424}', '\u{425}', '\u{426}',
        '\u{427}', '\u{428}', '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}', '\u{42e}', '\u{42f}', '\u{430}',
        '\u{431}', '\u{432}', '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}', '\u{438}', '\u{439}', '\u{43a}',
        '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}',
        '\u{445}', '\u{446}', '\u{447}', '\u{448}', '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}',
        '\u{44f}',
    ],
};

static KOI8_R: CodePage = CodePage {
    name: "KOI8-R, Russian",
    upper: [
        '\u{2500}', '\u{2502}', '\u{250c}', '\u{2510}', '\u{2514}', '\u{2518}', '\u{251c}', '\u{2524}', '\u{252c}',
        '\u{2534}', '\u{253c}', '\u{2580}', '\u{2584}', '\u{2588}', '\u{258c}', '\u{2590}', '\u{2591}', '\u{2592}',
        '\u{2593}', '\u{2320}', '\u{25a0}', '\u{2219}', '\u{221a}', '\u{2248}', '\u{2264}', '\u{2265}', '\u{a0}',
        '\u{2321}', '\u{b0}', '\u{b2}', '\u{b7}', '\u{f7}', '\u{2550}', '\u{2551}', '\u{2552}', '\u{451}', '\u{2553}',
        '\u{2554}', '\u{2555}', '\u{2556}', '\u{2557}', '\u{2558}', '\u{2559}', '\u{255a}', '\u{255b}', '\u{255c}',
        '\u{255d}', '\u{255e}', '\u{255f}', '\u{2560}', '\u{2561}', '\u{401}', '\u{2562}', '\u{2563}', '\u{2564}',
        '\u{2565}', '\u{2566}', '\u{2567}', '\u{2568}', '\u{2569}', '\u{256a}', '\u{256b}', '\u{256c}', '\u{a9}',
        '\u{44e}', '\u{430}', '\u{431}', '\u{446}', '\u{434}', '\u{435}', '\u{444}', '\u{433}', '\u{445}', '\u{438}',
        '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{44f}', '\u{440}', '\u{441}',
        '\u{442}', '\u{443}', '\u{436}', '\u{432}', '\u{44c}', '\u{44b}', '\u{437}', '\u{448}', '\u{44d}', '\u{449}',
        '\u{447}', '\u{44a}', '\u{42e}', '\u{410}', '\u{411}', '\u{426}', '\u{414}', '\u{415}', '\u{424}', '\u{413}',
        '\u{425}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{42f}',
        '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{416}', '\u{412}', '\u{42c}', '\u{42b}', '\u{417}', '\u{428}',
        '\u{42d}', '\u{429}', '\u{427}', '\u{42a}',
    ],
};

static ISO_8859_2: CodePage = CodePage {
    name: "ISO-8859-2, Central European",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{104}', '\u{2d8}', '\u{141}', '\u{a4}', '\u{13d}', '\u{15a}', '\u{a7}', '\u{a8}', '\u{160}', '\u{15e}',
        '\u{164}', '\u{179}', '\u{ad}', '\u{17d}', '\u{17b}', '\u{b0}', '\u{105}', '\u{2db}', '\u{142}', '\u{b4}',
        '\u{13e}', '\u{15b}', '\u{2c7}', '\u{b8}', '\u{161}', '\u{15f}', '\u{165}', '\u{17a}', '\u{2dd}', '\u{17e}',
        '\u{17c}', '\u{154}', '\u{c1}', '\u{c2}', '\u{102}', '\u{c4}', '\u{139}', '\u{106}', '\u{c7}', '\u{10c}',
        '\u{c9}', '\u{118}', '\u{cb}', '\u{11a}', '\u{cd}', '\u{ce}', '\u{10e}', '\u{110}', '\u{143}', '\u{147}',
        '\u{d3}', '\u{d4}', '\u{150}', '\u{d6}', '\u{d7}', '\u{158}', '\u{16e}', '\u{da}', '\u{170}', '\u{dc}',
        '\u{dd}', '\u{162}', '\u{df}', '\u{155}', '\u{e1}', '\u{e2}', '\u{103}', '\u{e4}', '\u{13a}', '\u{107}',
        '\u{e7}', '\u{10d}', '\u{e9}', '\u{119}', '\u{eb}', '\u{11b}', '\u{ed}', '\u{ee}', '\u{10f}', '\u{111}',
        '\u{144}', '\u{148}', '\u{f3}', '\u{f4}', '\u{151}', '\u{f6}', '\u{f7}', '\u{159}', '\u{16f}', '\u{fa}',
        '\u{171}', '\u{fc}', '\u{fd}', '\u{163}', '\u{2d9}',
    ],
};

static ISO_8859_4: CodePage = CodePage {
    name: "ISO-8859-4, Baltic",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{104}', '\u{138}', '\u{156}', '\u{a4}', '\u{128}', '\u{13b}', '\u{a7}', '\u{a8}', '\u{160}', '\u{112}',
        '\u{122}', '\u{166}', '\u{ad}', '\u{17d}', '\u{af}', '\u{b0}', '\u{105}', '\u{2db}', '\u{157}', '\u{b4}',
        '\u{129}', '\u{13c}', '\u{2c7}', '\u{b8}', '\u{161}', '\u{113}', '\u{123}', '\u{167}', '\u{14a}', '\u{17e}',
        '\u{14b}', '\u{100}', '\u{c1}', '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{12e}', '\u{10c}',
        '\u{c9}', '\u{118}', '\u{cb}', '\u{116}', '\u{cd}', '\u{ce}', '\u{12a}', '\u{110}', '\u{145}', '\u{14c}',
        '\u{136}', '\u{d4}', '\u{d5}', '\u{d6}', '\u{d7}', '\u{d8}', '\u{172}', '\u{da}', '\u{db}', '\u{dc}',
        '\u{168}', '\u{16a}', '\u{df}', '\u{101}', '\u{e1}', '\u{e2}', '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}',
        '\u{12f}', '\u{10d}', '\u{e9}', '\u{119}', '\u{eb}', '\u{117}', '\u{ed}', '\u{ee}', '\u{12b}', '\u{111}',
        '\u{146}', '\u{14d}', '\u{137}', '\u{f4}', '\u{f5}', '\u{f6}', '\u{f7}', '\u{f8}', '\u{173}', '\u{fa}',
        '\u{fb}', '\u{fc}', '\u{169}', '\u{16b}', '\u{2d9}',
    ],
};

static CP866: CodePage = CodePage {
    name: "CP866, Russian",
    upper: [
        '\u{410}', '\u{411}', '\u{412}', '\u{413}', '\u{414}', '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}',
        '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}',
        '\u{424}', '\u{425}', '\u{426}', '\u{427}', '\u{428}', '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}',
        '\u{42e}', '\u{42f}', '\u{430}', '\u{431}', '\u{432}', '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}',
        '\u{438}', '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{2591}', '\u{2592}',
        '\u{2593}', '\u{2502}', '\u{2524}', '\u{2561}', '\u{2562}', '\u{2556}', '\u{2555}', '\u{2563}', '\u{2551}',
        '\u{2557}', '\u{255d}', '\u{255c}', '\u{255b}', '\u{2510}', '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}',
        '\u{2500}', '\u{253c}', '\u{255e}', '\u{255f}', '\u{255a}', '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}',
        '\u{2550}', '\u{256c}', '\u{2567}', '\u{2568}', '\u{2564}', '\u{2565}', '\u{2559}', '\u{2558}', '\u{2552}',
        '\u{2553}', '\u{256b}', '\u{256a}', '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}', '\u{258c}', '\u{2590}',
        '\u{2580}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}', '\u{445}', '\u{446}', '\u{447}', '\u{448}',
        '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}', '\u{44f}', '\u{401}', '\u{451}', '\u{404}',
        '\u{454}', '\u{407}', '\u{457}', '\u{40e}', '\u{45e}', '\u{b0}', '\u{2219}', '\u{b7}', '\u{221a}', '\u{2116}',
        '\u{a4}', '\u{25a0}', '\u{a0}',
    ],
};

static ISO_8859_9: CodePage = CodePage {
    name: "ISO-8859-9, Turkish",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{a1}', '\u{a2}', '\u{a3}', '\u{a4}', '\u{a5}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{aa}', '\u{ab}',
        '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{b4}', '\u{b5}', '\u{b6}',
        '\u{b7}', '\u{b8}', '\u{b9}', '\u{ba}', '\u{bb}', '\u{bc}', '\u{bd}', '\u{be}', '\u{bf}', '\u{c0}', '\u{c1}',
        '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{c7}', '\u{c8}', '\u{c9}', '\u{ca}', '\u{cb}', '\u{cc}',
        '\u{cd}', '\u{ce}', '\u{cf}', '\u{11e}', '\u{d1}', '\u{d2}', '\u{d3}', '\u{d4}', '\u{d5}', '\u{d6}', '\u{d7}',
        '\u{d8}', '\u{d9}', '\u{da}', '\u{db}', '\u{dc}', '\u{130}', '\u{15e}', '\u{df}', '\u{e0}', '\u{e1}', '\u{e2}',
        '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}', '\u{e7}', '\u{e8}', '\u{e9}', '\u{ea}', '\u{eb}', '\u{ec}', '\u{ed}',
        '\u{ee}', '\u{ef}', '\u{11f}', '\u{f1}', '\u{f2}', '\u{f3}', '\u{f4}', '\u{f5}', '\u{f6}', '\u{f7}', '\u{f8}',
        '\u{f9}', '\u{fa}', '\u{fb}', '\u{fc}', '\u{131}', '\u{15f}', '\u{ff}',
    ],
};

static ISO_8859_8: CodePage = CodePage {
    name: "ISO-8859-8, Hebrew",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{fffd}', '\u{a2}', '\u{a3}', '\u{a4}', '\u{a5}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{d7}', '\u{ab}',
        '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{b4}', '\u{b5}', '\u{b6}',
        '\u{b7}', '\u{b8}', '\u{b9}', '\u{f7}', '\u{bb}', '\u{bc}', '\u{bd}', '\u{be}', '\u{fffd}', '\u{fffd}',
        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}',
        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}',
        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{fffd}',
        '\u{fffd}', '\u{fffd}', '\u{fffd}', '\u{2017}', '\u{5d0}', '\u{5d1}', '\u{5d2}', '\u{5d3}', '\u{5d4}',
        '\u{5d5}', '\u{5d6}', '\u{5d7}', '\u{5d8}', '\u{5d9}', '\u{5da}', '\u{5db}', '\u{5dc}', '\u{5dd}', '\u{5de}',
        '\u{5df}', '\u{5e0}', '\u{5e1}', '\u{5e2}', '\u{5e3}', '\u{5e4}', '\u{5e5}', '\u{5e6}', '\u{5e7}', '\u{5e8}',
        '\u{5e9}', '\u{5ea}', '\u{fffd}', '\u{fffd}', '\u{200e}', '\u{200f}', '\u{fffd}',
    ],
};

static KOI8_U: CodePage = CodePage {
    name: "KOI8-U, Ukrainian",
    upper: [
        '\u{2500}', '\u{2502}', '\u{250c}', '\u{2510}', '\u{2514}', '\u{2518}', '\u{251c}', '\u{2524}', '\u{252c}',
        '\u{2534}', '\u{253c}', '\u{2580}', '\u{2584}', '\u{2588}', '\u{258c}', '\u{2590}', '\u{2591}', '\u{2592}',
        '\u{2593}', '\u{2320}', '\u{25a0}', '\u{2219}', '\u{221a}', '\u{2248}', '\u{2264}', '\u{2265}', '\u{a0}',
        '\u{2321}', '\u{b0}', '\u{b2}', '\u{b7}', '\u{f7}', '\u{2550}', '\u{2551}', '\u{2552}', '\u{451}', '\u{454}',
        '\u{2554}', '\u{456}', '\u{457}', '\u{2557}', '\u{2558}', '\u{2559}', '\u{255a}', '\u{255b}', '\u{491}',
        '\u{255d}', '\u{255e}', '\u{255f}', '\u{2560}', '\u{2561}', '\u{401}', '\u{404}', '\u{2563}', '\u{406}',
        '\u{407}', '\u{2566}', '\u{2567}', '\u{2568}', '\u{2569}', '\u{256a}', '\u{490}', '\u{256c}', '\u{a9}',
        '\u{44e}', '\u{430}', '\u{431}', '\u{446}', '\u{434}', '\u{435}', '\u{444}', '\u{433}', '\u{445}', '\u{438}',
        '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{44f}', '\u{440}', '\u{441}',
        '\u{442}', '\u{443}', '\u{436}', '\u{432}', '\u{44c}', '\u{44b}', '\u{437}', '\u{448}', '\u{44d}', '\u{449}',
        '\u{447}', '\u{44a}', '\u{42e}', '\u{410}', '\u{411}', '\u{426}', '\u{414}', '\u{415}', '\u{424}', '\u{413}',
        '\u{425}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{42f}',
        '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{416}', '\u{412}', '\u{42c}', '\u{42b}', '\u{417}', '\u{428}',
        '\u{42d}', '\u{429}', '\u{427}', '\u{42a}',
    ],
};

static ISO_8859_15: CodePage = CodePage {
    name: "ISO-8859-15, West European",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{a1}', '\u{a2}', '\u{a3}', '\u{20ac}', '\u{a5}', '\u{160}', '\u{a7}', '\u{161}', '\u{a9}', '\u{aa}',
        '\u{ab}', '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{17d}', '\u{b5}',
        '\u{b6}', '\u{b7}', '\u{17e}', '\u{b9}', '\u{ba}', '\u{bb}', '\u{152}', '\u{153}', '\u{178}', '\u{bf}',
        '\u{c0}', '\u{c1}', '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{c7}', '\u{c8}', '\u{c9}', '\u{ca}',
        '\u{cb}', '\u{cc}', '\u{cd}', '\u{ce}', '\u{cf}', '\u{d0}', '\u{d1}', '\u{d2}', '\u{d3}', '\u{d4}', '\u{d5}',
        '\u{d6}', '\u{d7}', '\u{d8}', '\u{d9}', '\u{da}', '\u{db}', '\u{dc}', '\u{dd}', '\u{de}', '\u{df}', '\u{e0}',
        '\u{e1}', '\u{e2}', '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}', '\u{e7}', '\u{e8}', '\u{e9}', '\u{ea}', '\u{eb}',
        '\u{ec}', '\u{ed}', '\u{ee}', '\u{ef}', '\u{f0}', '\u{f1}', '\u{f2}', '\u{f3}', '\u{f4}', '\u{f5}', '\u{f6}',
        '\u{f7}', '\u{f8}', '\u{f9}', '\u{fa}', '\u{fb}', '\u{fc}', '\u{fd}', '\u{fe}', '\u{ff}',
    ],
};

static ISO_8859_5: CodePage = CodePage {
    name: "ISO-8859-5, Cyrillic",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{401}', '\u{402}', '\u{403}', '\u{404}', '\u{405}', '\u{406}', '\u{407}', '\u{408}', '\u{409}', '\u{40a}',
        '\u{40b}', '\u{40c}', '\u{ad}', '\u{40e}', '\u{40f}', '\u{410}', '\u{411}', '\u{412}', '\u{413}', '\u{414}',
        '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}', '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}',
        '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}', '\u{424}', '\u{425}', '\u{426}', '\u{427}', '\u{428}',
        '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}', '\u{42e}', '\u{42f}', '\u{430}', '\u{431}', '\u{432}',
        '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}', '\u{438}', '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}',
        '\u{43d}', '\u{43e}', '\u{43f}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}', '\u{445}', '\u{446}',
        '\u{447}', '\u{448}', '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}', '\u{44f}', '\u{2116}',
        '\u{451}', '\u{452}', '\u{453}', '\u{454}', '\u{455}', '\u{456}', '\u{457}', '\u{458}', '\u{459}', '\u{45a}',
        '\u{45b}', '\u{45c}', '\u{a7}', '\u{45e}', '\u{45f}',
    ],
};

static CP850: CodePage = CodePage {
    name: "CP850, Latin I",
    upper: [
        '\u{c7}', '\u{fc}', '\u{e9}', '\u{e2}', '\u{e4}', '\u{e0}', '\u{e5}', '\u{e7}', '\u{ea}', '\u{eb}', '\u{e8}',
        '\u{ef}', '\u{ee}', '\u{ec}', '\u{c4}', '\u{c5}', '\u{c9}', '\u{e6}', '\u{c6}', '\u{f4}', '\u{f6}', '\u{f2}',
        '\u{fb}', '\u{f9}', '\u{ff}', '\u{d6}', '\u{dc}', '\u{f8}', '\u{a3}', '\u{d8}', '\u{d7}', '\u{192}', '\u{e1}',
        '\u{ed}', '\u{f3}', '\u{fa}', '\u{f1}', '\u{d1}', '\u{aa}', '\u{ba}', '\u{bf}', '\u{ae}', '\u{ac}', '\u{bd}',
        '\u{bc}', '\u{a1}', '\u{ab}', '\u{bb}', '\u{2591}', '\u{2592}', '\u{2593}', '\u{2502}', '\u{2524}', '\u{c1}',
        '\u{c2}', '\u{c0}', '\u{a9}', '\u{2563}', '\u{2551}', '\u{2557}', '\u{255d}', '\u{a2}', '\u{a5}', '\u{2510}',
        '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}', '\u{2500}', '\u{253c}', '\u{e3}', '\u{c3}', '\u{255a}',
        '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}', '\u{2550}', '\u{256c}', '\u{a4}', '\u{f0}', '\u{d0}', '\u{ca}',
        '\u{cb}', '\u{c8}', '\u{131}', '\u{cd}', '\u{ce}', '\u{cf}', '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}',
        '\u{a6}', '\u{cc}', '\u{2580}', '\u{d3}', '\u{df}', '\u{d4}', '\u{d2}', '\u{f5}', '\u{d5}', '\u{b5}', '\u{fe}',
        '\u{de}', '\u{da}', '\u{db}', '\u{d9}', '\u{fd}', '\u{dd}', '\u{af}', '\u{b4}', '\u{ad}', '\u{b1}', '\u{2017}',
        '\u{be}', '\u{b6}', '\u{a7}', '\u{f7}', '\u{b8}', '\u{b0}', '\u{a8}', '\u{b7}', '\u{b9}', '\u{b3}', '\u{b2}',
        '\u{25a0}', '\u{a0}',
    ],
};

static CP865: CodePage = CodePage {
    name: "CP865, Nordic",
    upper: [
        '\u{c7}', '\u{fc}', '\u{e9}', '\u{e2}', '\u{e4}', '\u{e0}', '\u{e5}', '\u{e7}', '\u{ea}', '\u{eb}', '\u{e8}',
        '\u{ef}', '\u{ee}', '\u{ec}', '\u{c4}', '\u{c5}', '\u{c9}', '\u{e6}', '\u{c6}', '\u{f4}', '\u{f6}', '\u{f2}',
        '\u{fb}', '\u{f9}', '\u{ff}', '\u{d6}', '\u{dc}', '\u{f8}', '\u{a3}', '\u{d8}', '\u{20a7}', '\u{192}',
        '\u{e1}', '\u{ed}', '\u{f3}', '\u{fa}', '\u{f1}', '\u{d1}', '\u{aa}', '\u{ba}', '\u{bf}', '\u{2310}', '\u{ac}',
        '\u{bd}', '\u{bc}', '\u{a1}', '\u{ab}', '\u{a4}', '\u{2591}', '\u{2592}', '\u{2593}', '\u{2502}', '\u{2524}',
        '\u{2561}', '\u{2562}', '\u{2556}', '\u{2555}', '\u{2563}', '\u{2551}', '\u{2557}', '\u{255d}', '\u{255c}',
        '\u{255b}', '\u{2510}', '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}', '\u{2500}', '\u{253c}', '\u{255e}',
        '\u{255f}', '\u{255a}', '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}', '\u{2550}', '\u{256c}', '\u{2567}',
        '\u{2568}', '\u{2564}', '\u{2565}', '\u{2559}', '\u{2558}', '\u{2552}', '\u{2553}', '\u{256b}', '\u{256a}',
        '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}', '\u{258c}', '\u{2590}', '\u{2580}', '\u{3b1}', '\u{df}',
        '\u{393}', '\u{3c0}', '\u{3a3}', '\u{3c3}', '\u{b5}', '\u{3c4}', '\u{3a6}', '\u{398}', '\u{3a9}', '\u{3b4}',
        '\u{221e}', '\u{3c6}', '\u{3b5}', '\u{2229}', '\u{2261}', '\u{b1}', '\u{2265}', '\u{2264}', '\u{2320}',
        '\u{2321}', '\u{f7}', '\u{2248}', '\u{b0}', '\u{2219}', '\u{b7}', '\u{221a}', '\u{207f}', '\u{b2}', '\u{25a0}',
        '\u{a0}',
    ],
};

static ISO_8859_7: CodePage = CodePage {
    name: "ISO-8859-7, Greek",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{2018}', '\u{2019}', '\u{a3}', '\u{20ac}', '\u{20af}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{37a}',
        '\u{ab}', '\u{ac}', '\u{ad}', '\u{fffd}', '\u{2015}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{384}',
        '\u{385}', '\u{386}', '\u{b7}', '\u{388}', '\u{389}', '\u{38a}', '\u{bb}', '\u{38c}', '\u{bd}', '\u{38e}',
        '\u{38f}', '\u{390}', '\u{391}', '\u{392}', '\u{393}', '\u{394}', '\u{395}', '\u{396}', '\u{397}', '\u{398}',
        '\u{399}', '\u{39a}', '\u{39b}', '\u{39c}', '\u{39d}', '\u{39e}', '\u{39f}', '\u{3a0}', '\u{3a1}', '\u{fffd}',
        '\u{3a3}', '\u{3a4}', '\u{3a5}', '\u{3a6}', '\u{3a7}', '\u{3a8}', '\u{3a9}', '\u{3aa}', '\u{3ab}', '\u{3ac}',
        '\u{3ad}', '\u{3ae}', '\u{3af}', '\u{3b0}', '\u{3b1}', '\u{3b2}', '\u{3b3}', '\u{3b4}', '\u{3b5}', '\u{3b6}',
        '\u{3b7}', '\u{3b8}', '\u{3b9}', '\u{3ba}', '\u{3bb}', '\u{3bc}', '\u{3bd}', '\u{3be}', '\u{3bf}', '\u{3c0}',
        '\u{3c1}', '\u{3c2}', '\u{3c3}', '\u{3c4}', '\u{3c5}', '\u{3c6}', '\u{3c7}', '\u{3c8}', '\u{3c9}', '\u{3ca}',
        '\u{3cb}', '\u{3cc}', '\u{3cd}', '\u{3ce}', '\u{fffd}',
    ],
};

static ISO_8859_1: CodePage = CodePage {
    name: "ISO-8859-1, West European",
    upper: [
        '\u{80}', '\u{81}', '\u{82}', '\u{83}', '\u{84}', '\u{85}', '\u{86}', '\u{87}', '\u{88}', '\u{89}', '\u{8a}',
        '\u{8b}', '\u{8c}', '\u{8d}', '\u{8e}', '\u{8f}', '\u{90}', '\u{91}', '\u{92}', '\u{93}', '\u{94}', '\u{95}',
        '\u{96}', '\u{97}', '\u{98}', '\u{99}', '\u{9a}', '\u{9b}', '\u{9c}', '\u{9d}', '\u{9e}', '\u{9f}', '\u{a0}',
        '\u{a1}', '\u{a2}', '\u{a3}', '\u{a4}', '\u{a5}', '\u{a6}', '\u{a7}', '\u{a8}', '\u{a9}', '\u{aa}', '\u{ab}',
        '\u{ac}', '\u{ad}', '\u{ae}', '\u{af}', '\u{b0}', '\u{b1}', '\u{b2}', '\u{b3}', '\u{b4}', '\u{b5}', '\u{b6}',
        '\u{b7}', '\u{b8}', '\u{b9}', '\u{ba}', '\u{bb}', '\u{bc}', '\u{bd}', '\u{be}', '\u{bf}', '\u{c0}', '\u{c1}',
        '\u{c2}', '\u{c3}', '\u{c4}', '\u{c5}', '\u{c6}', '\u{c7}', '\u{c8}', '\u{c9}', '\u{ca}', '\u{cb}', '\u{cc}',
        '\u{cd}', '\u{ce}', '\u{cf}', '\u{d0}', '\u{d1}', '\u{d2}', '\u{d3}', '\u{d4}', '\u{d5}', '\u{d6}', '\u{d7}',
        '\u{d8}', '\u{d9}', '\u{da}', '\u{db}', '\u{dc}', '\u{dd}', '\u{de}', '\u{df}', '\u{e0}', '\u{e1}', '\u{e2}',
        '\u{e3}', '\u{e4}', '\u{e5}', '\u{e6}', '\u{e7}', '\u{e8}', '\u{e9}', '\u{ea}', '\u{eb}', '\u{ec}', '\u{ed}',
        '\u{ee}', '\u{ef}', '\u{f0}', '\u{f1}', '\u{f2}', '\u{f3}', '\u{f4}', '\u{f5}', '\u{f6}', '\u{f7}', '\u{f8}',
        '\u{f9}', '\u{fa}', '\u{fb}', '\u{fc}', '\u{fd}', '\u{fe}', '\u{ff}',
    ],
};

static CP866U: CodePage = CodePage {
    name: "CP866U (CP1125), Ukrainian",
    upper: [
        '\u{410}', '\u{411}', '\u{412}', '\u{413}', '\u{414}', '\u{415}', '\u{416}', '\u{417}', '\u{418}', '\u{419}',
        '\u{41a}', '\u{41b}', '\u{41c}', '\u{41d}', '\u{41e}', '\u{41f}', '\u{420}', '\u{421}', '\u{422}', '\u{423}',
        '\u{424}', '\u{425}', '\u{426}', '\u{427}', '\u{428}', '\u{429}', '\u{42a}', '\u{42b}', '\u{42c}', '\u{42d}',
        '\u{42e}', '\u{42f}', '\u{430}', '\u{431}', '\u{432}', '\u{433}', '\u{434}', '\u{435}', '\u{436}', '\u{437}',
        '\u{438}', '\u{439}', '\u{43a}', '\u{43b}', '\u{43c}', '\u{43d}', '\u{43e}', '\u{43f}', '\u{2591}', '\u{2592}',
        '\u{2593}', '\u{2502}', '\u{2524}', '\u{2561}', '\u{2562}', '\u{2556}', '\u{2555}', '\u{2563}', '\u{2551}',
        '\u{2557}', '\u{255d}', '\u{255c}', '\u{255b}', '\u{2510}', '\u{2514}', '\u{2534}', '\u{252c}', '\u{251c}',
        '\u{2500}', '\u{253c}', '\u{255e}', '\u{255f}', '\u{255a}', '\u{2554}', '\u{2569}', '\u{2566}', '\u{2560}',
        '\u{2550}', '\u{256c}', '\u{2567}', '\u{2568}', '\u{2564}', '\u{2565}', '\u{2559}', '\u{2558}', '\u{2552}',
        '\u{2553}', '\u{256b}', '\u{256a}', '\u{2518}', '\u{250c}', '\u{2588}', '\u{2584}', '\u{258c}', '\u{2590}',
        '\u{2580}', '\u{440}', '\u{441}', '\u{442}', '\u{443}', '\u{444}', '\u{445}', '\u{446}', '\u{447}', '\u{448}',
        '\u{449}', '\u{44a}', '\u{44b}', '\u{44c}', '\u{44d}', '\u{44e}', '\u{44f}', '\u{401}', '\u{451}', '\u{490}',
        '\u{491}', '\u{404}', '\u{454}', '\u{406}', '\u{456}', '\u{407}', '\u{457}', '\u{b7}', '\u{221a}', '\u{2116}',
        '\u{a4}', '\u{25a0}', '\u{a0}',
    ],
};

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn cyrillic_both_ways() {
        let cp866 = for_font(25).unwrap();
        assert_eq!(cp866.encode_str("Привет!"), [0x8F, 0xE0, 0xA8, 0xA2, 0xA5, 0xE2, b'!']);
        assert_eq!(cp866.decode(0x8F), 'П');
        let koi = for_font(2).unwrap();
        assert_eq!(koi.encode_str("Да"), [0xE4, 0xC1]);
        assert_eq!(koi.decode(0xC1), 'а');
        // Not in the code page: a question mark.
        assert_eq!(for_font(21).unwrap().encode_str("Ω€Ж"), [0xD9, 0xA4, b'?']);
        assert!(for_font(7).is_none() && for_font(0).is_none());
    }
}