Begin getting docs in order
This commit is contained in:
parent
d203aaf5d3
commit
13fda08e1b
@ -1,13 +1,30 @@
|
||||
pub use {
|
||||
use {
|
||||
super::B64Alphabet,
|
||||
std::io::{self, ErrorKind, Read, Write},
|
||||
std::{
|
||||
fmt,
|
||||
io::{self, 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),
|
||||
MissingPadding,
|
||||
IntError(TryFromIntError),
|
||||
}
|
||||
|
||||
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::MissingPadding => write!(f, "Missing Padding"),
|
||||
Self::IntError(e) => write!(f, "Int Error: {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
@ -22,6 +39,22 @@ impl From<char> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
reader: R,
|
||||
writer: W,
|
||||
@ -37,14 +70,24 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decodes the bytes provided by `self.reader` and writes the resulting
|
||||
/// bytes into `self.writer`.
|
||||
/// # Errors
|
||||
/// - io failure will return `Error::Io`
|
||||
/// - a character not in the alphabet, or encountering any character after
|
||||
/// the first occurance of the padding character, will return `Error::IllegalChar`
|
||||
/// - if the reader comes up short of the final four byte block will return
|
||||
/// `Error::MissingPadding`
|
||||
/// - `intError` should never be returned. If this error is recieved the code
|
||||
/// is somehow broken. Please file a bug.
|
||||
pub fn decode(&mut self) -> Result<(), Error> {
|
||||
loop {
|
||||
let mut ibuf = [0_u8; 4];
|
||||
let mut obuf = [0_u8; 3];
|
||||
let mut in_buf = [0_u8; 4];
|
||||
let mut out_buf = [0_u8; 3];
|
||||
let mut num = 0_u32;
|
||||
let mut n_bytes = 0;
|
||||
loop {
|
||||
n_bytes += match self.reader.read(&mut ibuf) {
|
||||
n_bytes += match self.reader.read(&mut in_buf) {
|
||||
Ok(n) => n,
|
||||
Err(e) if e.kind() == ErrorKind::Interrupted => continue,
|
||||
Err(e) => return Err(e.into()),
|
||||
@ -57,7 +100,7 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
||||
_ => return Err(Error::MissingPadding),
|
||||
}
|
||||
let mut bytes = 0;
|
||||
for (i, &c) in ibuf.iter().enumerate() {
|
||||
for (i, &c) in in_buf.iter().enumerate() {
|
||||
let c = c.into();
|
||||
num <<= 6;
|
||||
if c == self.alphabet.pad() {
|
||||
@ -69,15 +112,15 @@ impl<R: Read, W: Write> Decoder<R, W> {
|
||||
let Some(idx) = self.alphabet.get(c) else {
|
||||
return Err(Error::IllegalChar(c));
|
||||
};
|
||||
num |= idx as u32;
|
||||
num |= u32::try_from(idx)?;
|
||||
bytes += 1;
|
||||
}
|
||||
let olen = bytes * 6 / 8;
|
||||
for i in (0..3).rev() {
|
||||
obuf[i] = (num & 0xff) as u8;
|
||||
out_buf[i] = (num & 0xff) as u8;
|
||||
num >>= 8;
|
||||
}
|
||||
self.writer.write_all(&mut obuf[0..olen])?;
|
||||
self.writer.write_all(&out_buf[0..olen])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub use {
|
||||
use {
|
||||
super::B64Alphabet,
|
||||
std::{
|
||||
fmt::{self, Write},
|
||||
@ -49,6 +49,8 @@ pub struct Encoder<R: Read, W: Write> {
|
||||
}
|
||||
|
||||
impl<R: Read, W: Write> Encoder<R, W> {
|
||||
/// Creates a new encoder with the given reader and writer. If alphabet is
|
||||
/// `None` the encoder will use the default rfc4648 alphabet.
|
||||
pub fn new(reader: R, writer: W, alphabet: Option<B64Alphabet>) -> Self {
|
||||
Self {
|
||||
reader,
|
||||
@ -91,14 +93,7 @@ impl<R: Read, W: Write> Encoder<R, W> {
|
||||
}
|
||||
num >>= 6;
|
||||
}
|
||||
write!(
|
||||
self.writer,
|
||||
"{}{}{}{}",
|
||||
char::try_from(obuf[0]).unwrap(),
|
||||
char::try_from(obuf[1]).unwrap(),
|
||||
char::try_from(obuf[2]).unwrap(),
|
||||
char::try_from(obuf[3]).unwrap()
|
||||
)?;
|
||||
write!(self.writer, "{}{}{}{}", obuf[0], obuf[1], obuf[2], obuf[3])?;
|
||||
if outlen < 4 {
|
||||
break;
|
||||
}
|
||||
|
14
src/lib.rs
14
src/lib.rs
@ -1,10 +1,6 @@
|
||||
mod decode;
|
||||
mod encode;
|
||||
|
||||
pub use {
|
||||
decode::{Decoder as B64Decoder, Error as B64DecoderError},
|
||||
encode::{Encoder as B64Encoder, Error as B64EncoderError},
|
||||
};
|
||||
#[warn(clippy::all, clippy::pedantic)]
|
||||
pub mod decode;
|
||||
pub mod encode;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct B64Alphabet {
|
||||
@ -29,7 +25,7 @@ impl Default for B64Alphabet {
|
||||
}
|
||||
|
||||
impl B64Alphabet {
|
||||
pub fn get(&self, c: char) -> Option<usize> {
|
||||
pub(crate) fn get(&self, c: char) -> Option<usize> {
|
||||
for (idx, x) in self.items.iter().enumerate() {
|
||||
if *x == c {
|
||||
return Some(idx);
|
||||
@ -38,7 +34,7 @@ impl B64Alphabet {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn pad(&self) -> char {
|
||||
pub(crate) fn pad(&self) -> char {
|
||||
self.pad
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user