//mod ext; use ext::*; mod encode; mod hash; pub use digest; pub use hash::{ ParallelHashOutput, ParallelHash, ParallelDigest, }; pub type DefaultDigest = sha2::Sha256; #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct Builder { digest: std::marker::PhantomData, chunk_size: Option, } impl Builder { #[inline] pub fn create_default() -> ParallelDigest { Self::new().create() } pub const fn new_default() -> Self { Self { digest: std::marker::PhantomData, chunk_size: None } } } impl Builder { //pub type Digest = D; pub const fn new() -> Self { Self { digest: std::marker::PhantomData, chunk_size: None } } pub const fn with_digest(self) -> Builder { Builder { chunk_size: self.chunk_size, digest: std::marker::PhantomData, } } pub const fn with_chunk_size(self, chunk_size: usize) -> Self { Self { chunk_size: std::num::NonZeroUsize::new(chunk_size), ..self } } } impl Builder { #[inline] pub fn chunk_size(&self) -> usize { extern "C" { fn getpagesize() -> std::os::raw::c_int; } self.chunk_size .or_else(|| unsafe { std::num::NonZeroUsize::new(getpagesize().try_into().expect("Failed to get page size")) }) .expect("Failed to get page size: cannot be zero") .get() } #[inline] pub fn create(self) -> ParallelDigest { ParallelDigest::::new(self.chunk_size()) } #[inline] pub fn digest_slice(self, slice: impl AsRef<[u8]>) -> ParallelHash { ParallelDigest::::digest_slice(self.chunk_size(), slice) } } impl From> for ParallelDigest { #[inline] fn from(from: Builder) -> Self { from.create() } } #[cfg(test)] mod tests { use super::*; #[test] fn parallel_hash_specific_cs() { const CHUNK_SIZE: usize = 0; let slice = [10u8; 4096 << 2];//b"One two three for fize size seven eight."; let mut digest = Builder::new().with_chunk_size(CHUNK_SIZE).create(); digest.append_slice(slice); let digest= digest.complete().finalize(); println!("digest: {digest}"); assert_eq!(digest, Builder::new_default().with_chunk_size(CHUNK_SIZE).digest_slice(slice).finalize(), "phash of same input produced different output"); assert_ne!(digest, Builder::new_default().with_chunk_size(CHUNK_SIZE).digest_slice(&slice[..8]).finalize(), "phash of differing input produced same output"); } }