Code cleanup and refactor to match interface of b64 and b32 better

This commit is contained in:
Nathan Fisher 2025-01-16 19:03:30 -05:00
parent 66d5702da0
commit 68138ab850
4 changed files with 73 additions and 104 deletions

View file

@ -1,57 +1,8 @@
use std::{ use {
fmt, crate::Error,
io::{self, ErrorKind, Read, Write}, std::io::{ErrorKind, Read, Write},
num::TryFromIntError,
}; };
#[derive(Debug)]
/// Errors which might possibly occur while decoding base64 encoded data
pub enum Error {
Io(io::Error),
IllegalChar(char),
IntError(TryFromIntError),
MissingChar,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(e) => write!(f, "{e}"),
Self::IllegalChar(c) => write!(f, "Illegal Character ({c})"),
Self::IntError(e) => write!(f, "Int Error: {e}"),
Self::MissingChar => write!(f, "Missing character"),
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
impl From<char> for Error {
fn from(value: char) -> Self {
Self::IllegalChar(value)
}
}
impl From<TryFromIntError> for Error {
fn from(value: TryFromIntError) -> Self {
Self::IntError(value)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Io(e) => Some(e),
Self::IntError(e) => Some(e),
_ => None,
}
}
}
pub struct Decoder<R: Read, W: Write> { pub struct Decoder<R: Read, W: Write> {
reader: R, reader: R,
writer: W, writer: W,

View file

@ -1,47 +1,8 @@
use { use {
super::B16_ALPHABET, crate::{Error, B16_ALPHABET},
std::{ std::io::{ErrorKind, Read, Write},
fmt::{self, Write},
io::{self, ErrorKind, Read},
},
}; };
#[derive(Debug)]
pub enum Error {
Io(io::Error),
Fmt(fmt::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(e) => write!(f, "{e}"),
Self::Fmt(e) => write!(f, "{e}"),
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
impl From<fmt::Error> for Error {
fn from(value: fmt::Error) -> Self {
Self::Fmt(value)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Fmt(e) => Some(e),
Self::Io(e) => Some(e),
}
}
}
pub struct Encoder<R: Read, W: Write> { pub struct Encoder<R: Read, W: Write> {
reader: R, reader: R,
writer: W, writer: W,
@ -81,10 +42,8 @@ impl<R: Read, W: Write> Encoder<R, W> {
} }
Ok(()) Ok(())
} }
}
impl<R: Read> Encoder<R, String> { pub fn output(self) -> W {
pub fn output(self) -> String {
self.writer self.writer
} }
} }
@ -95,17 +54,17 @@ mod tests {
#[test] #[test]
fn encode() { fn encode() {
let mut encoder = Encoder::new("Hello, World".as_bytes(), String::new()); let mut encoder = Encoder::new("Hello, World".as_bytes(), vec![]);
encoder.encode().unwrap(); encoder.encode().unwrap();
assert_eq!(encoder.output(), "48656C6C6F2C20576F726C64"); assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C64");
encoder = Encoder { encoder = Encoder {
reader: "Hello, World!".as_bytes(), reader: "Hello, World!".as_bytes(),
writer: String::new(), writer: vec![],
}; };
encoder.encode().unwrap(); encoder.encode().unwrap();
assert_eq!(encoder.output(), "48656C6C6F2C20576F726C6421"); assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C6421");
encoder = Encoder::new("Hello, World!\n".as_bytes(), String::new()); encoder = Encoder::new("Hello, World!\n".as_bytes(), vec![]);
encoder.encode().unwrap(); encoder.encode().unwrap();
assert_eq!(encoder.output(), "48656C6C6F2C20576F726C64210A"); assert_eq!(encoder.output(), b"48656C6C6F2C20576F726C64210A");
} }
} }

57
src/error.rs Normal file
View file

@ -0,0 +1,57 @@
use std::{fmt, io, num::TryFromIntError};
#[derive(Debug)]
pub enum Error {
Io(io::Error),
Fmt(fmt::Error),
IllegalChar(char),
IntError(TryFromIntError),
MissingChar,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(e) => write!(f, "{e}"),
Self::Fmt(e) => write!(f, "{e}"),
Self::IllegalChar(c) => write!(f, "Illegal Character ({c})"),
Self::IntError(e) => write!(f, "Int Error: {e}"),
Self::MissingChar => write!(f, "Missing character"),
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
impl From<char> for Error {
fn from(value: char) -> Self {
Self::IllegalChar(value)
}
}
impl From<fmt::Error> for Error {
fn from(value: fmt::Error) -> Self {
Self::Fmt(value)
}
}
impl From<TryFromIntError> for Error {
fn from(value: TryFromIntError) -> Self {
Self::IntError(value)
}
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Fmt(e) => Some(e),
Self::Io(e) => Some(e),
Self::IntError(e) => Some(e),
_ => None,
}
}
}

View file

@ -1,6 +1,8 @@
pub mod decode;
#[warn(clippy::all, clippy::pedantic)] #[warn(clippy::all, clippy::pedantic)]
pub mod encode; mod decode;
mod encode;
mod error;
pub use {decode::Decoder, encode::Encoder, error::Error};
pub static B16_ALPHABET: [char; 16] = [ pub static B16_ALPHABET: [char; 16] = [
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',