Coverage Report

Created: 2025-06-04 06:23

/src/zip/src/cp437.rs
Line
Count
Source (jump to first uncovered line)
1
//! Convert a string in IBM codepage 437 to UTF-8
2
3
/// Trait to convert IBM codepage 437 to the target type
4
pub trait FromCp437 {
5
    /// Target type
6
    type Target;
7
8
    /// Function that does the conversion from cp437.
9
    /// Generally allocations will be avoided if all data falls into the ASCII range.
10
    #[allow(clippy::wrong_self_convention)]
11
    fn from_cp437(self) -> Self::Target;
12
}
13
14
impl<'a> FromCp437 for &'a [u8] {
15
    type Target = ::std::borrow::Cow<'a, str>;
16
17
0
    fn from_cp437(self) -> Self::Target {
18
0
        if self.iter().all(|c| *c < 0x80) {
19
0
            ::std::str::from_utf8(self).unwrap().into()
20
        } else {
21
0
            self.iter().map(|c| to_char(*c)).collect::<String>().into()
22
        }
23
0
    }
24
}
25
26
impl FromCp437 for Vec<u8> {
27
    type Target = String;
28
29
318k
    fn from_cp437(self) -> Self::Target {
30
16.3M
        if self.iter().all(|c| *c < 0x80) {
31
242k
            String::from_utf8(self).unwrap()
32
        } else {
33
75.4k
            self.into_iter().map(to_char).collect()
34
        }
35
318k
    }
36
}
37
38
9.04M
fn to_char(input: u8) -> char {
39
9.04M
    let output = match input {
40
9.04M
        0x00..=0x7f => input as u32,
41
30.5k
        0x80 => 0x00c7,
42
33.9k
        0x81 => 0x00fc,
43
4.36k
        0x82 => 0x00e9,
44
836
        0x83 => 0x00e2,
45
3.57k
        0x84 => 0x00e4,
46
11.6k
        0x85 => 0x00e0,
47
16.8k
        0x86 => 0x00e5,
48
6.83k
        0x87 => 0x00e7,
49
2.23k
        0x88 => 0x00ea,
50
3.84k
        0x89 => 0x00eb,
51
20.0k
        0x8a => 0x00e8,
52
1.16k
        0x8b => 0x00ef,
53
5.11k
        0x8c => 0x00ee,
54
8.70k
        0x8d => 0x00ec,
55
1.60k
        0x8e => 0x00c4,
56
2.01k
        0x8f => 0x00c5,
57
1.54k
        0x90 => 0x00c9,
58
1.32k
        0x91 => 0x00e6,
59
737
        0x92 => 0x00c6,
60
1.71k
        0x93 => 0x00f4,
61
1.62k
        0x94 => 0x00f6,
62
4.06k
        0x95 => 0x00f2,
63
10.2k
        0x96 => 0x00fb,
64
2.33k
        0x97 => 0x00f9,
65
1.80k
        0x98 => 0x00ff,
66
7.87k
        0x99 => 0x00d6,
67
17.6k
        0x9a => 0x00dc,
68
2.36k
        0x9b => 0x00a2,
69
5.60k
        0x9c => 0x00a3,
70
1.73k
        0x9d => 0x00a5,
71
2.17k
        0x9e => 0x20a7,
72
1.50k
        0x9f => 0x0192,
73
15.7k
        0xa0 => 0x00e1,
74
848
        0xa1 => 0x00ed,
75
22.4k
        0xa2 => 0x00f3,
76
2.02k
        0xa3 => 0x00fa,
77
9.07k
        0xa4 => 0x00f1,
78
1.94k
        0xa5 => 0x00d1,
79
6.07k
        0xa6 => 0x00aa,
80
2.99k
        0xa7 => 0x00ba,
81
2.03k
        0xa8 => 0x00bf,
82
3.82k
        0xa9 => 0x2310,
83
3.71k
        0xaa => 0x00ac,
84
3.49k
        0xab => 0x00bd,
85
18.2k
        0xac => 0x00bc,
86
3.00k
        0xad => 0x00a1,
87
12.2k
        0xae => 0x00ab,
88
13.3k
        0xaf => 0x00bb,
89
6.15k
        0xb0 => 0x2591,
90
4.76k
        0xb1 => 0x2592,
91
9.94k
        0xb2 => 0x2593,
92
3.17k
        0xb3 => 0x2502,
93
18.1k
        0xb4 => 0x2524,
94
14.1k
        0xb5 => 0x2561,
95
4.53k
        0xb6 => 0x2562,
96
4.13k
        0xb7 => 0x2556,
97
2.35k
        0xb8 => 0x2555,
98
14.9k
        0xb9 => 0x2563,
99
1.91k
        0xba => 0x2551,
100
41.7k
        0xbb => 0x2557,
101
98.7k
        0xbc => 0x255d,
102
16.0k
        0xbd => 0x255c,
103
2.41k
        0xbe => 0x255b,
104
20.7k
        0xbf => 0x2510,
105
7.45k
        0xc0 => 0x2514,
106
5.69k
        0xc1 => 0x2534,
107
9.19k
        0xc2 => 0x252c,
108
53.5k
        0xc3 => 0x251c,
109
16.9k
        0xc4 => 0x2500,
110
2.86k
        0xc5 => 0x253c,
111
718k
        0xc6 => 0x255e,
112
1.98k
        0xc7 => 0x255f,
113
1.81k
        0xc8 => 0x255a,
114
4.67k
        0xc9 => 0x2554,
115
1.46k
        0xca => 0x2569,
116
16.1k
        0xcb => 0x2566,
117
2.34k
        0xcc => 0x2560,
118
21.1k
        0xcd => 0x2550,
119
2.69k
        0xce => 0x256c,
120
4.50k
        0xcf => 0x2567,
121
3.93k
        0xd0 => 0x2568,
122
813k
        0xd1 => 0x2564,
123
2.46k
        0xd2 => 0x2565,
124
10.2k
        0xd3 => 0x2559,
125
12.1k
        0xd4 => 0x2558,
126
3.38k
        0xd5 => 0x2552,
127
3.01k
        0xd6 => 0x2553,
128
2.15k
        0xd7 => 0x256b,
129
1.85k
        0xd8 => 0x256a,
130
4.80k
        0xd9 => 0x2518,
131
3.52k
        0xda => 0x250c,
132
5.45k
        0xdb => 0x2588,
133
3.59k
        0xdc => 0x2584,
134
1.94k
        0xdd => 0x258c,
135
1.54k
        0xde => 0x2590,
136
3.60k
        0xdf => 0x2580,
137
7.65k
        0xe0 => 0x03b1,
138
1.69k
        0xe1 => 0x00df,
139
6.42k
        0xe2 => 0x0393,
140
1.52k
        0xe3 => 0x03c0,
141
2.06k
        0xe4 => 0x03a3,
142
2.07k
        0xe5 => 0x03c3,
143
9.66k
        0xe6 => 0x00b5,
144
1.82k
        0xe7 => 0x03c4,
145
8.63k
        0xe8 => 0x03a6,
146
2.42k
        0xe9 => 0x0398,
147
11.4k
        0xea => 0x03a9,
148
1.19k
        0xeb => 0x03b4,
149
1.10k
        0xec => 0x221e,
150
2.50k
        0xed => 0x03c6,
151
2.09k
        0xee => 0x03b5,
152
20.2k
        0xef => 0x2229,
153
1.79k
        0xf0 => 0x2261,
154
9.26k
        0xf1 => 0x00b1,
155
3.65k
        0xf2 => 0x2265,
156
6.01k
        0xf3 => 0x2264,
157
11.9k
        0xf4 => 0x2320,
158
14.3k
        0xf5 => 0x2321,
159
7.51k
        0xf6 => 0x00f7,
160
16.1k
        0xf7 => 0x2248,
161
10.4k
        0xf8 => 0x00b0,
162
15.6k
        0xf9 => 0x2219,
163
11.5k
        0xfa => 0x00b7,
164
17.2k
        0xfb => 0x221a,
165
12.7k
        0xfc => 0x207f,
166
17.4k
        0xfd => 0x00b2,
167
30.2k
        0xfe => 0x25a0,
168
1.01M
        0xff => 0x00a0,
169
    };
170
9.04M
    ::std::char::from_u32(output).unwrap()
171
9.04M
}
172
173
#[cfg(test)]
174
mod test {
175
    #[test]
176
    fn to_char_valid() {
177
        for i in 0x00_u32..0x100 {
178
            super::to_char(i as u8);
179
        }
180
    }
181
182
    #[test]
183
    fn ascii() {
184
        for i in 0x00..0x80 {
185
            assert_eq!(super::to_char(i), i as char);
186
        }
187
    }
188
189
    #[test]
190
    fn example_slice() {
191
        use super::FromCp437;
192
        let data = b"Cura\x87ao";
193
        assert!(::std::str::from_utf8(data).is_err());
194
        assert_eq!(data.from_cp437(), "Curaçao");
195
    }
196
197
    #[test]
198
    fn example_vec() {
199
        use super::FromCp437;
200
        let data = vec![0xCC, 0xCD, 0xCD, 0xB9];
201
        assert!(String::from_utf8(data.clone()).is_err());
202
        assert_eq!(&data.from_cp437(), "╠══╣");
203
    }
204
}