group cp437 functions
This commit is contained in:
		
							parent
							
								
									dea176d0d9
								
							
						
					
					
						commit
						4f83aa3d5c
					
				
					 3 changed files with 60 additions and 59 deletions
				
			
		|  | @ -1,57 +1,54 @@ | |||
| //! Conversion between UTF-8 and CP-437.
 | ||||
| //!
 | ||||
| //! Most of the functionality is only available with feature "cp437" enabled.
 | ||||
| 
 | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| #[allow(unused)] // depends on features
 | ||||
| pub use feature_cp437::*; | ||||
| /// Contains functions to convert between UTF-8 and Codepage 437.
 | ||||
| ///
 | ||||
| /// See <https://en.wikipedia.org/wiki/Code_page_437#Character_set>
 | ||||
| pub struct Cp437Converter; | ||||
| 
 | ||||
| #[cfg(feature = "cp437")] | ||||
| mod feature_cp437 { | ||||
|     use super::*; | ||||
| 
 | ||||
|     /// An array of 256 elements, mapping most of the CP437 values to UTF-8 characters
 | ||||
|     ///
 | ||||
|     /// Mostly follows CP437, except 0x0A, which is kept for use as line ending.
 | ||||
|     ///
 | ||||
|     /// See <https://en.wikipedia.org/wiki/Code_page_437#Character_set>
 | ||||
|     ///
 | ||||
|     /// Mostly copied from <https://github.com/kip93/cp437-tools>. License: GPL-3.0
 | ||||
|     #[rustfmt::skip] | ||||
|     pub const CP437_TO_UTF8: [char; 256] = [ | ||||
|         /* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '♪', '♫', '☼', | ||||
|         /* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '→', '←', '∟', '↔',  '▲', '▼', | ||||
|         /* 2X */ ' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/', | ||||
|         /* 3X */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', | ||||
|         /* 4X */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', | ||||
|         /* 5X */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_', | ||||
|         /* 6X */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||||
|         /* 7X */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '⌂', | ||||
|         /* 8X */ 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è', 'ï', 'î', 'ì', 'Ä', 'Å', | ||||
|         /* 9X */ 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', '¢', '£', '¥', '₧', 'ƒ', | ||||
|         /* AX */ 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '⌐', '¬', '½', '¼', '¡', '«', '»', | ||||
|         /* BX */ '░', '▒', '▓', '│', '┤', '╡', '╢', '╖', '╕', '╣', '║', '╗', '╝', '╜', '╛', '┐', | ||||
|         /* CX */ '└', '┴', '┬', '├', '─', '┼', '╞', '╟', '╚', '╔', '╩', '╦', '╠', '═', '╬', '╧', | ||||
|         /* DX */ '╨', '╤', '╥', '╙', '╘', '╒', '╓', '╫', '╪', '┘', '┌', '█', '▄', '▌', '▐', '▀', | ||||
|         /* EX */ 'α', 'ß', 'Γ', 'π', 'Σ', 'σ', 'µ', 'τ', 'Φ', 'Θ', 'Ω', 'δ', '∞', 'φ', 'ε', '∩', | ||||
|         /* FX */ '≡', '±', '≥', '≤', '⌠', '⌡', '÷', '≈', '°', '∙', '·', '√', 'ⁿ', '²', '■', ' ', | ||||
|     ]; | ||||
| 
 | ||||
|     static UTF8_TO_CP437: once_cell::sync::Lazy<HashMap<char, u8>> = | ||||
|         once_cell::sync::Lazy::new(|| { | ||||
|             let pairs = CP437_TO_UTF8 | ||||
|                 .iter() | ||||
|                 .enumerate() | ||||
|                 .map(move |(index, char)| (*char, index as u8)); | ||||
|             HashMap::from_iter(pairs) | ||||
|         }); | ||||
| /// An array of 256 elements, mapping most of the CP437 values to UTF-8 characters
 | ||||
| ///
 | ||||
| /// Mostly follows CP437, except 0x0A, which is kept for use as line ending.
 | ||||
| ///
 | ||||
| /// See <https://en.wikipedia.org/wiki/Code_page_437#Character_set>
 | ||||
| ///
 | ||||
| /// Mostly copied from <https://github.com/kip93/cp437-tools>. License: GPL-3.0
 | ||||
| #[rustfmt::skip] | ||||
| const CP437_TO_UTF8: [char; 256] = [ | ||||
|     /* 0X */ '\0', '☺', '☻', '♥', '♦', '♣', '♠', '•', '◘', '○', '\n', '♂', '♀', '♪', '♫', '☼', | ||||
|     /* 1X */ '►', '◄', '↕', '‼', '¶', '§', '▬', '↨', '↑', '↓', '→', '←', '∟', '↔',  '▲', '▼', | ||||
|     /* 2X */ ' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/', | ||||
|     /* 3X */ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', | ||||
|     /* 4X */ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', | ||||
|     /* 5X */ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_', | ||||
|     /* 6X */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', | ||||
|     /* 7X */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', '⌂', | ||||
|     /* 8X */ 'Ç', 'ü', 'é', 'â', 'ä', 'à', 'å', 'ç', 'ê', 'ë', 'è', 'ï', 'î', 'ì', 'Ä', 'Å', | ||||
|     /* 9X */ 'É', 'æ', 'Æ', 'ô', 'ö', 'ò', 'û', 'ù', 'ÿ', 'Ö', 'Ü', '¢', '£', '¥', '₧', 'ƒ', | ||||
|     /* AX */ 'á', 'í', 'ó', 'ú', 'ñ', 'Ñ', 'ª', 'º', '¿', '⌐', '¬', '½', '¼', '¡', '«', '»', | ||||
|     /* BX */ '░', '▒', '▓', '│', '┤', '╡', '╢', '╖', '╕', '╣', '║', '╗', '╝', '╜', '╛', '┐', | ||||
|     /* CX */ '└', '┴', '┬', '├', '─', '┼', '╞', '╟', '╚', '╔', '╩', '╦', '╠', '═', '╬', '╧', | ||||
|     /* DX */ '╨', '╤', '╥', '╙', '╘', '╒', '╓', '╫', '╪', '┘', '┌', '█', '▄', '▌', '▐', '▀', | ||||
|     /* EX */ 'α', 'ß', 'Γ', 'π', 'Σ', 'σ', 'µ', 'τ', 'Φ', 'Θ', 'Ω', 'δ', '∞', 'φ', 'ε', '∩', | ||||
|     /* FX */ '≡', '±', '≥', '≤', '⌠', '⌡', '÷', '≈', '°', '∙', '·', '√', 'ⁿ', '²', '■', ' ', | ||||
| ]; | ||||
| static UTF8_TO_CP437: once_cell::sync::Lazy<HashMap<char, u8>> = | ||||
|     once_cell::sync::Lazy::new(|| { | ||||
|         let pairs = CP437_TO_UTF8 | ||||
|             .iter() | ||||
|             .enumerate() | ||||
|             .map(move |(index, char)| (*char, index as u8)); | ||||
|         HashMap::from_iter(pairs) | ||||
|     }); | ||||
| 
 | ||||
| impl Cp437Converter { | ||||
|     const MISSING_CHAR_CP437: u8 = 0x3F; // '?'
 | ||||
| 
 | ||||
|     /// Convert the provided bytes to UTF-8.
 | ||||
|     pub fn cp437_to_str(cp437: &[u8]) -> String { | ||||
|         cp437.iter().map(move |char| cp437_to_char(*char)).collect() | ||||
|         cp437 | ||||
|             .iter() | ||||
|             .map(move |char| Self::cp437_to_char(*char)) | ||||
|             .collect() | ||||
|     } | ||||
| 
 | ||||
|     /// Convert a single CP-437 character to UTF-8.
 | ||||
|  | @ -63,17 +60,18 @@ mod feature_cp437 { | |||
|     ///
 | ||||
|     /// Characters that are not available are mapped to '?'.
 | ||||
|     pub fn str_to_cp437(utf8: &str) -> Vec<u8> { | ||||
|         utf8.chars().map(char_to_cp437).collect() | ||||
|         utf8.chars().map(Self::char_to_cp437).collect() | ||||
|     } | ||||
| 
 | ||||
|     /// Convert a single UTF-8 character to CP-437.
 | ||||
|     pub fn char_to_cp437(utf8: char) -> u8 { | ||||
|         *UTF8_TO_CP437.get(&utf8).unwrap_or(&MISSING_CHAR_CP437) | ||||
|         *UTF8_TO_CP437 | ||||
|             .get(&utf8) | ||||
|             .unwrap_or(&Self::MISSING_CHAR_CP437) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| #[cfg(feature = "cp437")] | ||||
| mod tests_feature_cp437 { | ||||
|     use super::*; | ||||
| 
 | ||||
|  | @ -102,13 +100,16 @@ mod tests_feature_cp437 { | |||
|         │dx ≡ Σ √x²ⁿ·δx | ||||
|         ⌡"#;
 | ||||
| 
 | ||||
|         let cp437 = str_to_cp437(utf8); | ||||
|         let actual = cp437_to_str(&*cp437); | ||||
|         let cp437 = Cp437Converter::str_to_cp437(utf8); | ||||
|         let actual = Cp437Converter::cp437_to_str(&*cp437); | ||||
|         assert_eq!(utf8, actual) | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn convert_invalid() { | ||||
|         assert_eq!(cp437_to_char(char_to_cp437('😜')), '?'); | ||||
|         assert_eq!( | ||||
|             Cp437Converter::cp437_to_char(Cp437Converter::char_to_cp437('😜')), | ||||
|             '?' | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -83,20 +83,17 @@ pub use feature_cp437::*; | |||
| #[cfg(feature = "cp437")] | ||||
| mod feature_cp437 { | ||||
|     use super::*; | ||||
|     use crate::{ | ||||
|         cp437::{char_to_cp437, cp437_to_char}, | ||||
|         CharGrid, | ||||
|     }; | ||||
|     use crate::{CharGrid, Cp437Converter}; | ||||
| 
 | ||||
|     impl From<&Cp437Grid> for CharGrid { | ||||
|         fn from(value: &Cp437Grid) -> Self { | ||||
|             value.map(cp437_to_char) | ||||
|             value.map(Cp437Converter::cp437_to_char) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     impl From<&CharGrid> for Cp437Grid { | ||||
|         fn from(value: &CharGrid) -> Self { | ||||
|             value.map(char_to_cp437) | ||||
|             value.map(Cp437Converter::char_to_cp437) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ pub use crate::command::{Command, Offset}; | |||
| pub use crate::compression_code::CompressionCode; | ||||
| pub use crate::connection::Connection; | ||||
| pub use crate::constants::*; | ||||
| pub use crate::cp437::Cp437Converter; | ||||
| pub use crate::cp437_grid::Cp437Grid; | ||||
| pub use crate::data_ref::DataRef; | ||||
| pub use crate::grid::Grid; | ||||
|  | @ -66,7 +67,6 @@ mod compression; | |||
| mod compression_code; | ||||
| mod connection; | ||||
| mod constants; | ||||
| pub mod cp437; | ||||
| mod cp437_grid; | ||||
| mod data_ref; | ||||
| mod grid; | ||||
|  | @ -74,6 +74,9 @@ mod origin; | |||
| mod packet; | ||||
| mod value_grid; | ||||
| 
 | ||||
| #[cfg(feature = "cp437")] | ||||
| mod cp437; | ||||
| 
 | ||||
| // include README.md in doctest
 | ||||
| #[doc = include_str!("../README.md")] | ||||
| #[cfg(doctest)] | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter