#![cfg_attr(not(any(test, feature = "std")), no_std)]
#![allow(unsafe_op_in_unsafe_fn)]
#[allow(unused_imports)]
use core::{fmt, mem, ptr, slice, str};
#[macro_use]
mod encoding;
#[macro_use]
mod arch;
mod ratio;
pub use self::ratio::Ratio;
mod pad;
pub use self::pad::*;
pub use Padding::Forbidden as NoPad;
mod buf;
pub use self::buf::*;
mod hex;
pub use self::hex::*;
mod base64;
pub use self::base64::*;
mod base64std;
pub use self::base64std::*;
mod base32;
pub use self::base32::*;
#[cfg(doc)]
pub mod incremental;
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum ErrorKind {
InvalidCharacter,
IncorrectLength,
NonCanonical,
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(match self {
ErrorKind::InvalidCharacter => "invalid character",
ErrorKind::IncorrectLength => "incorrect length",
ErrorKind::NonCanonical => "non-canonical input",
})
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub struct Error {
pub kind: ErrorKind,
pub offset: usize,
}
impl Error {
#[inline]
pub const fn new(kind: ErrorKind, offset: usize) -> Self {
Self { kind, offset }
}
#[inline]
pub(crate) const fn shifted(self, offset: usize) -> Self {
Self { offset: self.offset + offset, ..self }
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} at offset {}", self.kind, self.offset)
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
#[derive(Clone, Debug)]
pub struct Display<'a, E> {
encoding: &'a E,
bytes: &'a [u8],
}
impl<'a, E: Encoding> Display<'a, E> {
#[inline]
pub fn new(encoding: &'a E, bytes: &'a [u8]) -> Self {
Self { encoding, bytes }
}
}
impl<'a, E: Encoding> fmt::Display for Display<'a, E> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut stack_buf = mem::MaybeUninit::<[u8; 512]>::uninit();
let chunk_size = E::RATIO.encoding_chunk_size(mem::size_of_val(&stack_buf));
for chunk in self.bytes.chunks(chunk_size) {
let string = self.encoding.encode_bytes_into(chunk, &mut stack_buf);
f.write_str(string)?;
}
Ok(())
}
}
mod sealed {
pub trait Sealed {}
}
use sealed::Sealed;
pub trait Encoding: Sealed {
const RATIO: Ratio;
fn encode_bytes_into<B: EncodeBuf>(&self, bytes: &[u8], buffer: B) -> B::Output;
fn decode_bytes_into<B: DecodeBuf>(&self, string: &[u8], buffer: B) -> Result<B::Output, Error>;
}