binocular/preview/
encoding.rs1pub fn try_decode_utf16(bytes: &[u8]) -> Option<String> {
2 if bytes.len() < 2 {
3 return None;
4 }
5
6 if bytes[0] == 0xFF && bytes[1] == 0xFE {
7 return Some(decode_utf16(bytes, Endian::Little));
8 }
9
10 if bytes[0] == 0xFE && bytes[1] == 0xFF {
11 return Some(decode_utf16(bytes, Endian::Big));
12 }
13
14 None
15}
16
17enum Endian {
18 Little,
19 Big,
20}
21
22fn decode_utf16(bytes: &[u8], endian: Endian) -> String {
23 let u16_iter = bytes[2..].chunks_exact(2).map(|chunk| match endian {
24 Endian::Little => u16::from_le_bytes([chunk[0], chunk[1]]),
25 Endian::Big => u16::from_be_bytes([chunk[0], chunk[1]]),
26 });
27
28 char::decode_utf16(u16_iter)
29 .map(|r| r.unwrap_or(char::REPLACEMENT_CHARACTER))
30 .collect()
31}