Change alphabet to use bytes rather than chars

This commit is contained in:
Nathan Fisher 2025-01-10 18:46:06 -05:00
parent 4b165a6736
commit 2e2ac8154e
3 changed files with 19 additions and 26 deletions

View file

@ -1,5 +1,5 @@
use std::io::{self, Read, Write};
use super::*;
use std::io::{self, Read, Write};
#[derive(Debug)]
pub enum DecoderError {
@ -21,7 +21,11 @@ pub struct Decoder<R: Read, W: Write> {
impl<R: Read, W: Write> Decoder<R, W> {
pub fn new(reader: R, writer: W, alphabet: Option<B32Alphabet>) -> Self {
Self { reader, writer, alphabet: alphabet.unwrap_or_default() }
Self {
reader,
writer,
alphabet: alphabet.unwrap_or_default(),
}
}
pub fn decode(&mut self) -> Result<(), DecoderError> {
@ -34,10 +38,9 @@ impl<R: Read, W: Write> Decoder<R, W> {
}
}
for c in &buf {
let c = char::from(*c);
num <<= 5;
if !matches!(self.alphabet.pad(), Some(ch) if ch == c) {
let idx = self.alphabet.idx(c).ok_or(DecoderError::IllegalChar)?;
if !matches!(self.alphabet.pad(), Some(ch) if ch == *c) {
let idx = self.alphabet.idx(*c).ok_or(DecoderError::IllegalChar)?;
num |= idx as u64;
}
}
@ -75,7 +78,7 @@ mod tests {
#[test]
fn get_idx() {
let idx = B32_RFC4648_ALPHABET.idx('S').unwrap();
let idx = B32_RFC4648_ALPHABET.idx(b'S').unwrap();
assert_eq!(idx, 18);
}
@ -88,4 +91,3 @@ mod tests {
assert_eq!(HELLO, String::from_utf8(decoder.bytes()).unwrap());
}
}

View file

@ -123,20 +123,10 @@ mod test {
let mut encoder = Encoder::new(reader, writer, None, None);
encoder.encode().unwrap();
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSA====");
encoder = Encoder::new(
"Hello, World!".as_bytes(),
String::new(),
None,
None
);
encoder = Encoder::new("Hello, World!".as_bytes(), String::new(), None, None);
encoder.encode().unwrap();
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCC===");
encoder = Encoder::new(
"Hello, World!\n".as_bytes(),
String::new(),
None,
None,
);
encoder = Encoder::new("Hello, World!\n".as_bytes(), String::new(), None, None);
encoder.encode().unwrap();
assert_eq!(encoder.output(), "JBSWY3DPFQQFO33SNRSCCCQ=");
}

View file

@ -5,16 +5,17 @@ pub mod error;
#[derive(Clone, Copy)]
pub struct B32Alphabet {
items: [char; 32],
pad: Option<char>,
items: [u8; 32],
pad: Option<u8>,
}
pub static B32_RFC4648_ALPHABET: B32Alphabet = B32Alphabet {
items: [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7',
b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O',
b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'2', b'3', b'4', b'5',
b'6', b'7',
],
pad: Some('='),
pad: Some(b'='),
};
impl Default for B32Alphabet {
@ -24,7 +25,7 @@ impl Default for B32Alphabet {
}
impl B32Alphabet {
pub(crate) fn idx(&self, c: char) -> Option<usize> {
pub(crate) fn idx(&self, c: u8) -> Option<usize> {
for (idx, x) in self.items.iter().enumerate() {
if *x == c {
return Some(idx);
@ -33,7 +34,7 @@ impl B32Alphabet {
None
}
pub(crate) fn pad(&self) -> Option<char> {
pub(crate) fn pad(&self) -> Option<u8> {
self.pad
}
}