ferroui_base/media/fonts/tables/
encoding_id_extensions.rs1use super::encoding_ids::EncodingIDs;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10pub enum Encoding {
11 BigEndianUnicode,
13 UTF8,
15}
16
17impl Encoding {
18 pub fn get_string(&self, bytes: &[u8]) -> String {
20 match self {
21 Encoding::BigEndianUnicode => {
22 let pairs = bytes.chunks_exact(2);
23 let has_trailing_byte = !pairs.remainder().is_empty();
24 let units = pairs.map(|pair| u16::from_be_bytes([pair[0], pair[1]]));
25
26 let mut text: String = char::decode_utf16(units)
27 .map(|unit| unit.unwrap_or(char::REPLACEMENT_CHARACTER))
28 .collect();
29
30 if has_trailing_byte {
32 text.push(char::REPLACEMENT_CHARACTER);
33 }
34
35 text
36 }
37 Encoding::UTF8 => String::from_utf8_lossy(bytes).into_owned(),
38 }
39 }
40}
41
42pub struct EncodingIDExtensions;
44
45impl EncodingIDExtensions {
46 pub fn as_encoding(id: EncodingIDs) -> Encoding {
48 if id == EncodingIDs::Unicode11 || id == EncodingIDs::Unicode2 {
49 Encoding::BigEndianUnicode
50 } else {
51 Encoding::UTF8
52 }
53 }
54}
55
56impl EncodingIDs {
57 #[inline]
59 pub fn as_encoding(self) -> Encoding {
60 EncodingIDExtensions::as_encoding(self)
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn selects_utf16_for_windows_unicode_encodings() {
70 assert_eq!(EncodingIDs::Unicode11.as_encoding(), Encoding::BigEndianUnicode);
71 assert_eq!(EncodingIDs::Unicode2.as_encoding(), Encoding::BigEndianUnicode);
72 assert_eq!(EncodingIDs::Unicode1.as_encoding(), Encoding::UTF8);
73 assert_eq!(EncodingIDs(77).as_encoding(), Encoding::UTF8);
74 }
75
76 #[test]
77 fn decodes_utf16_big_endian() {
78 let bytes = [0x00, 0x41, 0xD8, 0x3D, 0xDE, 0x00, 0xD8, 0x00, 0x42];
80
81 assert_eq!(Encoding::BigEndianUnicode.get_string(&bytes), "A\u{1F600}\u{FFFD}\u{FFFD}");
82 assert_eq!(Encoding::BigEndianUnicode.get_string(&[]), "");
83 }
84
85 #[test]
86 fn decodes_utf8_with_replacement() {
87 assert_eq!(Encoding::UTF8.get_string(b"Inter"), "Inter");
88 assert_eq!(Encoding::UTF8.get_string(&[b'a', 0xFF, b'b']), "a\u{FFFD}b");
89 }
90}