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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use std::hash::{Hasher, Hash};
use std::borrow::Cow;
use std::{cmp, fmt};
#[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<u8>,
remaps: Cow<'static, [(u8, char, char)]>,
}
impl Cp437Dialect {
#[inline]
pub fn overlap_unicode(&self, unicode: char) -> bool {
(self.overlap_unicode)(unicode) && !self.remaps.iter().rev().find(|&&(_, _, to)| to == unicode).is_some()
}
#[inline]
pub fn overlap_cp437(&self, cp437: u8) -> bool {
(self.overlap_cp437)(cp437) && !self.remaps.iter().rev().find(|&&(whom, _, _)| whom == cp437).is_some()
}
#[inline(always)]
pub fn decode(&self, cp437: u8) -> char {
self.cp437_to_unicode[cp437 as usize]
}
#[inline]
pub fn encode(&self, unicode: char) -> Option<u8> {
self.remaps.iter().rev().find(|&&(_, _, to)| to == unicode).map(|&(whom, _, _)| whom).or_else(|| (self.encode)(unicode))
}
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
}
}
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<H: Hasher>(&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[..] &&
self.overlap_unicode == other.overlap_unicode &&
self.overlap_cp437 == other.overlap_cp437 &&
self.encode == other.encode &&
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<cmp::Ordering> {
Some(self.cmp(other))
}
}
include!(concat!(env!("OUT_DIR"), "/dialects.rs"));