codepage-437-0.1.0/.gitignore000064400000000000000000000003231324133031000137340ustar0000000000000000* !.gitignore !.travis.yml !gh_rsa.enc !appveyor.yml !LICENSE !Cargo.toml !rustfmt.toml !build.rs !*.sublime-project !*.md !src !src/** !tests !tests/** !test-data !test-data/** !dialect-specs !dialect-specs/** codepage-437-0.1.0/.travis.yml000064400000000000000000000046231324302626300140770ustar0000000000000000sudo: false language: generic cache: cargo: true matrix: include: - env: LANGUAGE=Rust language: rust rust: stable - env: LANGUAGE=Rust language: rust rust: beta - env: LANGUAGE=Rust CLIPPY=true language: rust rust: nightly - env: LANGUAGE=Rust-doc DEPLOY=true DEPLOY_FILE="$TRAVIS_BUILD_DIR/../codepage-437-doc-$TRAVIS_TAG.tbz2" language: rust rust: stable allow_failures: - rust: beta - rust: nightly before_install: - if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then openssl aes-256-cbc -K $encrypted_c6bd1f0adfcf_key -iv $encrypted_c6bd1f0adfcf_iv -in gh_rsa.enc -out gh_rsa -d; fi script: - if [ "$LANGUAGE" == "Rust" ]; then cargo build --verbose; fi - if [ "$LANGUAGE" == "Rust" ]; then cargo test --verbose; fi - if [ "$LANGUAGE" == "Rust" ] && [ "$CLIPPY" ]; then cargo install -f clippy; cargo clippy; fi after_success: - if [ "$LANGUAGE" == "Rust-doc" ]; then curl -SL https://keybase.io/nabijaczleweli/key.asc | gpg --import; curl -SL https://gist.github.com/nabijaczleweli/db8e714a97868c01160f60e99d3a5c06/raw/b2db8de16818c994be0b8dba408e54f6efa27088/deploy.sh.gpg | gpg -d | bash; fi - if [ "$LANGUAGE" == "Rust-doc" ] && [ "$TRAVIS_TAG" ] && [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then cargo doc; cp -r target/doc "$TRAVIS_BUILD_DIR/../codepage-437-doc-$TRAVIS_TAG"; pushd "$TRAVIS_BUILD_DIR/.."; tar -caf "codepage-437-doc-$TRAVIS_TAG.tbz2" "codepage-437-doc-$TRAVIS_TAG"; rm -rf "codepage-437-doc-$TRAVIS_TAG"; popd; fi deploy: provider: releases api_key: secure: "qiahlZXdO2/G14yOmx1X/xus11cHv+2E0SLgX4sp5+QmkAVH6mwFLjZYwCArxgGb0n8sULtis8dykfbsS8ffO38LmHlJkGJ3TnKOWQ3Dck9WN/dYlrpB8IN/f929BcV5G15ywKMkCTUXS0mfrd4bWMxniA1xJaM25hGwket480ets0oO1k4QZ4JbJrjjPWV+OwP/szgKUCY7W8rkBmHCZyPGWIFZ+4STest8Rv+pNa7+qj92gx/dIp2LwDQIGROl01AOIhJ1UM2jv6WwWBqzXx12qqbvP6UcRxGjZW78ibgiNyoMY0FE6UuBIwA5QScCXBcgufF6jNZ4OvQp/mNSN15B9tyY8D/3znrqafW5RtPf6tCifmeAT67C9ZMXcRtL7gHgus+tYtlqNrC+ljYm5ll8jAXHu/OajBCWsg85CmXKPwRUVuyhx3JNdc5m2Bbo1xfwdy9jXsgJe8C9N10fUEcenBineIZ0Qb1FoWFMbrvD8/m2XhWSasKQ2dKB2RzzrTFbCAKjSoEK1BqPfGeAoGW3A/XsizkjnmzespczSibOfXpk5Gs3gRLdxnN6TyIJrG4Wk4fihpS7Ooss0TjKMlEZx6pCCQXlPQd717ukLUBUQ+IKrfX+3QwZP3uTpyzu656QCMLcNNlgHNJv5xLpsxV0D0Iak33QPcizpUjV1mY=" file: "$DEPLOY_FILE" skip_cleanup: true on: tags: true condition: $DEPLOY = true codepage-437-0.1.0/appveyor.yml000064400000000000000000000013501324025554000143470ustar0000000000000000version: 0.1.0-{build} skip_tags: false platform: x64 configuration: Release clone_folder: C:\codepage-437 install: - set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%;C:\Users\appveyor\.cargo\bin - bash -lc "pacman --needed --noconfirm -Sy pacman-mirrors" - bash -lc "pacman --noconfirm -Sy" # - bash -lc "pacman --noconfirm -S mingw-w64-x86_64-toolchain" - - curl -SL https://win.rustup.rs/ -oC:\rustup-init.exe - C:\rustup-init.exe -y --default-host="x86_64-pc-windows-gnu" build: off build_script: - git submodule update --init --recursive - cargo build --release - cargo test --release test: off notifications: - provider: Email to: - nabijaczleweli@gmail.com on_build_status_changed: true codepage-437-0.1.0/build.rs000064400000000000000000000163241324306237300134360ustar0000000000000000extern crate csv; use std::io::{BufReader, BufRead, Write}; use std::path::{PathBuf, Path}; use std::fs::{self, File}; use std::char; use std::env; #[derive(Debug, Clone, Hash, Eq, Ord, PartialEq, PartialOrd)] struct Mapping { cp437: u8, unicode: char, comment: String, } impl Mapping { pub fn from_record(record: csv::StringRecord) -> Result { if record.len() != 3 { return Err(format!("Invalid record length ({}, should be 3)", record.len())); } let (cp437, unicode, comment) = (record.get(0).unwrap(), record.get(1).unwrap(), record.get(2).unwrap()); if &cp437[..2] != "0x" { return Err(format!("Invalid cp437 code prefix (\"{}\", should be \"0x\")", &cp437[..2])); } let cp437 = &cp437[2..]; if !cp437.chars().all(|c| (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { return Err(format!("cp437 code \"0x{}\" not hex", cp437)); } if cp437.chars().count() > 2 { return Err(format!("cp437 code \"0x{}\" too big", cp437)); } let cp437 = u8::from_str_radix(cp437, 16).unwrap(); if &unicode[..2] != "0x" { return Err(format!("Invalid Unicode code prefix (\"{}\", should be \"0x\")", &unicode[..2])); } let unicode = &unicode[2..]; if !unicode.chars().all(|c| (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { return Err(format!("Unicode code \"0x{}\" not hex", unicode)); } if unicode.chars().count() > 8 { return Err(format!("Unicode code \"0x{}\" too big", unicode)); } let unicode = u32::from_str_radix(unicode, 16).unwrap(); let unicode = if let Some(unicode) = char::from_u32(unicode) { unicode } else { return Err(format!("Unicode code 0x{:X} out of range", unicode)); }; Ok(Mapping { cp437: cp437, unicode: unicode, comment: comment.to_string(), }) } pub fn from_mappings>(p: P) -> Vec { let mut ret = Vec::new(); for record in csv::ReaderBuilder::new().delimiter('\t' as u8).from_path(p).unwrap().into_records().map(Result::unwrap) { ret.push(Mapping::from_record(record).unwrap()); } ret } } fn main() { let out_dir = env::var("OUT_DIR").expect("OUT_DIR env var nonexistant/non-Unicode"); let mut specs_rs = File::create(PathBuf::from(format!("{}/dialects.rs", out_dir))).unwrap(); for dir in fs::read_dir("dialect-specs").unwrap().map(Result::unwrap).filter(|f| f.file_type().unwrap().is_dir()) { let dialect_name_func = dir.file_name().to_str().unwrap().to_lowercase(); let dialect_name_type = dir.file_name().to_str().unwrap().to_uppercase(); let dialect_name_init = dialect_name_type.clone() + "_INIT"; let cp437_overlap_func = format!("{}_cp437_overlaps", dialect_name_func); let unicode_overlap_func = format!("{}_unicode_overlaps", dialect_name_func); let encode_func = format!("{}_encode", dialect_name_func); let values_tsv = dir.path().join("values.tsv"); let variants_tsv = dir.path().join("variants.tsv"); let documentation_md = dir.path().join("documentation.md"); let overlaps_rs = dir.path().join("overlaps.rs"); println!("cargo:rerun-if-changed={}", values_tsv.display()); println!("cargo:rerun-if-changed={}", variants_tsv.display()); println!("cargo:rerun-if-changed={}", documentation_md.display()); println!("cargo:rerun-if-changed={}", overlaps_rs.display()); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "// {} start", dir.path().display()).unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "").unwrap(); for line in BufReader::new(File::open(&overlaps_rs).unwrap()).lines().map(Result::unwrap) { if line.contains("DIALECT_OVERLAP_CP437") || line.contains("DIALECT_OVERLAP_UNICODE") { specs_rs.write_all(line.replace("DIALECT_OVERLAP_CP437", &cp437_overlap_func) .replace("DIALECT_OVERLAP_UNICODE", &unicode_overlap_func) .as_bytes()) .unwrap(); } else { specs_rs.write_all(line.as_bytes()).unwrap(); } writeln!(specs_rs).unwrap(); } let primary_mappings = Mapping::from_mappings(&values_tsv); let variant_mappings = Mapping::from_mappings(&variants_tsv); let mut decode_array = vec![('\x00', String::new()); 256]; for i in 0..256 { decode_array[i] = (i as u8 as char, String::new()); } for &Mapping { cp437, unicode, ref comment } in &primary_mappings { decode_array[cp437 as usize] = (unicode, comment.clone()); } writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "fn {}(unicode: char) -> Option {{", encode_func).unwrap(); writeln!(specs_rs, "\tSome(match unicode {{").unwrap(); for &mapp in &[&primary_mappings, &variant_mappings] { for &Mapping { cp437, unicode, ref comment } in mapp { writeln!(specs_rs, "\t\t\'\\u{{{:06X}}}\' => 0x{:X}, // {}", unicode as u32, cp437, comment).unwrap(); } writeln!(specs_rs, "").unwrap(); } writeln!(specs_rs, "\t\tc => if {}(c) {{ c as u8 }} else {{ return None }},", unicode_overlap_func).unwrap(); writeln!(specs_rs, "\t}})").unwrap(); writeln!(specs_rs, "}}").unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "const {}: Cp437Dialect = Cp437Dialect {{", dialect_name_init).unwrap(); writeln!(specs_rs, "\tcp437_to_unicode: [").unwrap(); for &(unicode, ref comment) in decode_array.iter() { write!(specs_rs, "\t\t\'\\u{{{:06X}}}\',", unicode as u32).unwrap(); if !comment.is_empty() { writeln!(specs_rs, " // {}", comment).unwrap(); } else { writeln!(specs_rs, "").unwrap(); } } writeln!(specs_rs, "\t],").unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "\toverlap_unicode: {},", unicode_overlap_func).unwrap(); writeln!(specs_rs, "\toverlap_cp437: {},", cp437_overlap_func).unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "\tencode: {},", encode_func).unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "\tremaps: Cow::Borrowed(&[]),").unwrap(); writeln!(specs_rs, "}};").unwrap(); writeln!(specs_rs, "").unwrap(); for line in BufReader::new(File::open(&documentation_md).unwrap()).lines().map(Result::unwrap) { writeln!(specs_rs, "/// {}", line).unwrap(); } writeln!(specs_rs, "pub static {}: Cp437Dialect = {};", dialect_name_type, dialect_name_init).unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "// {} end", dir.path().display()).unwrap(); writeln!(specs_rs, "").unwrap(); writeln!(specs_rs, "").unwrap(); } } codepage-437-0.1.0/Cargo.toml.orig000064400000000000000000000010451324132762500146540ustar0000000000000000[package] name = "codepage-437" description = "Codepage 437 transcoding for Rust" documentation = "https://cdn.rawgit.com/nabijaczleweli/codepage-437/doc/codepage_437/index.html" repository = "https://github.com/nabijaczleweli/codepage-437" readme = "README.md" keywords = ["windows", "dos", "code", "page"] categories = ["encoding"] license = "MIT" build = "build.rs" # Remember to also update in appveyor.yml version = "0.1.0" authors = ["nabijaczleweli "] exclude = ["*.enc"] [build-dependencies] csv = "1.0.0-beta.5" codepage-437-0.1.0/Cargo.toml0000644000000020150000000000000111470ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g. crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "codepage-437" version = "0.1.0" authors = ["nabijaczleweli "] build = "build.rs" exclude = ["*.enc"] description = "Codepage 437 transcoding for Rust" documentation = "https://cdn.rawgit.com/nabijaczleweli/codepage-437/doc/codepage_437/index.html" readme = "README.md" keywords = ["windows", "dos", "code", "page"] categories = ["encoding"] license = "MIT" repository = "https://github.com/nabijaczleweli/codepage-437" [build-dependencies.csv] version = "1.0.0-beta.5" codepage-437-0.1.0/codepage-437.sublime-project000064400000000000000000000017511324133350000170660ustar0000000000000000{ "build_systems": [ { "working_dir": "$project_path", "shell_cmd": "cargo build --color always && cargo test --color always", "name": "Build codepage-437", "target": "ansi_color_build", "syntax": "Packages/ANSIescape/ANSI.tmLanguage" }, { "working_dir": "$project_path", "shell_cmd": "cargo doc --color always", "name": "Document codepage-437", "target": "ansi_color_build", "syntax": "Packages/ANSIescape/ANSI.tmLanguage" } ], "folders": [ { "follow_symlinks": true, "name": "Source", "path": "src" }, { "follow_symlinks": true, "name": "Dialects", "path": "dialect-specs" }, { "follow_symlinks": true, "name": "Tests", "path": "tests" }, { "follow_symlinks": true, "name": "Test data", "path": "test-data" }, { "follow_symlinks": true, "name": "Build scripts", "path": ".", "file_include_patterns": ["Cargo.*", "*.yml", "build.rs", "*.rc"], "folder_exclude_patterns": ["*"] }, ] } codepage-437-0.1.0/dialect-specs/cp437_control/documentation.md000064400000000000000000000014311324134472000222720ustar0000000000000000[`cp437_DOSLatinUS`](http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT) as provided by the Unicode Consortium. Contains control characters in the `'\x00'..'\x20'` area. The decode table is additionally enriched from the the [variant table](https://en.wikipedia.org/wiki/Code_page_437#Notes) on Wikipedia. # Examples Decoding: ```rust # use codepage_437::CP437_CONTROL; assert_eq!(CP437_CONTROL.decode(0x41), 'A'); assert_eq!(CP437_CONTROL.decode(0x91), 'æ'); // LATIN SMALL LIGATURE AE ``` Encoding: ```rust # use codepage_437::CP437_CONTROL; assert_eq!(CP437_CONTROL.encode('A'), Some(0x41)); assert_eq!(CP437_CONTROL.encode('æ'), Some(0x91)); // LATIN SMALL LIGATURE AE assert_eq!(CP437_CONTROL.encode('ź'), None); // LATIN SMALL LETTER Z WITH ACUTE ``` codepage-437-0.1.0/dialect-specs/cp437_control/overlaps.rs000064400000000000000000000002431324134325600213030ustar0000000000000000#[inline(always)] fn DIALECT_OVERLAP_CP437(b: u8) -> bool { b.is_ascii() } #[inline(always)] fn DIALECT_OVERLAP_UNICODE(c: char) -> bool { c.is_ascii() } codepage-437-0.1.0/dialect-specs/cp437_control/values.tsv000064400000000000000000000123571324133344100211430ustar0000000000000000cp437_DOSLatinUS Unicode Comment 0x80 0x00C7 LATIN CAPITAL LETTER C WITH CEDILLA 0x81 0x00FC LATIN SMALL LETTER U WITH DIAERESIS 0x82 0x00E9 LATIN SMALL LETTER E WITH ACUTE 0x83 0x00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX 0x84 0x00E4 LATIN SMALL LETTER A WITH DIAERESIS 0x85 0x00E0 LATIN SMALL LETTER A WITH GRAVE 0x86 0x00E5 LATIN SMALL LETTER A WITH RING ABOVE 0x87 0x00E7 LATIN SMALL LETTER C WITH CEDILLA 0x88 0x00EA LATIN SMALL LETTER E WITH CIRCUMFLEX 0x89 0x00EB LATIN SMALL LETTER E WITH DIAERESIS 0x8A 0x00E8 LATIN SMALL LETTER E WITH GRAVE 0x8B 0x00EF LATIN SMALL LETTER I WITH DIAERESIS 0x8C 0x00EE LATIN SMALL LETTER I WITH CIRCUMFLEX 0x8D 0x00EC LATIN SMALL LETTER I WITH GRAVE 0x8E 0x00C4 LATIN CAPITAL LETTER A WITH DIAERESIS 0x8F 0x00C5 LATIN CAPITAL LETTER A WITH RING ABOVE 0x90 0x00C9 LATIN CAPITAL LETTER E WITH ACUTE 0x91 0x00E6 LATIN SMALL LIGATURE AE 0x92 0x00C6 LATIN CAPITAL LIGATURE AE 0x93 0x00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX 0x94 0x00F6 LATIN SMALL LETTER O WITH DIAERESIS 0x95 0x00F2 LATIN SMALL LETTER O WITH GRAVE 0x96 0x00FB LATIN SMALL LETTER U WITH CIRCUMFLEX 0x97 0x00F9 LATIN SMALL LETTER U WITH GRAVE 0x98 0x00FF LATIN SMALL LETTER Y WITH DIAERESIS 0x99 0x00D6 LATIN CAPITAL LETTER O WITH DIAERESIS 0x9A 0x00DC LATIN CAPITAL LETTER U WITH DIAERESIS 0x9B 0x00A2 CENT SIGN 0x9C 0x00A3 POUND SIGN 0x9D 0x00A5 YEN SIGN 0x9E 0x20A7 PESETA SIGN 0x9F 0x0192 LATIN SMALL LETTER F WITH HOOK 0xA0 0x00E1 LATIN SMALL LETTER A WITH ACUTE 0xA1 0x00ED LATIN SMALL LETTER I WITH ACUTE 0xA2 0x00F3 LATIN SMALL LETTER O WITH ACUTE 0xA3 0x00FA LATIN SMALL LETTER U WITH ACUTE 0xA4 0x00F1 LATIN SMALL LETTER N WITH TILDE 0xA5 0x00D1 LATIN CAPITAL LETTER N WITH TILDE 0xA6 0x00AA FEMININE ORDINAL INDICATOR 0xA7 0x00BA MASCULINE ORDINAL INDICATOR 0xA8 0x00BF INVERTED QUESTION MARK 0xA9 0x2310 REVERSED NOT SIGN 0xAA 0x00AC NOT SIGN 0xAB 0x00BD VULGAR FRACTION ONE HALF 0xAC 0x00BC VULGAR FRACTION ONE QUARTER 0xAD 0x00A1 INVERTED EXCLAMATION MARK 0xAE 0x00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xAF 0x00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0xB0 0x2591 LIGHT SHADE 0xB1 0x2592 MEDIUM SHADE 0xB2 0x2593 DARK SHADE 0xB3 0x2502 BOX DRAWINGS LIGHT VERTICAL 0xB4 0x2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT 0xB5 0x2561 BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE 0xB6 0x2562 BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE 0xB7 0x2556 BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE 0xB8 0x2555 BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE 0xB9 0x2563 BOX DRAWINGS DOUBLE VERTICAL AND LEFT 0xBA 0x2551 BOX DRAWINGS DOUBLE VERTICAL 0xBB 0x2557 BOX DRAWINGS DOUBLE DOWN AND LEFT 0xBC 0x255D BOX DRAWINGS DOUBLE UP AND LEFT 0xBD 0x255C BOX DRAWINGS UP DOUBLE AND LEFT SINGLE 0xBE 0x255B BOX DRAWINGS UP SINGLE AND LEFT DOUBLE 0xBF 0x2510 BOX DRAWINGS LIGHT DOWN AND LEFT 0xC0 0x2514 BOX DRAWINGS LIGHT UP AND RIGHT 0xC1 0x2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL 0xC2 0x252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL 0xC3 0x251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT 0xC4 0x2500 BOX DRAWINGS LIGHT HORIZONTAL 0xC5 0x253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL 0xC6 0x255E BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE 0xC7 0x255F BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE 0xC8 0x255A BOX DRAWINGS DOUBLE UP AND RIGHT 0xC9 0x2554 BOX DRAWINGS DOUBLE DOWN AND RIGHT 0xCA 0x2569 BOX DRAWINGS DOUBLE UP AND HORIZONTAL 0xCB 0x2566 BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL 0xCC 0x2560 BOX DRAWINGS DOUBLE VERTICAL AND RIGHT 0xCD 0x2550 BOX DRAWINGS DOUBLE HORIZONTAL 0xCE 0x256C BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL 0xCF 0x2567 BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE 0xD0 0x2568 BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE 0xD1 0x2564 BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE 0xD2 0x2565 BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE 0xD3 0x2559 BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE 0xD4 0x2558 BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE 0xD5 0x2552 BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE 0xD6 0x2553 BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE 0xD7 0x256B BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE 0xD8 0x256A BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE 0xD9 0x2518 BOX DRAWINGS LIGHT UP AND LEFT 0xDA 0x250C BOX DRAWINGS LIGHT DOWN AND RIGHT 0xDB 0x2588 FULL BLOCK 0xDC 0x2584 LOWER HALF BLOCK 0xDD 0x258C LEFT HALF BLOCK 0xDE 0x2590 RIGHT HALF BLOCK 0xDF 0x2580 UPPER HALF BLOCK 0xE0 0x03B1 GREEK SMALL LETTER ALPHA 0xE1 0x00DF LATIN SMALL LETTER SHARP S 0xE2 0x0393 GREEK CAPITAL LETTER GAMMA 0xE3 0x03C0 GREEK SMALL LETTER PI 0xE4 0x03A3 GREEK CAPITAL LETTER SIGMA 0xE5 0x03C3 GREEK SMALL LETTER SIGMA 0xE6 0x00B5 MICRO SIGN 0xE7 0x03C4 GREEK SMALL LETTER TAU 0xE8 0x03A6 GREEK CAPITAL LETTER PHI 0xE9 0x0398 GREEK CAPITAL LETTER THETA 0xEA 0x03A9 GREEK CAPITAL LETTER OMEGA 0xEB 0x03B4 GREEK SMALL LETTER DELTA 0xEC 0x221E INFINITY 0xED 0x03C6 GREEK SMALL LETTER PHI 0xEE 0x03B5 GREEK SMALL LETTER EPSILON 0xEF 0x2229 INTERSECTION 0xF0 0x2261 IDENTICAL TO 0xF1 0x00B1 PLUS-MINUS SIGN 0xF2 0x2265 GREATER-THAN OR EQUAL TO 0xF3 0x2264 LESS-THAN OR EQUAL TO 0xF4 0x2320 TOP HALF INTEGRAL 0xF5 0x2321 BOTTOM HALF INTEGRAL 0xF6 0x00F7 DIVISION SIGN 0xF7 0x2248 ALMOST EQUAL TO 0xF8 0x00B0 DEGREE SIGN 0xF9 0x2219 BULLET OPERATOR 0xFA 0x00B7 MIDDLE DOT 0xFB 0x221A SQUARE ROOT 0xFC 0x207F SUPERSCRIPT LATIN SMALL LETTER N 0xFD 0x00B2 SUPERSCRIPT TWO 0xFE 0x25A0 BLACK SQUARE 0xFF 0x00A0 NO-BREAK SPACE codepage-437-0.1.0/dialect-specs/cp437_control/variants.tsv000064400000000000000000000010741324133757200214760ustar0000000000000000cp437_DOSLatinUS Unicode Comment 0x7F 0x0394 Greek capital delta 0xE1 0x03B2 Greek small beta 0xE3 0x03A0 Greek capital pi 0xE3 0x220F n-ary product sign 0xE4 0x2211 n-ary summation sign 0xE6 0x03BC Mu Small 0xEB 0x00F0 small eth 0xEB 0x2202 partial derivative sign 0xED 0x03D5 Phi Small (Closed Form) 0xED 0x1D719 Italicized Phi Small (Closed Form) 0xED 0x2205 empty set sign 0xED 0x2300 diameter sign 0xED 0x00D8 Capital Latin letter O with stroke 0xED 0x00F8 Lowercase Latin letter O with stroke 0xEE 0x2208 element-of sign 0xEE 0x20AC euro sign 0xFB 0x2713 check mark codepage-437-0.1.0/dialect-specs/cp437_wingdings/documentation.md000064400000000000000000000013621324142254400226070ustar0000000000000000cp437 [with wingdings](https://en.wikipedia.org/wiki/Code_page_437#Character_set), as seen on Wikipedia. Contains wingdings in the `'\x00'..'\x20'` area. The decode table is additionally enriched from the the [variant table](https://en.wikipedia.org/wiki/Code_page_437#Notes). # Examples Decoding: ```rust # use codepage_437::CP437_WINGDINGS; assert_eq!(CP437_WINGDINGS.decode(0x41), 'A'); assert_eq!(CP437_WINGDINGS.decode(0x02), '☻'); // BLACK SMILING FACE ``` Encoding: ```rust # use codepage_437::CP437_WINGDINGS; assert_eq!(CP437_WINGDINGS.encode('A'), Some(0x41)); assert_eq!(CP437_WINGDINGS.encode('☻'), Some(0x02)); // BLACK SMILING FACE assert_eq!(CP437_WINGDINGS.encode('ź'), None); // LATIN SMALL LETTER Z WITH ACUTE ``` codepage-437-0.1.0/dialect-specs/cp437_wingdings/overlaps.rs000064400000000000000000000003321324211203700216030ustar0000000000000000#[inline(always)] fn DIALECT_OVERLAP_CP437(b: u8) -> bool { b == 0 || (b > 0x1F && b < 0x7F) } #[inline(always)] fn DIALECT_OVERLAP_UNICODE(c: char) -> bool { c == '\u{00}' || (c > '\u{1F}' && c < '\u{7F}') } codepage-437-0.1.0/dialect-specs/cp437_wingdings/values.tsv000064400000000000000000000142221324140674200214520ustar0000000000000000cp437_wingdings Unicode Comment 0x01 0x263A WHITE SMILING FACE 0x02 0x263B BLACK SMILING FACE 0x03 0x2665 BLACK HEART SUIT 0x04 0x2666 BLACK DIAMOND SUIT 0x05 0x2663 BLACK CLUB SUIT 0x06 0x2660 BLACK SPADE SUIT 0x07 0x2022 BULLET 0x08 0x25D8 INVERSE BULLET 0x09 0x25CB WHITE CIRCLE 0x0A 0x25D9 INVERSE WHITE CIRCLE 0x0B 0x2642 MALE SIGN 0x0C 0x2640 FEMALE SIGN 0x0D 0x266A EIGHTH NOTE 0x0E 0x266B BEAMED EIGHTH NOTES 0x0F 0x263C WHITE SUN WITH RAYS 0x10 0x25BA BLACK RIGHT-POINTING POINTER 0x11 0x25C4 BLACK LEFT-POINTING POINTER 0x12 0x2195 UP DOWN ARROW 0x13 0x203C DOUBLE EXCLAMATION MARK 0x14 0x00B6 PILCROW SIGN 0x15 0x00A7 SECTION SIGN 0x16 0x25AC BLACK RECTANGLE 0x17 0x21A8 UP DOWN ARROW WITH BASE 0x18 0x2191 UPWARDS ARROW 0x19 0x2193 DOWNWARDS ARROW 0x1A 0x2192 RIGHTWARDS ARROW 0x1B 0x2190 LEFTWARDS ARROW 0x1C 0x221F RIGHT ANGLE 0x1D 0x2194 LEFT RIGHT ARROW 0x1E 0x25B2 BLACK UP-POINTING TRIANGLE 0x1F 0x25BC BLACK DOWN-POINTING TRIANGLE 0x7F 0x2302 HOUSE 0x80 0x00C7 LATIN CAPITAL LETTER C WITH CEDILLA 0x81 0x00FC LATIN SMALL LETTER U WITH DIAERESIS 0x82 0x00E9 LATIN SMALL LETTER E WITH ACUTE 0x83 0x00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX 0x84 0x00E4 LATIN SMALL LETTER A WITH DIAERESIS 0x85 0x00E0 LATIN SMALL LETTER A WITH GRAVE 0x86 0x00E5 LATIN SMALL LETTER A WITH RING ABOVE 0x87 0x00E7 LATIN SMALL LETTER C WITH CEDILLA 0x88 0x00EA LATIN SMALL LETTER E WITH CIRCUMFLEX 0x89 0x00EB LATIN SMALL LETTER E WITH DIAERESIS 0x8A 0x00E8 LATIN SMALL LETTER E WITH GRAVE 0x8B 0x00EF LATIN SMALL LETTER I WITH DIAERESIS 0x8C 0x00EE LATIN SMALL LETTER I WITH CIRCUMFLEX 0x8D 0x00EC LATIN SMALL LETTER I WITH GRAVE 0x8E 0x00C4 LATIN CAPITAL LETTER A WITH DIAERESIS 0x8F 0x00C5 LATIN CAPITAL LETTER A WITH RING ABOVE 0x90 0x00C9 LATIN CAPITAL LETTER E WITH ACUTE 0x91 0x00E6 LATIN SMALL LETTER AE 0x92 0x00C6 LATIN CAPITAL LETTER AE 0x93 0x00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX 0x94 0x00F6 LATIN SMALL LETTER O WITH DIAERESIS 0x95 0x00F2 LATIN SMALL LETTER O WITH GRAVE 0x96 0x00FB LATIN SMALL LETTER U WITH CIRCUMFLEX 0x97 0x00F9 LATIN SMALL LETTER U WITH GRAVE 0x98 0x00FF LATIN SMALL LETTER Y WITH DIAERESIS 0x99 0x00D6 LATIN CAPITAL LETTER O WITH DIAERESIS 0x9A 0x00DC LATIN CAPITAL LETTER U WITH DIAERESIS 0x9B 0x00A2 CENT SIGN 0x9C 0x00A3 POUND SIGN 0x9D 0x00A5 YEN SIGN 0x9E 0x20A7 PESETA SIGN 0x9F 0x0192 LATIN SMALL LETTER F WITH HOOK 0xA0 0x00E1 LATIN SMALL LETTER A WITH ACUTE 0xA1 0x00ED LATIN SMALL LETTER I WITH ACUTE 0xA2 0x00F3 LATIN SMALL LETTER O WITH ACUTE 0xA3 0x00FA LATIN SMALL LETTER U WITH ACUTE 0xA4 0x00F1 LATIN SMALL LETTER N WITH TILDE 0xA5 0x00D1 LATIN CAPITAL LETTER N WITH TILDE 0xA6 0x00AA FEMININE ORDINAL INDICATOR 0xA7 0x00BA MASCULINE ORDINAL INDICATOR 0xA8 0x00BF INVERTED QUESTION MARK 0xA9 0x2310 REVERSED NOT SIGN 0xAA 0x00AC NOT SIGN 0xAB 0x00BD VULGAR FRACTION ONE HALF 0xAC 0x00BC VULGAR FRACTION ONE QUARTER 0xAD 0x00A1 INVERTED EXCLAMATION MARK 0xAE 0x00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK 0xAF 0x00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0xB0 0x2591 LIGHT SHADE 0xB1 0x2592 MEDIUM SHADE 0xB2 0x2593 DARK SHADE 0xB3 0x2502 BOX DRAWINGS LIGHT VERTICAL 0xB4 0x2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT 0xB5 0x2561 BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE 0xB6 0x2562 BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE 0xB7 0x2556 BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE 0xB8 0x2555 BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE 0xB9 0x2563 BOX DRAWINGS DOUBLE VERTICAL AND LEFT 0xBA 0x2551 BOX DRAWINGS DOUBLE VERTICAL 0xBB 0x2557 BOX DRAWINGS DOUBLE DOWN AND LEFT 0xBC 0x255D BOX DRAWINGS DOUBLE UP AND LEFT 0xBD 0x255C BOX DRAWINGS UP DOUBLE AND LEFT SINGLE 0xBE 0x255B BOX DRAWINGS UP SINGLE AND LEFT DOUBLE 0xBF 0x2510 BOX DRAWINGS LIGHT DOWN AND LEFT 0xC0 0x2514 BOX DRAWINGS LIGHT UP AND RIGHT 0xC1 0x2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL 0xC2 0x252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL 0xC3 0x251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT 0xC4 0x2500 BOX DRAWINGS LIGHT HORIZONTAL 0xC5 0x253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL 0xC6 0x255E BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE 0xC7 0x255F BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE 0xC8 0x255A BOX DRAWINGS DOUBLE UP AND RIGHT 0xC9 0x2554 BOX DRAWINGS DOUBLE DOWN AND RIGHT 0xCA 0x2569 BOX DRAWINGS DOUBLE UP AND HORIZONTAL 0xCB 0x2566 BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL 0xCC 0x2560 BOX DRAWINGS DOUBLE VERTICAL AND RIGHT 0xCD 0x2550 BOX DRAWINGS DOUBLE HORIZONTAL 0xCE 0x256C BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL 0xCF 0x2567 BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE 0xD0 0x2568 BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE 0xD1 0x2564 BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE 0xD2 0x2565 BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE 0xD3 0x2559 BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE 0xD4 0x2558 BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE 0xD5 0x2552 BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE 0xD6 0x2553 BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE 0xD7 0x256B BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE 0xD8 0x256A BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE 0xD9 0x2518 BOX DRAWINGS LIGHT UP AND LEFT 0xDA 0x250C BOX DRAWINGS LIGHT DOWN AND RIGHT 0xDB 0x2588 FULL BLOCK 0xDC 0x2584 LOWER HALF BLOCK 0xDD 0x258C LEFT HALF BLOCK 0xDE 0x2590 RIGHT HALF BLOCK 0xDF 0x2580 UPPER HALF BLOCK 0xE0 0x03B1 GREEK SMALL LETTER ALPHA 0xE1 0x00DF LATIN SMALL LETTER SHARP S 0xE2 0x0393 GREEK CAPITAL LETTER GAMMA 0xE3 0x03C0 GREEK SMALL LETTER PI 0xE4 0x03A3 GREEK CAPITAL LETTER SIGMA 0xE5 0x03C3 GREEK SMALL LETTER SIGMA 0xE6 0x00B5 MICRO SIGN 0xE7 0x03C4 GREEK SMALL LETTER TAU 0xE8 0x03A6 GREEK CAPITAL LETTER PHI 0xE9 0x0398 GREEK CAPITAL LETTER THETA 0xEA 0x03A9 GREEK CAPITAL LETTER OMEGA 0xEB 0x03B4 GREEK SMALL LETTER DELTA 0xEC 0x221E INFINITY 0xED 0x03C6 GREEK SMALL LETTER PHI 0xEE 0x03B5 GREEK SMALL LETTER EPSILON 0xEF 0x2229 INTERSECTION 0xF0 0x2261 IDENTICAL TO 0xF1 0x00B1 PLUS-MINUS SIGN 0xF2 0x2265 GREATER-THAN OR EQUAL TO 0xF3 0x2264 LESS-THAN OR EQUAL TO 0xF4 0x2320 TOP HALF INTEGRAL 0xF5 0x2321 BOTTOM HALF INTEGRAL 0xF6 0x00F7 DIVISION SIGN 0xF7 0x2248 ALMOST EQUAL TO 0xF8 0x00B0 DEGREE SIGN 0xF9 0x2219 BULLET OPERATOR 0xFA 0x00B7 MIDDLE DOT 0xFB 0x221A SQUARE ROOT 0xFC 0x207F SUPERSCRIPT LATIN SMALL LETTER N 0xFD 0x00B2 SUPERSCRIPT TWO 0xFE 0x25A0 BLACK SQUARE 0xFF 0x00A0 NO-BREAK SPACE codepage-437-0.1.0/dialect-specs/cp437_wingdings/variants.tsv000064400000000000000000000010731324224472200220010ustar0000000000000000cp437_wingdings Unicode Comment 0x7F 0x0394 Greek capital delta 0xE1 0x03B2 Greek small beta 0xE3 0x03A0 Greek capital pi 0xE3 0x220F n-ary product sign 0xE4 0x2211 n-ary summation sign 0xE6 0x03BC Mu Small 0xEB 0x00F0 small eth 0xEB 0x2202 partial derivative sign 0xED 0x03D5 Phi Small (Closed Form) 0xED 0x1D719 Italicized Phi Small (Closed Form) 0xED 0x2205 empty set sign 0xED 0x2300 diameter sign 0xED 0x00D8 Capital Latin letter O with stroke 0xED 0x00F8 Lowercase Latin letter O with stroke 0xEE 0x2208 element-of sign 0xEE 0x20AC euro sign 0xFB 0x2713 check mark codepage-437-0.1.0/LICENSE000064400000000000000000000020711324025554000127650ustar0000000000000000The MIT License (MIT) Copyright (c) 2018 nabijaczleweli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. codepage-437-0.1.0/README.md000064400000000000000000000013261324025554000132410ustar0000000000000000# codepage-437 [![TravisCI build status](https://travis-ci.org/nabijaczleweli/codepage-437.svg?branch=master)](https://travis-ci.org/nabijaczleweli/codepage-437) [![AppVeyorCI build status](https://ci.appveyor.com/api/projects/status/ptk4p27nlvnf07mw/branch/master?svg=true)](https://ci.appveyor.com/project/nabijaczleweli/codepage-437/branch/master) [![Licence](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) [![Crates.io version](http://meritbadge.herokuapp.com/codepage-437)](https://crates.io/crates/codepage-437) [Code page 437](https://en.wikipedia.org/wiki/Code_page_437) transcoding for Rust. ## [Documentation](https://cdn.rawgit.com/nabijaczleweli/codepage-437/doc/codepage_437/index.html) codepage-437-0.1.0/rustfmt.toml000064400000000000000000000003241324025554000143600ustar0000000000000000max_width = 160 ideal_width = 128 fn_call_width = 96 fn_args_paren_newline = false fn_args_density = "Compressed" struct_trailing_comma = "Always" wrap_comments = true codepage-437-0.1.0/src/decode.rs000064400000000000000000000117751324307325300143550ustar0000000000000000use self::super::Cp437Dialect; use std::iter::FromIterator; use std::borrow::Cow; use std::str; /// Move data encoded in cp437 to a Unicode container of the specified type. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, FromCp437}; /// let cp437 = vec![0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x6E, 0x65, 0x77, 0x73, 0x20, 0x72, 0x65, /// 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, /// 0x65, 0x20, 0x9E, 0xAB, 0x20, 0x6D, 0x69, 0x6C, 0x6C, 0x69, 0x6F, 0x6E, 0x20, /// 0x41, 0x69, 0x72, 0x20, 0x4D, 0x65, 0x6C, 0x61, 0x6E, 0x65, 0x73, 0x69, 0x91, /// 0x20, 0x61, 0x69, 0x72, 0x63, 0x72, 0x61, 0x66, 0x74, 0x20, 0x68, 0x61, 0x73, /// 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, /// 0x20, 0x6D, 0x6F, 0x72, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x72, 0x6F, 0x75, /// 0x6E, 0x64, 0x20, 0x39, 0x3A, 0x30, 0x30, 0x61, 0x6D, 0x2E]; /// let unicode = "Local news reports that the ₧½ million Air Melanesiæ aircraft has crashed this morning around 9:00am."; /// /// assert_eq!(String::from_cp437(cp437, &CP437_CONTROL), unicode); // cp437 is moved out of /// ``` pub trait FromCp437 { /// Do the conversion. fn from_cp437(cp437: T, dialect: &Cp437Dialect) -> Self; } macro_rules! from_cp437_slice_impl { ($($l:expr)*) => ($( impl FromCp437<[u8; $l]> for String { fn from_cp437(cp437: [u8; $l], dialect: &Cp437Dialect) -> Self { from_cp437_slice_impl(&cp437, dialect) } } )*) } impl FromCp437> for String { fn from_cp437(cp437: Vec, dialect: &Cp437Dialect) -> Self { if cp437.iter().all(|&b| dialect.overlap_cp437(b)) { String::from_utf8(cp437).unwrap() } else { String::from_iter(cp437.into_iter().map(|b| dialect.decode(b))) } } } impl FromCp437<[u8; 0]> for String { fn from_cp437(_: [u8; 0], _: &Cp437Dialect) -> Self { String::new() } } from_cp437_slice_impl!( 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); fn from_cp437_slice_impl(cp437: &[u8], dialect: &Cp437Dialect) -> String { if cp437.iter().all(|&b| dialect.overlap_cp437(b)) { String::from_utf8(cp437.to_vec()).unwrap() } else { String::from_iter(cp437.iter().map(|&b| dialect.decode(b))) } } /// Try to borrow data encoded in cp437 as a Unicode container of the specified type. /// /// If that cannot be done, clone it. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, BorrowFromCp437}; /// # use std::borrow::Cow; /// let cp437 = [0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x6E, 0x65, 0x77, 0x73, 0x20, 0x72, 0x65, /// 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, /// 0x65, 0x20, 0x9E, 0xAB, 0x20, 0x6D, 0x69, 0x6C, 0x6C, 0x69, 0x6F, 0x6E, 0x20, /// 0x41, 0x69, 0x72, 0x20, 0x4D, 0x65, 0x6C, 0x61, 0x6E, 0x65, 0x73, 0x69, 0x91, /// 0x20, 0x61, 0x69, 0x72, 0x63, 0x72, 0x61, 0x66, 0x74, 0x20, 0x68, 0x61, 0x73, /// 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, /// 0x20, 0x6D, 0x6F, 0x72, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x72, 0x6F, 0x75, /// 0x6E, 0x64, 0x20, 0x39, 0x3A, 0x30, 0x30, 0x61, 0x6D, 0x2E]; /// let unicode = "Local news reports that the ₧½ million Air Melanesiæ aircraft has crashed this morning around 9:00am."; /// /// assert_eq!(Cow::borrow_from_cp437(&cp437[..], &CP437_CONTROL), /// String::borrow_from_cp437(&cp437[..], &CP437_CONTROL)); /// assert_eq!(Cow::borrow_from_cp437(&cp437[..], &CP437_CONTROL), unicode); /// ``` pub trait BorrowFromCp437<'c, T: ?Sized> { /// Do the conversion. fn borrow_from_cp437(cp437: &'c T, dialect: &Cp437Dialect) -> Self; } impl<'c, T: AsRef<[u8]> + ?Sized> BorrowFromCp437<'c, T> for Cow<'c, str> { fn borrow_from_cp437(cp437: &'c T, dialect: &Cp437Dialect) -> Self { borrow_from_cp437_cow_slice_impl(cp437.as_ref(), dialect) } } impl<'c, T: AsRef<[u8]> + ?Sized> BorrowFromCp437<'c, T> for String { fn borrow_from_cp437(cp437: &'c T, dialect: &Cp437Dialect) -> Self { borrow_from_cp437_string_slice_impl(cp437.as_ref(), dialect) } } fn borrow_from_cp437_cow_slice_impl<'c>(cp437: &'c [u8], dialect: &Cp437Dialect) -> Cow<'c, str> { if cp437.iter().all(|&b| dialect.overlap_cp437(b)) { Cow::Borrowed(str::from_utf8(&cp437[..]).unwrap()) } else { Cow::Owned(String::from_iter(cp437.iter().map(|&b| dialect.decode(b)))) } } fn borrow_from_cp437_string_slice_impl(cp437: &[u8], dialect: &Cp437Dialect) -> String { if cp437.iter().all(|&b| dialect.overlap_cp437(b)) { String::from_utf8(cp437.to_vec()).unwrap() } else { String::from_iter(cp437.iter().map(|&b| dialect.decode(b))) } } codepage-437-0.1.0/src/dialect.rs000064400000000000000000000101301324302546600145220ustar0000000000000000use std::hash::{Hasher, Hash}; use std::borrow::Cow; use std::{cmp, fmt}; /// Specifier for the specific kind of cp437. /// /// Dialects are instances of this type, aggregating data necessary to perform conversions. #[derive(Clone)] pub struct Cp437Dialect { cp437_to_unicode: [char; 256], overlap_unicode: fn(unicode: char) -> bool, overlap_cp437: fn(cp437: u8) -> bool, encode: fn(unicode: char) -> Option, /// cp437, from, to remaps: Cow<'static, [(u8, char, char)]>, } impl Cp437Dialect { /// Check, whether the specified Unicode codepoint overlaps with a cp437 one. #[inline] pub fn overlap_unicode(&self, unicode: char) -> bool { (self.overlap_unicode)(unicode) && !self.remaps.iter().rev().find(|&&(_, _, to)| to == unicode).is_some() } /// Check, whether the specified cp437 codepoint overlaps with a Unicode one. #[inline] pub fn overlap_cp437(&self, cp437: u8) -> bool { (self.overlap_cp437)(cp437) && !self.remaps.iter().rev().find(|&&(whom, _, _)| whom == cp437).is_some() } /// Decode a single cp437 codepoint into a Unicode one. #[inline(always)] pub fn decode(&self, cp437: u8) -> char { self.cp437_to_unicode[cp437 as usize] } /// Try to encode a single Unicode codepoint as a cp437 one. #[inline] pub fn encode(&self, unicode: char) -> Option { self.remaps.iter().rev().find(|&&(_, _, to)| to == unicode).map(|&(whom, _, _)| whom).or_else(|| (self.encode)(unicode)) } /// Map the specified cp437 codepoint mapped to the specified unicode character instead. /// /// # Examples /// /// Remap `√` to `✓`: /// /// ``` /// # use codepage_437::CP437_WINGDINGS; /// let square_root_or_checkmark = CP437_WINGDINGS.encode('√').unwrap(); /// /// let mut mapping = CP437_WINGDINGS.clone(); /// mapping.remap(square_root_or_checkmark, '✓'); /// assert_eq!(mapping.decode(square_root_or_checkmark), '✓'); /// ``` pub fn remap(&mut self, cp437: u8, unicode: char) -> &mut Cp437Dialect { self.remaps.to_mut().push((cp437, self.cp437_to_unicode[cp437 as usize], unicode)); self.cp437_to_unicode[cp437 as usize] = unicode; self } } // These traits are implemented manually, because rustc is at a loss for big arrays (like the 256 one). impl fmt::Debug for Cp437Dialect { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Cp437Dialect") .field("cp437_to_unicode", &&self.cp437_to_unicode[..]) .field("overlap_unicode", &self.overlap_unicode) .field("overlap_cp437", &self.overlap_cp437) .field("encode", &self.encode) .field("remaps", &self.remaps) .finish() } } impl Hash for Cp437Dialect { fn hash(&self, state: &mut H) { self.cp437_to_unicode[..].hash(state); self.overlap_unicode.hash(state); self.overlap_cp437.hash(state); self.encode.hash(state); self.remaps.hash(state); } } impl cmp::Eq for Cp437Dialect {} impl cmp::PartialEq for Cp437Dialect { fn eq(&self, other: &Cp437Dialect) -> bool { self.cp437_to_unicode[..] == other.cp437_to_unicode[..] && // align self.overlap_unicode == other.overlap_unicode && // align self.overlap_cp437 == other.overlap_cp437 && // align self.encode == other.encode && // align self.remaps == other.remaps } } impl cmp::Ord for Cp437Dialect { fn cmp(&self, other: &Cp437Dialect) -> cmp::Ordering { self.cp437_to_unicode[..] .cmp(&other.cp437_to_unicode[..]) .then(self.overlap_unicode.cmp(&other.overlap_unicode)) .then(self.overlap_cp437.cmp(&other.overlap_cp437)) .then(self.encode.cmp(&other.encode)) .then(self.remaps.cmp(&other.remaps)) } } impl cmp::PartialOrd for Cp437Dialect { fn partial_cmp(&self, other: &Cp437Dialect) -> Option { Some(self.cmp(other)) } } include!(concat!(env!("OUT_DIR"), "/dialects.rs")); codepage-437-0.1.0/src/encode.rs000064400000000000000000000217301324136017100143530ustar0000000000000000use self::super::Cp437Dialect; use std::borrow::Cow; /// Errors which can occur when attempting to interpret a string as a sequence of cp437 codepoints. /// /// As such, the `into_cp437` family of functions and functions make use of this error, for example. #[derive(Debug, Copy, Clone, Hash, Eq, Ord, PartialEq, PartialOrd)] pub struct Cp437Error { /// Returns the index in the given string up to which valid cp437 was verified. /// /// It is the maximum index such that `input[..index].to_cp_437()` would return `Ok(_)`. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, ToCp437}; /// // some unrepresentable characters, in a &str /// let word = "Eżektor"; /// /// // ToCp437::to_cp437() returns a Cp437Error /// let error = word.to_cp437(&CP437_CONTROL).unwrap_err(); /// /// // the second character is unrepresentable here /// assert_eq!(error.representable_up_to, 1); /// ``` pub representable_up_to: usize, } /// A possible error value when converting a `String` into a cp437 byte vector. /// /// This type is the error type for the [`into_cp437()`](trait.IntoCp437.html#tymethod.into_cp437) /// function on [`IntoCp437`](trait.IntoCp437.html). It is designed in such a way to carefully avoid reallocations: /// the [`into_string()`](#method.into_string) function will give back the String that was used /// in the conversion attempt. /// /// The [`Cp437Error`](struct.Cp437Error.html) type represents an error that may /// occur when converting a `&str` to a sequence of `u8`s. In this sense, it's /// an analogue to `IntoCp437Error`, and you can get one from a `IntoCp437Error` /// through the [`cp437_error()`](#method.cp437_error) function. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, IntoCp437}; /// // some unrepresentable chracters, in a String /// let word = "Eżektor".to_string(); /// /// let value = word.into_cp437(&CP437_CONTROL); /// /// assert!(value.is_err()); /// assert_eq!(value.unwrap_err().into_string(), "Eżektor".to_string()); /// ``` #[derive(Debug, Clone, Hash, Eq, Ord, PartialEq, PartialOrd)] pub struct IntoCp437Error { string: String, error: Cp437Error, } impl IntoCp437Error { /// Returns a `&str` that was attempted to convert to cp437. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, IntoCp437}; /// // some unrepresentable chracters, in a String /// let word = "Eżektor".to_string(); /// /// let value = word.into_cp437(&CP437_CONTROL); /// /// assert_eq!(value.unwrap_err().as_str(), "Eżektor"); /// ``` pub fn as_str(&self) -> &str { &self.string } /// Returns the `String` that was attempted to convert to cp437. /// /// This function is carefully constructed to avoid allocation. It will /// consume the error, moving out the string, so that a copy of the string /// does not need to be made. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, IntoCp437}; /// // some unrepresentable chracters, in a String /// let word = "Eżektor".to_string(); /// /// let value = word.into_cp437(&CP437_CONTROL); /// /// assert_eq!(value.unwrap_err().into_string(), "Eżektor".to_string()); /// ``` pub fn into_string(self) -> String { self.string } /// Fetch a `Cp437Error` to get more details about the conversion failure. /// /// The [`Cp437Error`](struct.Cp437Error.html) type represents an error that may /// occur when converting a `&str` to a sequence of `u8`s. In this sense, it's /// an analogue to `IntoCp437Error`. See its documentation for more details /// on using it. /// /// # Examples /// /// ``` /// # use codepage_437::{CP437_CONTROL, IntoCp437}; /// // some unrepresentable chracters, in a String /// let word = "Eżektor".to_string(); /// /// let error = word.into_cp437(&CP437_CONTROL).unwrap_err().cp437_error(); /// /// // the first character is unrepresentable here /// assert_eq!(error.representable_up_to, 1); /// ``` pub fn cp437_error(&self) -> Cp437Error { self.error } } /// Move Unicode data to a container of cp437 data. /// /// # Examples /// /// Good: /// /// ``` /// # use codepage_437::{CP437_CONTROL, IntoCp437}; /// let cp437 = vec![0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x6E, 0x65, 0x77, 0x73, 0x20, 0x72, 0x65, /// 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, /// 0x65, 0x20, 0x9E, 0xAB, 0x20, 0x6D, 0x69, 0x6C, 0x6C, 0x69, 0x6F, 0x6E, 0x20, /// 0x41, 0x69, 0x72, 0x20, 0x4D, 0x65, 0x6C, 0x61, 0x6E, 0x65, 0x73, 0x69, 0x91, /// 0x20, 0x61, 0x69, 0x72, 0x63, 0x72, 0x61, 0x66, 0x74, 0x20, 0x68, 0x61, 0x73, /// 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, /// 0x20, 0x6D, 0x6F, 0x72, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x72, 0x6F, 0x75, /// 0x6E, 0x64, 0x20, 0x39, 0x3A, 0x30, 0x30, 0x61, 0x6D, 0x2E]; /// let unicode = /// "Local news reports that the ₧½ million Air Melanesiæ aircraft has crashed this morning around 9:00am.".to_string(); /// /// assert_eq!(unicode.into_cp437(&CP437_CONTROL), Ok(cp437)); // unicode is moved out of /// ``` /// /// Unrepresentable: /// /// ``` /// # use codepage_437::{CP437_CONTROL, IntoCp437}; /// // Ż cannot be represented in cp437 /// let unicode = "Jurek je żurek w żupanie.".to_string(); /// /// let error = unicode.into_cp437(&CP437_CONTROL).unwrap_err(); // unicode is moved out of /// assert_eq!(error.as_str(), "Jurek je żurek w żupanie."); /// assert_eq!(error.cp437_error().representable_up_to, 9); /// /// let unicode = error.into_string(); // unicode now the same as original /// # assert_eq!(unicode, "Jurek je żurek w żupanie."); /// ``` pub trait IntoCp437 { /// Do the conversion. fn into_cp437(self, dialect: &Cp437Dialect) -> Result; } impl IntoCp437> for String { fn into_cp437(self, dialect: &Cp437Dialect) -> Result, IntoCp437Error> { if self.chars().all(|c| dialect.overlap_unicode(c)) { Ok(self.into_bytes()) } else { to_cp437_impl_meat(&self, dialect).map_err(|e| { IntoCp437Error { string: self, error: e, } }) } } } /// Borrow (if possible) Unicode data as cp437 data. /// /// # Examples /// /// Good: /// /// ``` /// # use codepage_437::{CP437_CONTROL, ToCp437}; /// let cp437 = [0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x6E, 0x65, 0x77, 0x73, 0x20, 0x72, 0x65, /// 0x70, 0x6F, 0x72, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, /// 0x65, 0x20, 0x9E, 0xAB, 0x20, 0x6D, 0x69, 0x6C, 0x6C, 0x69, 0x6F, 0x6E, 0x20, /// 0x41, 0x69, 0x72, 0x20, 0x4D, 0x65, 0x6C, 0x61, 0x6E, 0x65, 0x73, 0x69, 0x91, /// 0x20, 0x61, 0x69, 0x72, 0x63, 0x72, 0x61, 0x66, 0x74, 0x20, 0x68, 0x61, 0x73, /// 0x20, 0x63, 0x72, 0x61, 0x73, 0x68, 0x65, 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, /// 0x20, 0x6D, 0x6F, 0x72, 0x6E, 0x69, 0x6E, 0x67, 0x20, 0x61, 0x72, 0x6F, 0x75, /// 0x6E, 0x64, 0x20, 0x39, 0x3A, 0x30, 0x30, 0x61, 0x6D, 0x2E]; /// let unicode = "Local news reports that the ₧½ million Air Melanesiæ aircraft has crashed this morning around 9:00am."; /// /// assert_eq!(unicode.to_cp437(&CP437_CONTROL), Ok(cp437[..].into())); /// ``` /// /// Unrepresentable: /// /// ``` /// # use codepage_437::{CP437_CONTROL, ToCp437}; /// // Ż cannot be represented in cp437 /// let unicode = "Jurek je żurek w żupanie."; /// /// let error = unicode.to_cp437(&CP437_CONTROL).unwrap_err(); /// assert_eq!(error.representable_up_to, 9); /// ``` pub trait ToCp437<'s, T> { /// Do the conversion. fn to_cp437(&'s self, dialect: &Cp437Dialect) -> Result; } impl<'s> ToCp437<'s, Cow<'s, [u8]>> for str { fn to_cp437(&'s self, dialect: &Cp437Dialect) -> Result, Cp437Error> { to_cp437_cow_impl(&self, dialect) } } impl<'s, S: AsRef> ToCp437<'s, Cow<'s, [u8]>> for S { fn to_cp437(&'s self, dialect: &Cp437Dialect) -> Result, Cp437Error> { to_cp437_cow_impl(self.as_ref(), dialect) } } fn to_cp437_cow_impl<'c>(whom: &'c str, dialect: &Cp437Dialect) -> Result, Cp437Error> { if whom.chars().all(|c| dialect.overlap_unicode(c)) { Ok(Cow::Borrowed(whom.as_bytes())) } else { to_cp437_impl_meat(whom, dialect).map(Cow::Owned) } } fn to_cp437_impl_meat(whom: &str, dialect: &Cp437Dialect) -> Result, Cp437Error> { let mut result = Vec::with_capacity(whom.chars().count()); for c in whom.chars() { if let Some(b) = dialect.encode(c) { result.push(b); } else { return Err(Cp437Error { representable_up_to: result.len() }); } } Ok(result) } codepage-437-0.1.0/src/lib.rs000064400000000000000000000066341324135777100137060ustar0000000000000000//! Conversion to and from codepage 437. //! //! Use the `{Borrow,}FromCp437` traits to convert series of cp437 bytes to Unicode, //! and the `cp437_to_unicode()` function to decode a single codepoint. //! //! Use the `{Into,To}Cp437` traits to convert Unicode to a series of cp437 bytes, //! and the `unicode_to_cp437()` function to encode a single codepoint. //! //! # Examples //! //! Borrowing from a buffer: //! //! ``` //! # use codepage_437::{CP437_CONTROL, BorrowFromCp437}; //! # use std::borrow::Cow; //! # /* //! let data = &[/* buffer acquired somewhere */]; //! # */ //! # let data = &[0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x6E, 0x65, 0x77, 0x73]; //! //! /// in_unicode will be Cow::Borrowed if data only contains overlapping characters, //! /// or Cow::Owned if a conversion needed to have been made. //! let in_unicode = Cow::borrow_from_cp437(data, &CP437_CONTROL); //! # assert_eq!(in_unicode, "Local news"); //! //! // Also valid: //! let in_unicode = String::borrow_from_cp437(data, &CP437_CONTROL); //! # assert_eq!(in_unicode, "Local news"); //! ``` //! //! Moving out of a buffer: //! //! ``` //! # use codepage_437::{CP437_CONTROL, FromCp437}; //! # /* //! let data = vec![/* buffer moved in from somewhere */]; //! # */ //! # let data = vec![0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x20, 0x6E, 0x65, 0x77, 0x73]; //! //! /// data is moved out of and zero-alloced into in_unicode //! /// if it only contains overlapping characters //! let in_unicode = String::from_cp437(data, &CP437_CONTROL); //! # assert_eq!(in_unicode, "Local news"); //! ``` //! //! Borrowing from a `&str`: //! //! ``` //! # use codepage_437::{CP437_CONTROL, ToCp437}; //! let data = "Some string."; //! //! /// in_cp437 will be Cow::Borrowed if data only contains overlapping characters, //! /// Cow::Owned if a conversion needed to have been made, //! /// or Err, if data can't be represented as cp437 //! let in_cp437 = data.to_cp437(&CP437_CONTROL); //! # assert_eq!(in_cp437, Ok([0x53, 0x6F, 0x6D, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E][..].into())); //! //! // Also valid (String is AsRef): //! let data = "Some string.".to_string(); //! let in_cp437 = data.to_cp437(&CP437_CONTROL); //! # assert_eq!(in_cp437, Ok([0x53, 0x6F, 0x6D, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E][..].into())); //! ``` //! //! Moving out of a `String`: //! //! ``` //! # use codepage_437::{CP437_CONTROL, IntoCp437}; //! let data = "Some string.".to_string(); //! //! /// data is moved out of and zero-alloced into in_cp437 //! /// if it only contains overlapping characters //! let in_cp437 = data.into_cp437(&CP437_CONTROL); //! # assert_eq!(in_cp437, Ok([0x53, 0x6F, 0x6D, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x2E][..].into())); //! ``` //! //! Unrepresentable Unicode: //! //! ``` //! # use codepage_437::{CP437_CONTROL, ToCp437}; //! // Ż has no representation in cp437 //! let data = "Jurek żelaznym żurkiem żre żupan."; //! //! let result = data.to_cp437(&CP437_CONTROL); //! assert!(result.is_err()); //! // result.unwrap_err() is Cp437Error (or IntoCp437Error for into_cp437()), //! // with an API modeled after libstd's {From,}Utf8Error //! # assert_eq!(result.unwrap_err().representable_up_to, 6); //! ``` mod decode; mod encode; mod dialect; pub use self::dialect::*; pub use self::decode::{BorrowFromCp437, FromCp437}; pub use self::encode::{IntoCp437Error, Cp437Error, IntoCp437, ToCp437}; codepage-437-0.1.0/test-data/all.cp437000064400000000000000000000004001324031327600151730ustar0000000000000000  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~codepage-437-0.1.0/test-data/cp437_control/all.utf8000064400000000000000000000006761324031356700176430ustar0000000000000000  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ codepage-437-0.1.0/test-data/cp437_control/variants.cp437000064400000000000000000000000211324111457500206530ustar0000000000000000codepage-437-0.1.0/test-data/cp437_control/variants.utf8000064400000000000000000000000541324111444300207010ustar0000000000000000ΔβΠ∏∑μð∂ϕ𝜙∅⌀Øø∈€✓codepage-437-0.1.0/test-data/cp437_wingdings/all.utf8000064400000000000000000000007741324211005100201340ustar0000000000000000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ codepage-437-0.1.0/test-data/cp437_wingdings/variants.cp437000064400000000000000000000000211324111457500211640ustar0000000000000000codepage-437-0.1.0/test-data/cp437_wingdings/variants.utf8000064400000000000000000000000541324111444300212120ustar0000000000000000ΔβΠ∏∑μð∂ϕ𝜙∅⌀Øø∈€✓codepage-437-0.1.0/tests/cp437_control/decode/borrow_from_cp437/borrowing.rs000064400000000000000000000024501324135734000246030ustar0000000000000000use codepage_437::{CP437_CONTROL, BorrowFromCp437}; use self::super::super::super::is_borrowed; use std::borrow::Cow; #[test] fn borrowed_for_ascii_subset() { let mut data = vec![]; while data.len() <= 0x7F { let dlen = data.len(); data.push(dlen as u8); assert!(is_borrowed(&Cow::borrow_from_cp437(&data, &CP437_CONTROL))); assert!(is_borrowed(&Cow::borrow_from_cp437(&[*data.last().unwrap()], &CP437_CONTROL))); } } #[test] fn owned_for_ascii_superset() { let mut data = vec![]; while data.len() <= (0xFF - 0x80) { let dlen = data.len(); data.push((dlen + 0x80) as u8); assert!(!is_borrowed(&Cow::borrow_from_cp437(&data, &CP437_CONTROL))); assert!(!is_borrowed(&Cow::borrow_from_cp437(&[*data.last().unwrap()], &CP437_CONTROL))); } } #[test] fn owned_for_both() { let mut superset_idx = 0; let mut data = vec![0x80]; while data.len() <= 0x7F { data.pop(); let dlen = data.len(); data.push(dlen as u8); data.push((0x80 + (superset_idx % (0xFF - 0x80))) as u8); superset_idx += 1; assert!(!is_borrowed(&Cow::borrow_from_cp437(&data, &CP437_CONTROL))); assert!(!is_borrowed(&Cow::borrow_from_cp437(&[data[dlen], data[dlen + 1]], &CP437_CONTROL))); } } codepage-437-0.1.0/tests/cp437_control/decode/borrow_from_cp437/conversion.rs000064400000000000000000000034121324157515100247610ustar0000000000000000use codepage_437::{CP437_CONTROL, BorrowFromCp437}; use self::super::super::super::super::ALL_CP437; use self::super::super::super::ALL_UTF8; use std::borrow::Cow; macro_rules! array_test { ($test_name:ident, $sz:expr) => { #[test] fn $test_name() { let mut buf = [0u8; $sz]; buf.copy_from_slice(&ALL_CP437[..$sz]); let expected: String = ALL_UTF8.chars().take($sz).collect(); assert_eq!(Cow::borrow_from_cp437(&buf, &CP437_CONTROL), expected); assert_eq!(String::borrow_from_cp437(&buf, &CP437_CONTROL), expected); } } } #[test] fn slice() { assert_eq!(Cow::borrow_from_cp437(ALL_CP437, &CP437_CONTROL), ALL_UTF8); assert_eq!(String::borrow_from_cp437(ALL_CP437, &CP437_CONTROL), ALL_UTF8); } #[test] fn vec() { assert_eq!(Cow::borrow_from_cp437(&ALL_CP437.to_vec(), &CP437_CONTROL), ALL_UTF8); assert_eq!(String::borrow_from_cp437(&ALL_CP437.to_vec(), &CP437_CONTROL), ALL_UTF8); } array_test!(array_0, 0); array_test!(array_1, 1); array_test!(array_2, 2); array_test!(array_3, 3); array_test!(array_4, 4); array_test!(array_5, 5); array_test!(array_6, 6); array_test!(array_7, 7); array_test!(array_8, 8); array_test!(array_9, 9); array_test!(array_10, 10); array_test!(array_11, 11); array_test!(array_12, 12); array_test!(array_13, 13); array_test!(array_14, 14); array_test!(array_15, 15); array_test!(array_16, 16); array_test!(array_17, 17); array_test!(array_18, 18); array_test!(array_19, 19); array_test!(array_20, 20); array_test!(array_21, 21); array_test!(array_22, 22); array_test!(array_23, 23); array_test!(array_24, 24); array_test!(array_25, 25); array_test!(array_26, 26); array_test!(array_27, 27); array_test!(array_28, 28); array_test!(array_29, 29); array_test!(array_30, 30); array_test!(array_31, 31); array_test!(array_32, 32); codepage-437-0.1.0/tests/cp437_control/decode/borrow_from_cp437/mod.rs000064400000000000000000000000371324115313700233470ustar0000000000000000mod conversion; mod borrowing; codepage-437-0.1.0/tests/cp437_control/decode/from_cp437.rs000064400000000000000000000025421324157516300212100ustar0000000000000000use codepage_437::{CP437_CONTROL, FromCp437}; use self::super::super::super::ALL_CP437; use self::super::super::ALL_UTF8; macro_rules! array_test { ($test_name:ident, $sz:expr) => { #[test] fn $test_name() { let mut buf = [0u8; $sz]; buf.copy_from_slice(&ALL_CP437[..$sz]); assert_eq!(String::from_cp437(buf, &CP437_CONTROL), ALL_UTF8.chars().take($sz).collect::()); } } } #[test] fn vec() { assert_eq!(String::from_cp437(ALL_CP437.to_vec(), &CP437_CONTROL), ALL_UTF8); } array_test!(array_0, 0); array_test!(array_1, 1); array_test!(array_2, 2); array_test!(array_3, 3); array_test!(array_4, 4); array_test!(array_5, 5); array_test!(array_6, 6); array_test!(array_7, 7); array_test!(array_8, 8); array_test!(array_9, 9); array_test!(array_10, 10); array_test!(array_11, 11); array_test!(array_12, 12); array_test!(array_13, 13); array_test!(array_14, 14); array_test!(array_15, 15); array_test!(array_16, 16); array_test!(array_17, 17); array_test!(array_18, 18); array_test!(array_19, 19); array_test!(array_20, 20); array_test!(array_21, 21); array_test!(array_22, 22); array_test!(array_23, 23); array_test!(array_24, 24); array_test!(array_25, 25); array_test!(array_26, 26); array_test!(array_27, 27); array_test!(array_28, 28); array_test!(array_29, 29); array_test!(array_30, 30); array_test!(array_31, 31); array_test!(array_32, 32); codepage-437-0.1.0/tests/cp437_control/decode/mod.rs000064400000000000000000000011201324211040300200520ustar0000000000000000use self::super::super::ALL_CP437; use codepage_437::CP437_CONTROL; use self::super:: ALL_UTF8; mod borrow_from_cp437; mod from_cp437; #[test] fn decode() { let mut full_size = 0; for (cnt, (&b, c)) in ALL_CP437.iter().zip(ALL_UTF8.chars()).enumerate() { assert_eq!(CP437_CONTROL.decode(b), c); if CP437_CONTROL.overlap_cp437(b) { assert_eq!(b as char, c); } assert_eq!(b as usize, cnt); // Verify test data is consecutive full_size = cnt; } // Verify test data covers all 256 bytes assert_eq!(full_size, 0xFF); } codepage-437-0.1.0/tests/cp437_control/encode/encode.rs000064400000000000000000000011071324157521400205650ustar0000000000000000use self::super::super::{VARIANTS_CP437, VARIANTS_UTF8, ALL_UTF8}; use self::super::super::super::ALL_CP437; use codepage_437::CP437_CONTROL; #[test] fn normal() { for (&b, c) in ALL_CP437.iter().zip(ALL_UTF8.chars()) { assert_eq!(CP437_CONTROL.encode(c), Some(b)); } } #[test] fn variants() { for (&b, c) in VARIANTS_CP437.iter().zip(VARIANTS_UTF8.chars()) { assert_eq!(CP437_CONTROL.encode(c), Some(b)); } } #[test] fn unmapped() { for c in "ĄĘĆŹŻŃŁąęćźżńł".chars() { assert_eq!(CP437_CONTROL.encode(c), None); } } codepage-437-0.1.0/tests/cp437_control/encode/into_cp437.rs000064400000000000000000000013771324157523100212310ustar0000000000000000use self::super::super::{VARIANTS_CP437, VARIANTS_UTF8, ALL_UTF8}; use codepage_437::{CP437_CONTROL, Cp437Error, IntoCp437}; use self::super::super::super::ALL_CP437; #[test] fn good() { let everything_utf8 = ALL_UTF8.to_string() + VARIANTS_UTF8; let mut everything_cp437 = ALL_CP437.to_vec(); everything_cp437.extend(VARIANTS_CP437); assert_eq!(everything_utf8.into_cp437(&CP437_CONTROL), Ok(everything_cp437)); } #[test] fn unrepresentable() { let err = "Jurek je żurek w żupanie.".to_string().into_cp437(&CP437_CONTROL).unwrap_err(); assert_eq!(err.as_str(), "Jurek je żurek w żupanie."); assert_eq!(err.cp437_error(), Cp437Error { representable_up_to: 9 }); assert_eq!(err.into_string(), "Jurek je żurek w żupanie."); } codepage-437-0.1.0/tests/cp437_control/encode/mod.rs000064400000000000000000000000521324135706100201030ustar0000000000000000mod into_cp437; mod to_cp437; mod encode; codepage-437-0.1.0/tests/cp437_control/encode/to_cp437/borrowing.rs000064400000000000000000000025111324135722500227020ustar0000000000000000use self::super::super::super::{VARIANTS_UTF8, ALL_UTF8, is_borrowed}; use codepage_437::{CP437_CONTROL, ToCp437}; #[test] fn borrowed_for_ascii() { let mut data = String::new(); for c in ALL_UTF8.chars().take(0x80) { data.push(c); assert!(is_borrowed(&data.to_cp437(&CP437_CONTROL).unwrap())); assert!(is_borrowed(&[c].into_iter().collect::().to_cp437(&CP437_CONTROL).unwrap())); } } #[test] fn owned_for_beyond_ascii() { let mut data = String::new(); for c in ALL_UTF8.chars().skip(0x80).chain(VARIANTS_UTF8.chars()) { data.push(c); assert!(!is_borrowed(&data.to_cp437(&CP437_CONTROL).unwrap())); assert!(!is_borrowed(&[c].into_iter().collect::().to_cp437(&CP437_CONTROL).unwrap())); } } #[test] fn owned_for_both() { let mut beyond_iter = ALL_UTF8.chars().skip(0x80).chain(VARIANTS_UTF8.chars()).cycle(); let mut data = String::new(); data.push(beyond_iter.next().unwrap()); for c in ALL_UTF8.chars().take(0x80) { let new_beyond = beyond_iter.next().unwrap(); data.pop(); data.push(c); data.push(new_beyond); assert!(!is_borrowed(&data.to_cp437(&CP437_CONTROL).unwrap())); assert!(!is_borrowed(&[c, new_beyond].into_iter().collect::().to_cp437(&CP437_CONTROL).unwrap())); } } codepage-437-0.1.0/tests/cp437_control/encode/to_cp437/conversion.rs000064400000000000000000000012741324157524100230640ustar0000000000000000use self::super::super::super::{VARIANTS_CP437, VARIANTS_UTF8, ALL_UTF8}; use codepage_437::{CP437_CONTROL, Cp437Error, ToCp437}; use self::super::super::super::super::ALL_CP437; #[test] fn good() { let everything_utf8 = ALL_UTF8.to_string() + VARIANTS_UTF8; let mut everything_cp437 = ALL_CP437.to_vec(); everything_cp437.extend(VARIANTS_CP437); assert_eq!(everything_utf8.to_cp437(&CP437_CONTROL), Ok(everything_cp437[..].into())); assert_eq!(everything_utf8[..].to_cp437(&CP437_CONTROL), Ok(everything_cp437[..].into())); } #[test] fn unrepresentable() { assert_eq!("Jurek je żurek w żupanie.".to_cp437(&CP437_CONTROL), Err(Cp437Error { representable_up_to: 9 })); } codepage-437-0.1.0/tests/cp437_control/encode/to_cp437/mod.rs000064400000000000000000000000371324115313700214460ustar0000000000000000mod conversion; mod borrowing; codepage-437-0.1.0/tests/cp437_control/mod.rs000064400000000000000000000007221324156644100166560ustar0000000000000000use std::borrow::Cow; mod decode; mod encode; const ALL_UTF8: &str = include_str!("../../test-data/cp437_control/all.utf8"); const VARIANTS_CP437: &[u8] = include_bytes!("../../test-data/cp437_control/variants.cp437"); const VARIANTS_UTF8: &str = include_str!("../../test-data/cp437_control/variants.utf8"); fn is_borrowed(who: &Cow) -> bool { match who { &Cow::Borrowed(_) => true, &Cow::Owned(_) => false, } } codepage-437-0.1.0/tests/cp437_wingdings/decode/borrow_from_cp437/borrowing.rs000064400000000000000000000023441324211226200251070ustar0000000000000000use codepage_437::{CP437_WINGDINGS, BorrowFromCp437}; use self::super::super::super::is_borrowed; use std::borrow::Cow; #[test] fn borrowed_for_ascii_subset() { let mut data = vec![]; for b in (0x00..0x01).chain(0x20..0x7F) { data.push(b); assert!(is_borrowed(&Cow::borrow_from_cp437(&data, &CP437_WINGDINGS))); assert!(is_borrowed(&Cow::borrow_from_cp437(&[b], &CP437_WINGDINGS))); } } #[test] fn owned_for_ascii_superset() { let mut data = vec![]; for b in (0x01..0x20).chain(0x80..0x100) { let b = b as u8; data.push(b); assert!(!is_borrowed(&Cow::borrow_from_cp437(&data, &CP437_WINGDINGS))); assert!(!is_borrowed(&Cow::borrow_from_cp437(&[b], &CP437_WINGDINGS))); } } #[test] fn owned_for_both() { let mut superset_idx = 0; let mut data = vec![0x80]; while data.len() <= 0x7F { data.pop(); let dlen = data.len(); data.push(dlen as u8); data.push((0x80 + (superset_idx % (0xFF - 0x80))) as u8); superset_idx += 1; assert!(!is_borrowed(&Cow::borrow_from_cp437(&data, &CP437_WINGDINGS))); assert!(!is_borrowed(&Cow::borrow_from_cp437(&[data[dlen], data[dlen + 1]], &CP437_WINGDINGS))); } } codepage-437-0.1.0/tests/cp437_wingdings/decode/borrow_from_cp437/conversion.rs000064400000000000000000000034301324157541500252750ustar0000000000000000use codepage_437::{CP437_WINGDINGS, BorrowFromCp437}; use self::super::super::super::super::ALL_CP437; use self::super::super::super::ALL_UTF8; use std::borrow::Cow; macro_rules! array_test { ($test_name:ident, $sz:expr) => { #[test] fn $test_name() { let mut buf = [0u8; $sz]; buf.copy_from_slice(&ALL_CP437[..$sz]); let expected: String = ALL_UTF8.chars().take($sz).collect(); assert_eq!(Cow::borrow_from_cp437(&buf, &CP437_WINGDINGS), expected); assert_eq!(String::borrow_from_cp437(&buf, &CP437_WINGDINGS), expected); } } } #[test] fn slice() { assert_eq!(Cow::borrow_from_cp437(ALL_CP437, &CP437_WINGDINGS), ALL_UTF8); assert_eq!(String::borrow_from_cp437(ALL_CP437, &CP437_WINGDINGS), ALL_UTF8); } #[test] fn vec() { assert_eq!(Cow::borrow_from_cp437(&ALL_CP437.to_vec(), &CP437_WINGDINGS), ALL_UTF8); assert_eq!(String::borrow_from_cp437(&ALL_CP437.to_vec(), &CP437_WINGDINGS), ALL_UTF8); } array_test!(array_0, 0); array_test!(array_1, 1); array_test!(array_2, 2); array_test!(array_3, 3); array_test!(array_4, 4); array_test!(array_5, 5); array_test!(array_6, 6); array_test!(array_7, 7); array_test!(array_8, 8); array_test!(array_9, 9); array_test!(array_10, 10); array_test!(array_11, 11); array_test!(array_12, 12); array_test!(array_13, 13); array_test!(array_14, 14); array_test!(array_15, 15); array_test!(array_16, 16); array_test!(array_17, 17); array_test!(array_18, 18); array_test!(array_19, 19); array_test!(array_20, 20); array_test!(array_21, 21); array_test!(array_22, 22); array_test!(array_23, 23); array_test!(array_24, 24); array_test!(array_25, 25); array_test!(array_26, 26); array_test!(array_27, 27); array_test!(array_28, 28); array_test!(array_29, 29); array_test!(array_30, 30); array_test!(array_31, 31); array_test!(array_32, 32); codepage-437-0.1.0/tests/cp437_wingdings/decode/borrow_from_cp437/mod.rs000064400000000000000000000000371324115313700236600ustar0000000000000000mod conversion; mod borrowing; codepage-437-0.1.0/tests/cp437_wingdings/decode/from_cp437.rs000064400000000000000000000025501324157541500215200ustar0000000000000000use codepage_437::{CP437_WINGDINGS, FromCp437}; use self::super::super::super::ALL_CP437; use self::super::super::ALL_UTF8; macro_rules! array_test { ($test_name:ident, $sz:expr) => { #[test] fn $test_name() { let mut buf = [0u8; $sz]; buf.copy_from_slice(&ALL_CP437[..$sz]); assert_eq!(String::from_cp437(buf, &CP437_WINGDINGS), ALL_UTF8.chars().take($sz).collect::()); } } } #[test] fn vec() { assert_eq!(String::from_cp437(ALL_CP437.to_vec(), &CP437_WINGDINGS), ALL_UTF8); } array_test!(array_0, 0); array_test!(array_1, 1); array_test!(array_2, 2); array_test!(array_3, 3); array_test!(array_4, 4); array_test!(array_5, 5); array_test!(array_6, 6); array_test!(array_7, 7); array_test!(array_8, 8); array_test!(array_9, 9); array_test!(array_10, 10); array_test!(array_11, 11); array_test!(array_12, 12); array_test!(array_13, 13); array_test!(array_14, 14); array_test!(array_15, 15); array_test!(array_16, 16); array_test!(array_17, 17); array_test!(array_18, 18); array_test!(array_19, 19); array_test!(array_20, 20); array_test!(array_21, 21); array_test!(array_22, 22); array_test!(array_23, 23); array_test!(array_24, 24); array_test!(array_25, 25); array_test!(array_26, 26); array_test!(array_27, 27); array_test!(array_28, 28); array_test!(array_29, 29); array_test!(array_30, 30); array_test!(array_31, 31); array_test!(array_32, 32); codepage-437-0.1.0/tests/cp437_wingdings/decode/mod.rs000064400000000000000000000011261324211036700204020ustar0000000000000000use self::super::super::ALL_CP437; use codepage_437::CP437_WINGDINGS; use self::super:: ALL_UTF8; mod borrow_from_cp437; mod from_cp437; #[test] fn decode() { let mut full_size = 0; for (cnt, (&b, c)) in ALL_CP437.iter().zip(ALL_UTF8.chars()).enumerate() { assert_eq!(CP437_WINGDINGS.decode(b), c); if CP437_WINGDINGS.overlap_cp437(b) { assert_eq!(b as char, c); } assert_eq!(b as usize, cnt); // Verify test data is consecutive full_size = cnt; } // Verify test data covers all 256 bytes assert_eq!(full_size, 0xFF); } codepage-437-0.1.0/tests/cp437_wingdings/encode/encode.rs000064400000000000000000000011171324211204700210670ustar0000000000000000use self::super::super::{VARIANTS_CP437, VARIANTS_UTF8, ALL_UTF8}; use self::super::super::super::ALL_CP437; use codepage_437::CP437_WINGDINGS; #[test] fn normal() { for (&b, c) in ALL_CP437.iter().zip(ALL_UTF8.chars()) { assert_eq!(CP437_WINGDINGS.encode(c), Some(b)); } } #[test] fn variants() { for (&b, c) in VARIANTS_CP437.iter().zip(VARIANTS_UTF8.chars()) { assert_eq!(CP437_WINGDINGS.encode(c), Some(b)); } } #[test] fn unmapped() { for c in "ĄĘĆŹŻŃŁąęćźżńł".chars() { assert_eq!(CP437_WINGDINGS.encode(c), None); } } codepage-437-0.1.0/tests/cp437_wingdings/encode/into_cp437.rs000064400000000000000000000014051324157541500215360ustar0000000000000000use self::super::super::{VARIANTS_CP437, VARIANTS_UTF8, ALL_UTF8}; use codepage_437::{CP437_WINGDINGS, Cp437Error, IntoCp437}; use self::super::super::super::ALL_CP437; #[test] fn good() { let everything_utf8 = ALL_UTF8.to_string() + VARIANTS_UTF8; let mut everything_cp437 = ALL_CP437.to_vec(); everything_cp437.extend(VARIANTS_CP437); assert_eq!(everything_utf8.into_cp437(&CP437_WINGDINGS), Ok(everything_cp437)); } #[test] fn unrepresentable() { let err = "Jurek je żurek w żupanie.".to_string().into_cp437(&CP437_WINGDINGS).unwrap_err(); assert_eq!(err.as_str(), "Jurek je żurek w żupanie."); assert_eq!(err.cp437_error(), Cp437Error { representable_up_to: 9 }); assert_eq!(err.into_string(), "Jurek je żurek w żupanie."); } codepage-437-0.1.0/tests/cp437_wingdings/encode/mod.rs000064400000000000000000000000521324135706100204140ustar0000000000000000mod into_cp437; mod to_cp437; mod encode; codepage-437-0.1.0/tests/cp437_wingdings/encode/to_cp437/borrowing.rs000064400000000000000000000026731324211241200232100ustar0000000000000000use self::super::super::super::{VARIANTS_UTF8, ALL_UTF8, is_borrowed}; use codepage_437::{CP437_WINGDINGS, ToCp437}; #[test] fn borrowed_for_ascii() { let mut data = String::new(); for c in ALL_UTF8.chars().take(1).chain(ALL_UTF8.chars().skip(0x20).take(0x7F - 0x20)) { data.push(c); assert!(is_borrowed(&data.to_cp437(&CP437_WINGDINGS).unwrap())); assert!(is_borrowed(&[c].into_iter().collect::().to_cp437(&CP437_WINGDINGS).unwrap())); } } #[test] fn owned_for_beyond_ascii() { let mut data = String::new(); for c in ALL_UTF8.chars().skip(0x7F).chain(VARIANTS_UTF8.chars()) { data.push(c); assert!(!is_borrowed(&data.to_cp437(&CP437_WINGDINGS).unwrap())); assert!(!is_borrowed(&[c].into_iter().collect::().to_cp437(&CP437_WINGDINGS).unwrap())); } } #[test] fn owned_for_both() { let mut beyond_iter = ALL_UTF8.chars().skip(0x7F).chain(VARIANTS_UTF8.chars()).cycle(); let mut data = String::new(); data.push(beyond_iter.next().unwrap()); for c in ALL_UTF8.chars().take(1).chain(ALL_UTF8.chars().skip(0x20).take(0x7F - 0x20)) { let new_beyond = beyond_iter.next().unwrap(); data.pop(); data.push(c); data.push(new_beyond); assert!(!is_borrowed(&data.to_cp437(&CP437_WINGDINGS).unwrap())); assert!(!is_borrowed(&[c, new_beyond].into_iter().collect::().to_cp437(&CP437_WINGDINGS).unwrap())); } } codepage-437-0.1.0/tests/cp437_wingdings/encode/to_cp437/conversion.rs000064400000000000000000000013041324157541500233720ustar0000000000000000use self::super::super::super::{VARIANTS_CP437, VARIANTS_UTF8, ALL_UTF8}; use codepage_437::{CP437_WINGDINGS, Cp437Error, ToCp437}; use self::super::super::super::super::ALL_CP437; #[test] fn good() { let everything_utf8 = ALL_UTF8.to_string() + VARIANTS_UTF8; let mut everything_cp437 = ALL_CP437.to_vec(); everything_cp437.extend(VARIANTS_CP437); assert_eq!(everything_utf8.to_cp437(&CP437_WINGDINGS), Ok(everything_cp437[..].into())); assert_eq!(everything_utf8[..].to_cp437(&CP437_WINGDINGS), Ok(everything_cp437[..].into())); } #[test] fn unrepresentable() { assert_eq!("Jurek je żurek w żupanie.".to_cp437(&CP437_WINGDINGS), Err(Cp437Error { representable_up_to: 9 })); } codepage-437-0.1.0/tests/cp437_wingdings/encode/to_cp437/mod.rs000064400000000000000000000000371324115313700217570ustar0000000000000000mod conversion; mod borrowing; codepage-437-0.1.0/tests/cp437_wingdings/mod.rs000064400000000000000000000007301324157537200171710ustar0000000000000000use std::borrow::Cow; mod decode; mod encode; const ALL_UTF8: &str = include_str!("../../test-data/cp437_wingdings/all.utf8"); const VARIANTS_CP437: &[u8] = include_bytes!("../../test-data/cp437_wingdings/variants.cp437"); const VARIANTS_UTF8: &str = include_str!("../../test-data/cp437_wingdings/variants.utf8"); fn is_borrowed(who: &Cow) -> bool { match who { &Cow::Borrowed(_) => true, &Cow::Owned(_) => false, } } codepage-437-0.1.0/tests/dialect/mod.rs000064400000000000000000000000131324265061700156540ustar0000000000000000mod remap; codepage-437-0.1.0/tests/dialect/remap.rs000064400000000000000000000032041324303562500162030ustar0000000000000000use codepage_437::CP437_WINGDINGS; #[test] fn simple() { assert_eq!(CP437_WINGDINGS.encode('√'), Some(0xFB)); assert_eq!(CP437_WINGDINGS.encode('✓'), Some(0xFB)); assert_eq!(CP437_WINGDINGS.decode(0xFB), '√'); let mut mapping = CP437_WINGDINGS.clone(); mapping.remap(0xFB, '✓'); assert_eq!(mapping.encode('√'), Some(0xFB)); assert_eq!(mapping.encode('✓'), Some(0xFB)); assert_eq!(mapping.decode(0xFB), '✓'); } #[test] fn hard() { assert_eq!(CP437_WINGDINGS.encode('Ź'), None); assert_eq!(CP437_WINGDINGS.encode('A'), Some(0x41)); assert_eq!(CP437_WINGDINGS.decode(0x41), 'A'); let mut mapping = CP437_WINGDINGS.clone(); mapping.remap(0x41, 'Ź'); assert_eq!(mapping.encode('Ź'), Some(0x41)); assert_eq!(mapping.encode('A'), Some(0x41)); // NB: still holds assert_eq!(mapping.decode(0x41), 'Ź'); } #[test] fn double() { assert_eq!(CP437_WINGDINGS.encode('Ź'), None); assert_eq!(CP437_WINGDINGS.encode('A'), Some(0x41)); assert_eq!(CP437_WINGDINGS.encode('√'), Some(0xFB)); assert_eq!(CP437_WINGDINGS.encode('✓'), Some(0xFB)); assert_eq!(CP437_WINGDINGS.decode(0x41), 'A'); assert_eq!(CP437_WINGDINGS.decode(0xFB), '√'); let mut mapping = CP437_WINGDINGS.clone(); mapping.remap(0x41, 'Ź'); mapping.remap(0xFB, '✓'); assert_eq!(mapping.encode('Ź'), Some(0x41)); assert_eq!(mapping.encode('A'), Some(0x41)); // NB: still holds assert_eq!(mapping.encode('√'), Some(0xFB)); assert_eq!(mapping.encode('✓'), Some(0xFB)); assert_eq!(mapping.decode(0x41), 'Ź'); assert_eq!(mapping.decode(0xFB), '✓'); } codepage-437-0.1.0/tests/mod.rs000064400000000000000000000002261324265014000142440ustar0000000000000000extern crate codepage_437; mod cp437_wingdings; mod cp437_control; mod dialect; const ALL_CP437: &[u8] = include_bytes!("../test-data/all.cp437");