//! Convert a string in IBM codepage 437 to UTF-8
/// Trait to convert IBM codepage 437 to the target type
pub trait FromCp437 {
/// Target type
type Target;
/// Function that does the conversion from cp437.
/// Generally allocations will be avoided if all data falls into the ASCII range.
#[ allow(clippy::wrong_self_convention)]
fn from_cp437(self ) -> Self ::Target;
}
impl <'a> FromCp437 for &' a [u8] {
type Target = ::std::borrow::Cow<'a, str>;
fn from_cp437(self ) -> Self ::Target {
if self .iter().all(|c| *c < 0 x80) {
::std::str::from_utf8(self ).unwrap().into()
} else {
self .iter().map(|c| to_char(*c)).collect::<String>().into()
}
}
}
impl FromCp437 for Box <[u8]> {
type Target = Box <str>;
fn from_cp437(self ) -> Self ::Target {
if self .iter().all(|c| *c < 0 x80) {
String::from_utf8(self .into()).unwrap()
} else {
self .iter().copied().map(to_char).collect()
}
.into_boxed_str()
}
}
fn to_char(input: u8) -> char {
let output = match input {
0 x00..=0 x7f => input as u32,
0 x80 => 0 x00c7,
0 x81 => 0 x00fc,
0 x82 => 0 x00e9,
0 x83 => 0 x00e2,
0 x84 => 0 x00e4,
0 x85 => 0 x00e0,
0 x86 => 0 x00e5,
0 x87 => 0 x00e7,
0 x88 => 0 x00ea,
0 x89 => 0 x00eb,
0 x8a => 0 x00e8,
0 x8b => 0 x00ef,
0 x8c => 0 x00ee,
0 x8d => 0 x00ec,
0 x8e => 0 x00c4,
0 x8f => 0 x00c5,
0 x90 => 0 x00c9,
0 x91 => 0 x00e6,
0 x92 => 0 x00c6,
0 x93 => 0 x00f4,
0 x94 => 0 x00f6,
0 x95 => 0 x00f2,
0 x96 => 0 x00fb,
0 x97 => 0 x00f9,
0 x98 => 0 x00ff,
0 x99 => 0 x00d6,
0 x9a => 0 x00dc,
0 x9b => 0 x00a2,
0 x9c => 0 x00a3,
0 x9d => 0 x00a5,
0 x9e => 0 x20a7,
0 x9f => 0 x0192,
0 xa0 => 0 x00e1,
0 xa1 => 0 x00ed,
0 xa2 => 0 x00f3,
0 xa3 => 0 x00fa,
0 xa4 => 0 x00f1,
0 xa5 => 0 x00d1,
0 xa6 => 0 x00aa,
0 xa7 => 0 x00ba,
0 xa8 => 0 x00bf,
0 xa9 => 0 x2310,
0 xaa => 0 x00ac,
0 xab => 0 x00bd,
0 xac => 0 x00bc,
0 xad => 0 x00a1,
0 xae => 0 x00ab,
0 xaf => 0 x00bb,
0 xb0 => 0 x2591,
0 xb1 => 0 x2592,
0 xb2 => 0 x2593,
0 xb3 => 0 x2502,
0 xb4 => 0 x2524,
0 xb5 => 0 x2561,
0 xb6 => 0 x2562,
0 xb7 => 0 x2556,
0 xb8 => 0 x2555,
0 xb9 => 0 x2563,
0 xba => 0 x2551,
0 xbb => 0 x2557,
0 xbc => 0 x255d,
0 xbd => 0 x255c,
0 xbe => 0 x255b,
0 xbf => 0 x2510,
0 xc0 => 0 x2514,
0 xc1 => 0 x2534,
0 xc2 => 0 x252c,
0 xc3 => 0 x251c,
0 xc4 => 0 x2500,
0 xc5 => 0 x253c,
0 xc6 => 0 x255e,
0 xc7 => 0 x255f,
0 xc8 => 0 x255a,
0 xc9 => 0 x2554,
0 xca => 0 x2569,
0 xcb => 0 x2566,
0 xcc => 0 x2560,
0 xcd => 0 x2550,
0 xce => 0 x256c,
0 xcf => 0 x2567,
0 xd0 => 0 x2568,
0 xd1 => 0 x2564,
0 xd2 => 0 x2565,
0 xd3 => 0 x2559,
0 xd4 => 0 x2558,
0 xd5 => 0 x2552,
0 xd6 => 0 x2553,
0 xd7 => 0 x256b,
0 xd8 => 0 x256a,
0 xd9 => 0 x2518,
0 xda => 0 x250c,
0 xdb => 0 x2588,
0 xdc => 0 x2584,
0 xdd => 0 x258c,
0 xde => 0 x2590,
0 xdf => 0 x2580,
0 xe0 => 0 x03b1,
0 xe1 => 0 x00df,
0 xe2 => 0 x0393,
0 xe3 => 0 x03c0,
0 xe4 => 0 x03a3,
0 xe5 => 0 x03c3,
0 xe6 => 0 x00b5,
0 xe7 => 0 x03c4,
0 xe8 => 0 x03a6,
0 xe9 => 0 x0398,
0 xea => 0 x03a9,
0 xeb => 0 x03b4,
0 xec => 0 x221e,
0 xed => 0 x03c6,
0 xee => 0 x03b5,
0 xef => 0 x2229,
0 xf0 => 0 x2261,
0 xf1 => 0 x00b1,
0 xf2 => 0 x2265,
0 xf3 => 0 x2264,
0 xf4 => 0 x2320,
0 xf5 => 0 x2321,
0 xf6 => 0 x00f7,
0 xf7 => 0 x2248,
0 xf8 => 0 x00b0,
0 xf9 => 0 x2219,
0 xfa => 0 x00b7,
0 xfb => 0 x221a,
0 xfc => 0 x207f,
0 xfd => 0 x00b2,
0 xfe => 0 x25a0,
0 xff => 0 x00a0,
};
::std::char::from_u32(output).unwrap()
}
#[ cfg(test)]
mod test {
#[ test]
fn to_char_valid() {
for i in 0 x00_u32..0 x100 {
super ::to_char(i as u8);
}
}
#[ test]
fn ascii() {
for i in 0 x00..0 x80 {
assert_eq!(super ::to_char(i), i as char);
}
}
#[ test]
#[ allow(unknown_lints)] // invalid_from_utf8 was added in rust 1.72
#[ allow(invalid_from_utf8)]
fn example_slice() {
use super ::FromCp437;
let data = b"Cura\x87ao" ;
assert!(::std::str::from_utf8(data).is_err());
assert_eq!(data.from_cp437(), "Curaçao" );
}
#[ test]
fn example_vec() {
use super ::FromCp437;
let data = vec![0 xCC, 0 xCD, 0 xCD, 0 xB9];
assert!(String::from_utf8(data.clone()).is_err());
assert_eq!(&*data.from_cp437(), "╠══╣" );
}
}
Messung V0.5 in Prozent C=98 H=100 G=98
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-17)
¤
*© Formatika GbR, Deutschland