Use io::Write instead of fmt::Write for Encoder

This commit is contained in:
Nathan Fisher 2025-01-12 18:44:39 -05:00
parent bb47d46586
commit 23babcc511
2 changed files with 29 additions and 50 deletions

View file

@ -7,11 +7,16 @@ pub struct Decoder<R: Read, W: Write> {
reader: R,
writer: W,
alphabet: B32Alphabet,
ignore_whitespace: bool
ignore_whitespace: bool,
}
impl<R: Read, W: Write> Decoder<R, W> {
pub fn new(reader: R, writer: W, alphabet: Option<B32Alphabet>, ignore_whitespace: bool) -> Self {
pub fn new(
reader: R,
writer: W,
alphabet: Option<B32Alphabet>,
ignore_whitespace: bool,
) -> Self {
Self {
reader,
writer,
@ -20,7 +25,6 @@ impl<R: Read, W: Write> Decoder<R, W> {
}
}
/// Decodes the bytes provided by `self.reader` and writes the resulting
/// bytes into `self.writer`.
/// # Important
@ -63,7 +67,10 @@ impl<R: Read, W: Write> Decoder<R, W> {
for c in &in_buf {
num <<= 5;
if !matches!(self.alphabet.pad(), Some(ch) if ch == *c) {
let idx = self.alphabet.idx(*c).ok_or(Error::IllegalChar((*c).into()))?;
let idx = self
.alphabet
.idx(*c)
.ok_or(Error::IllegalChar((*c).into()))?;
num |= idx as u64;
}
}

View file

@ -1,29 +1,8 @@
use {
super::*,
std::{
fmt::{self, Write},
io::{self, Read},
},
crate::{error::Error, B32Alphabet},
std::io::{self, ErrorKind, Read, Write},
};
#[derive(Debug)]
pub enum EncoderError {
IO(io::Error),
FMT(fmt::Error),
}
impl From<io::Error> for EncoderError {
fn from(value: io::Error) -> Self {
Self::IO(value)
}
}
impl From<fmt::Error> for EncoderError {
fn from(value: fmt::Error) -> Self {
Self::FMT(value)
}
}
pub struct Encoder<R: Read, W: Write> {
reader: R,
writer: W,
@ -41,7 +20,7 @@ impl<R: Read, W: Write> Encoder<R, W> {
}
}
pub fn encode(&mut self) -> Result<(), EncoderError> {
pub fn encode(&mut self) -> Result<(), Error> {
let mut total: usize = 0;
loop {
let mut buf = [0; 5];
@ -50,7 +29,7 @@ impl<R: Read, W: Write> Encoder<R, W> {
loop {
n_bytes = match self.reader.read(&mut buf) {
Ok(n) => n,
Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
Err(e) => return Err(e.into()),
};
break;
@ -64,10 +43,10 @@ impl<R: Read, W: Write> Encoder<R, W> {
num |= *c as u64;
}
}
let mut buf = ['\0'; 8];
let mut buf = [b'\0'; 8];
for i in (0..8).rev() {
let b = (num & 0x1f) as u8;
buf[i] = char::try_from(self.alphabet.items[b as usize]).unwrap();
buf[i] = self.alphabet.items[b as usize];
num >>= 5;
}
let mut outlen = n_bytes * 8 / 5;
@ -76,19 +55,19 @@ impl<R: Read, W: Write> Encoder<R, W> {
outlen += 1;
}
buf[0..outlen].iter().try_for_each(|c| {
self.writer.write_char(*c)?;
self.writer.write_all(&[*c])?;
total += 1;
if let Some(wrap) = self.wrap {
if total % wrap == 0 {
self.writer.write_char('\n')?;
writeln!(self.writer)?;
}
}
Ok::<(), fmt::Error>(())
Ok::<(), io::Error>(())
})?;
if let Some(pad) = self.alphabet.pad {
if rem != 0 {
for _c in 0..8 - outlen {
self.writer.write_char(char::try_from(pad).unwrap())?;
self.writer.write_all(&[pad])?;
}
}
}
@ -100,12 +79,6 @@ impl<R: Read, W: Write> Encoder<R, W> {
}
}
impl<R: Read> Encoder<R, String> {
pub fn output(self) -> String {
self.writer
}
}
#[cfg(test)]
mod test {
use {
@ -119,16 +92,15 @@ mod test {
#[test]
fn hello() {
let reader = "Hello, World".as_bytes();
let writer = String::new();
let mut encoder = Encoder::new(reader, writer, None, None);
let mut encoder = Encoder::new(reader, vec![], None, None);
encoder.encode().unwrap();
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSA====");
encoder = Encoder::new("Hello, World!".as_bytes(), String::new(), None, None);
assert_eq!(encoder.writer, b"JBSWY3DPFQQFO33SNRSA====");
encoder = Encoder::new("Hello, World!".as_bytes(), vec![], None, None);
encoder.encode().unwrap();
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCC===");
encoder = Encoder::new("Hello, World!\n".as_bytes(), String::new(), None, None);
assert_eq!(encoder.writer, b"JBSWY3DPFQQFO33SNRSCC===");
encoder = Encoder::new("Hello, World!\n".as_bytes(), vec![], None, None);
encoder.encode().unwrap();
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCCCQ=");
assert_eq!(encoder.writer, b"JBSWY3DPFQQFO33SNRSCCCQ=");
}
#[test]
@ -136,8 +108,8 @@ mod test {
let infile = File::open("src/testdata/lorem.txt").unwrap();
let reader = BufReader::new(infile);
let outfile = fs::read_to_string("src/testdata/lorem_b32.txt").unwrap();
let mut encoder = Encoder::new(reader, String::new(), None, Some(76));
let mut encoder = Encoder::new(reader, vec![], None, Some(76));
encoder.encode().unwrap();
assert_eq!(encoder.output(), outfile);
assert_eq!(encoder.writer, outfile.as_bytes());
}
}