use crate::TranscoderBuilder;
use encoding_rs::Encoding;
use std::io::Write;
pub struct TranscoderWriter<W: Write> {
decoder: &'static Encoding,
encoder: &'static Encoding,
inner: W,
}
impl TranscoderBuilder {
pub fn build_writer<W: Write>(self, writer: W) -> TranscoderWriter<W> {
TranscoderWriter {
decoder: self.from_encoding,
encoder: self.to_encoding,
inner: writer,
}
}
}
impl<W> TranscoderWriter<W>
where
W: Write,
{
pub fn into_inner(self) -> W {
self.inner
}
}
impl<W> Write for TranscoderWriter<W>
where
W: Write,
{
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let org_len = buf.len();
let (buf, _, _) = self.decoder.decode(buf);
let (buf, _, _) = self.encoder.encode(&buf);
self.inner.write_all(&buf).and(Ok(org_len))
}
fn flush(&mut self) -> std::io::Result<()> {
self.inner.flush()
}
}
#[cfg(test)]
mod tests {
use std::io::Write;
use encoding_rs::WINDOWS_1252;
use crate::TranscoderBuilder;
#[derive(Default)]
pub struct MemWriter {
pub mem: Vec<u8>,
}
impl Write for MemWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.mem.append(&mut buf.to_vec());
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
#[test]
fn utf8_to_win1252() {
let expectation: [u8; 6] = [233, 224, 231, 234, 226, 238];
let input = "éàçêâî";
let mem_writer = MemWriter::default();
let mut writer = TranscoderBuilder::new()
.to_encoding(WINDOWS_1252)
.build_writer(mem_writer);
writer.write_all(input.as_bytes()).unwrap();
assert!(writer.into_inner().mem == expectation);
}
#[test]
fn win1252_to_utf8() {
let input: [u8; 6] = [233, 224, 231, 234, 226, 238];
let expectation = "éàçêâî";
let mem_writer = MemWriter::default();
let mut writer = TranscoderBuilder::new()
.from_encoding(WINDOWS_1252)
.build_writer(mem_writer);
writer.write_all(&input).unwrap();
assert!(String::from_utf8_lossy(&writer.into_inner().mem) == expectation);
}
}