codecs/
utf16.rs

1use std::error::Error as StdError;
2use std::string::FromUtf16Error;
3
4use core2::io::{self, Read, Seek, Write};
5
6/// UTF-16 Little Endian **without** a byte-order marker (BOM).
7pub struct Utf16Le;
8
9/// UTF-16 Big Endian **without** a byte-order marker (BOM).
10pub struct Utf16Be;
11
12/// UTF-16 Little Endian **without** a byte-order marker (BOM).
13pub struct Utf16LeBom;
14
15/// UTF-16 Big Endian **with** a byte-order marker (BOM).
16pub struct Utf16BeBom;
17
18pub const BOM_LE_BYTES: [u8; 2] = [0xFF, 0xFE];
19pub const BOM_BE_BYTES: [u8; 2] = [0xFE, 0xFF];
20pub const BOM_LE: u16 = 0xFFFE;
21pub const BOM_BE: u16 = 0xFEFF;
22
23pub trait Utf16Ext {
24    type Error: StdError;
25
26    fn encode_utf16_le(&self) -> Vec<u8>;
27    fn encode_utf16_le_bom(&self) -> Vec<u8>;
28    fn encode_utf16_be(&self) -> Vec<u8>;
29    fn encode_utf16_be_bom(&self) -> Vec<u8>;
30
31    fn decode_utf16_le(&self, input: &[u8]) -> Result<String, Self::Error>;
32    fn decode_utf16_le_bom(&self, input: &[u8]) -> Result<String, Self::Error>;
33    fn decode_utf16_be(&self, input: &[u8]) -> Result<String, Self::Error>;
34    fn decode_utf16_be_bom(&self, input: &[u8]) -> Result<String, Self::Error>;
35}
36
37pub struct Utf16Writer<W: io::Write> {
38    // mode: Utf16,
39    writer: W,
40}
41
42pub struct Utf16Reader<R: io::Read> {
43    // mode: Utf16,
44    reader: R,
45}
46
47impl<R: io::Read> Read for Utf16Reader<R> {
48    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
49        todo!()
50    }
51}
52
53impl<W: io::Write> Write for Utf16Writer<W> {
54    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
55        todo!()
56    }
57
58    fn flush(&mut self) -> io::Result<()> {
59        self.writer.flush()
60    }
61}
62
63impl<S: io::Seek + io::Read> Seek for Utf16Reader<S> {
64    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
65        todo!()
66    }
67}
68
69impl<S: io::Seek + io::Write> Seek for Utf16Writer<S> {
70    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
71        todo!()
72    }
73}
74
75#[derive(Debug, thiserror::Error)]
76pub enum DecodeUtf16Error {
77    #[error("Could not decode UTF-16 input")]
78    Decode(#[from] FromUtf16Error),
79
80    #[error("Input has invalid length to be a valid UTF-16 input.")]
81    BadLength,
82}
83
84impl Utf16Ext for &str {
85    type Error = DecodeUtf16Error;
86
87    fn encode_utf16_le(&self) -> Vec<u8> {
88        todo!()
89    }
90
91    fn encode_utf16_le_bom(&self) -> Vec<u8> {
92        // Take a rough shot at getting a sensible capacity
93        let mut vec = Vec::with_capacity(self.len() * 2);
94
95        for b in BOM_LE_BYTES {
96            vec.push(b);
97        }
98
99        self.encode_utf16().for_each(|w| {
100            for b in w.to_le_bytes() {
101                vec.push(b);
102            }
103        });
104
105        vec
106    }
107
108    fn encode_utf16_be(&self) -> Vec<u8> {
109        todo!()
110    }
111
112    fn encode_utf16_be_bom(&self) -> Vec<u8> {
113        todo!()
114    }
115
116    fn decode_utf16_le(&self, input: &[u8]) -> Result<String, Self::Error> {
117        if input.len() % 2 != 0 {
118            return Err(DecodeUtf16Error::BadLength);
119        }
120
121        let bytes = input
122            .chunks(2)
123            .map(|x| u16::from_le_bytes([x[0], x[1]]))
124            .collect::<Vec<u16>>();
125
126        Ok(String::from_utf16(&bytes)?)
127    }
128
129    fn decode_utf16_le_bom(&self, input: &[u8]) -> Result<String, Self::Error> {
130        todo!()
131    }
132
133    fn decode_utf16_be(&self, input: &[u8]) -> Result<String, Self::Error> {
134        todo!()
135    }
136
137    fn decode_utf16_be_bom(&self, input: &[u8]) -> Result<String, Self::Error> {
138        todo!()
139    }
140}
141
142impl Utf16Ext for String {
143    type Error = DecodeUtf16Error;
144
145    fn encode_utf16_le(&self) -> Vec<u8> {
146        todo!()
147    }
148
149    fn encode_utf16_le_bom(&self) -> Vec<u8> {
150        <&str as Utf16Ext>::encode_utf16_le_bom(&&**self)
151    }
152
153    fn encode_utf16_be(&self) -> Vec<u8> {
154        todo!()
155    }
156
157    fn encode_utf16_be_bom(&self) -> Vec<u8> {
158        todo!()
159    }
160
161    fn decode_utf16_le(&self, input: &[u8]) -> Result<String, Self::Error> {
162        <&str as Utf16Ext>::decode_utf16_le(&&**self, input)
163    }
164
165    fn decode_utf16_le_bom(&self, input: &[u8]) -> Result<String, Self::Error> {
166        todo!()
167    }
168
169    fn decode_utf16_be(&self, input: &[u8]) -> Result<String, Self::Error> {
170        todo!()
171    }
172
173    fn decode_utf16_be_bom(&self, input: &[u8]) -> Result<String, Self::Error> {
174        todo!()
175    }
176}