use crate::Digest;
use core::fmt::{self, Debug, Formatter};
#[cfg(feature = "sha3")]
type Impl = sha3::Keccak256;
#[cfg(not(feature = "sha3"))]
type Impl = crate::keccak::V256;
#[derive(Clone, Default)]
pub struct Hasher(Impl);
impl Hasher {
pub fn new() -> Self {
Self::default()
}
pub fn update(&mut self, data: impl AsRef<[u8]>) {
#[cfg(feature = "sha3")]
{
sha3::Digest::update(&mut self.0, data.as_ref());
}
#[cfg(not(feature = "sha3"))]
{
self.0 = self.0.absorb(data.as_ref());
}
}
pub fn finalize(self) -> Digest {
#[cfg(feature = "sha3")]
{
Digest(sha3::Digest::finalize(self.0).into())
}
#[cfg(not(feature = "sha3"))]
{
Digest(self.0.squeeze())
}
}
}
impl Debug for Hasher {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_tuple("Hasher").finish()
}
}
impl fmt::Write for Hasher {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.update(s);
Ok(())
}
}
#[cfg(feature = "std")]
mod io {
use super::Hasher;
use std::io::{self, Write};
impl Write for Hasher {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.update(buf);
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
}