use digest::Digest;
pub trait Hasher: Send {
fn update(&mut self, data: &[u8]);
fn finalize(self) -> Vec<u8>;
}
pub struct DigestHasher<D: digest::Digest + Send>(D);
impl<D: digest::Digest + Send> DigestHasher<D> {
pub fn from_digest(digest: D) -> Self {
Self(digest)
}
}
impl<D: digest::Digest + Send> Hasher for DigestHasher<D> {
fn update(&mut self, data: &[u8]) {
self.0.update(data);
}
fn finalize(self) -> Vec<u8> {
self.0.finalize().to_vec()
}
}
#[cfg(feature = "sha256")]
pub type Sha256Hasher = DigestHasher<sha2::Sha256>;
#[cfg(feature = "sha256")]
impl Default for Sha256Hasher {
fn default() -> Self {
Self::new()
}
}
impl Sha256Hasher {
pub fn new() -> Self {
DigestHasher::from_digest(sha2::Sha256::new())
}
}
#[cfg(feature = "blake3")]
pub struct Blake3Hasher(blake3::Hasher);
#[cfg(feature = "blake3")]
impl Default for Blake3Hasher {
fn default() -> Self {
Self::new()
}
}
#[cfg(feature = "blake3")]
impl Blake3Hasher {
pub fn new() -> Self {
Self(blake3::Hasher::new())
}
}
#[cfg(feature = "blake3")]
impl Hasher for Blake3Hasher {
fn update(&mut self, data: &[u8]) {
self.0.update(data);
}
fn finalize(self) -> Vec<u8> {
self.0.finalize().as_bytes().to_vec()
}
}
#[cfg(feature = "sha3")]
pub type Sha3_256Hasher = DigestHasher<sha3::Sha3_256>;
#[cfg(feature = "sha3")]
impl Sha3_256Hasher {
pub fn new() -> Self {
DigestHasher::from_digest(sha3::Sha3_256::new())
}
}