use crate::sealed::Sealed;
#[cfg(doc)]
use crate::GitOid;
use core::fmt::Debug;
use core::hash::Hash;
use core::ops::Deref;
use digest::block_buffer::generic_array::GenericArray;
use digest::Digest;
use digest::OutputSizeUser;
pub trait HashAlgorithm: Sealed {
#[doc(hidden)]
const NAME: &'static str;
#[doc(hidden)]
type Alg: Digest;
#[doc(hidden)]
type Array: Copy + PartialEq + Ord + Hash + Debug + Deref<Target = [u8]>;
#[doc(hidden)]
fn array_from_generic(
arr: GenericArray<u8, <Self::Alg as OutputSizeUser>::OutputSize>,
) -> Self::Array;
#[doc(hidden)]
fn new() -> Self::Alg;
}
#[allow(unused_macros)]
macro_rules! impl_hash_algorithm {
( $type:ident, $alg_ty:ty, $name:literal ) => {
impl Sealed for $type {}
impl HashAlgorithm for $type {
const NAME: &'static str = $name;
type Alg = $alg_ty;
type Array = GenericArray<u8, <Self::Alg as OutputSizeUser>::OutputSize>;
fn array_from_generic(
arr: GenericArray<u8, <Self::Alg as OutputSizeUser>::OutputSize>,
) -> Self::Array {
arr
}
fn new() -> Self::Alg {
Self::Alg::new()
}
}
};
}
#[cfg(feature = "sha1")]
pub struct Sha1 {
#[doc(hidden)]
_private: (),
}
#[cfg(feature = "sha1")]
impl_hash_algorithm!(Sha1, sha1::Sha1, "sha1");
#[cfg(feature = "sha256")]
pub struct Sha256 {
#[doc(hidden)]
_private: (),
}
#[cfg(feature = "sha256")]
impl_hash_algorithm!(Sha256, sha2::Sha256, "sha256");
#[cfg(feature = "sha1cd")]
pub struct Sha1Cd {
#[doc(hidden)]
_private: (),
}
#[cfg(feature = "sha1cd")]
impl_hash_algorithm!(Sha1Cd, sha1collisiondetection::Sha1CD, "sha1cd");