use std::{rc::Rc, sync::Arc};
pub trait Digest {
const NAME: &'static str;
fn digest(&mut self, input: &[u8]) -> String;
fn update(&mut self, input: &[u8]);
fn verify(&mut self, encoded: &str) -> bool;
}
pub trait DigestBuilder: Digest {
fn build() -> Self;
}
pub trait DigestFactory {
type Digest: DigestBuilder + Digest + Send + 'static;
}
impl<'a, T> DigestFactory for &'a T
where
T: DigestFactory,
{
type Digest = T::Digest;
}
impl<'a, T> DigestFactory for &'a mut T
where
T: DigestFactory,
{
type Digest = T::Digest;
}
impl<T> DigestFactory for Box<T>
where
T: DigestFactory,
{
type Digest = T::Digest;
}
impl<T> DigestFactory for Rc<T>
where
T: DigestFactory,
{
type Digest = T::Digest;
}
impl<T> DigestFactory for Arc<T>
where
T: DigestFactory,
{
type Digest = T::Digest;
}
impl<'a, T> Digest for &'a mut T
where
T: Digest,
{
const NAME: &'static str = T::NAME;
fn digest(&mut self, input: &[u8]) -> String {
T::digest(self, input)
}
fn update(&mut self, input: &[u8]) {
T::update(self, input)
}
fn verify(&mut self, encoded: &str) -> bool {
T::verify(self, encoded)
}
}
impl<T> Digest for Box<T>
where
T: Digest,
{
const NAME: &'static str = T::NAME;
fn digest(&mut self, input: &[u8]) -> String {
T::digest(self, input)
}
fn update(&mut self, input: &[u8]) {
T::update(self, input)
}
fn verify(&mut self, encoded: &str) -> bool {
T::verify(self, encoded)
}
}