pub mod arrayref;
pub mod owned;
pub mod slice;
#[cfg(feature = "generic-tests")]
pub mod tests;
#[derive(Debug, PartialEq)]
pub enum UpdateError {
InvalidPayloadLength,
MaximumLengthExceeded,
Unknown,
}
impl core::fmt::Display for UpdateError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let text = match self {
UpdateError::InvalidPayloadLength => "the length of the provided payload is invalid",
UpdateError::MaximumLengthExceeded => "the maximum input length is exceeded",
UpdateError::Unknown => "indicates an unknown error",
};
f.write_str(text)
}
}
#[cfg(feature = "error-in-core")]
mod error_in_core {
impl core::error::Error for super::UpdateError {}
}
pub trait DigestIncrementalBase {
type IncrementalState: InitializeDigestState;
fn reset(state: &mut Self::IncrementalState);
fn update(state: &mut Self::IncrementalState, payload: &[u8]) -> Result<(), UpdateError>;
}
pub trait InitializeDigestState {
fn new() -> Self;
}
#[derive(Clone)]
pub struct Hasher<const N: usize, D: DigestIncrementalBase> {
pub state: D::IncrementalState,
}
impl<const N: usize, D: arrayref::DigestIncremental<N>> Default for Hasher<N, D>
where
D::IncrementalState: Default,
{
fn default() -> Self {
Self {
state: Default::default(),
}
}
}
impl<const N: usize, D: DigestIncrementalBase + slice::Hash> Hasher<N, D> {
pub fn hash_slice(digest: &mut [u8], payload: &[u8]) -> Result<usize, slice::HashError> {
D::hash(digest, payload)
}
}
impl<const N: usize, D: slice::DigestIncremental> Hasher<N, D> {
pub fn finish_slice(&mut self, digest: &mut [u8]) -> Result<usize, slice::FinishError> {
D::finish(&mut self.state, digest)
}
}
impl<const N: usize, D: DigestIncrementalBase> Hasher<N, D> {
pub fn update(&mut self, payload: &[u8]) -> Result<(), UpdateError> {
D::update(&mut self.state, payload)
}
pub fn reset(&mut self) {
D::reset(&mut self.state)
}
pub fn new() -> Self {
Self {
state: D::IncrementalState::new(),
}
}
}
impl<const N: usize, D: arrayref::DigestIncremental<N>> Hasher<N, D> {
pub fn finish(&mut self, digest: &mut [u8; N]) {
D::finish(&mut self.state, digest)
}
pub fn finish_to_owned(&mut self) -> [u8; N] {
<D as owned::DigestIncremental<N>>::finish(&mut self.state)
}
}
impl<const N: usize, D: DigestIncrementalBase + arrayref::Hash<N>> Hasher<N, D> {
pub fn hash(digest: &mut [u8; N], payload: &[u8]) -> Result<(), arrayref::HashError> {
D::hash(digest, payload)
}
pub fn hash_to_owned(payload: &[u8]) -> Result<[u8; N], arrayref::HashError> {
<D as owned::Hash<N>>::hash(payload)
}
}