use super::{AlgorithmName, XofReaderCore}; use crate::XofReader; use block_buffer::EagerBuffer; use core::fmt; use crypto_common::typenum::{IsLess, Le, NonZero, U256}; /// Wrapper around [`XofReaderCore`] implementations. /// /// It handles data buffering and implements the mid-level traits. #[derive(Clone, Default)] pub struct XofReaderCoreWrapper<T> where T: XofReaderCore, T::BlockSize: IsLess<U256>, Le<T::BlockSize, U256>: NonZero, { pub(super) core: T, pub(super) buffer: EagerBuffer<T::BlockSize>, } impl<T> fmt::Debug for XofReaderCoreWrapper<T> where T: XofReaderCore + AlgorithmName, T::BlockSize: IsLess<U256>, Le<T::BlockSize, U256>: NonZero, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { T::write_alg_name(f)?; f.write_str(" { .. }") } } impl<T> XofReader for XofReaderCoreWrapper<T> where T: XofReaderCore, T::BlockSize: IsLess<U256>, Le<T::BlockSize, U256>: NonZero, { #[inline] fn read(&mut self, buffer: &mut [u8]) { let Self { core, buffer: buf } = self; buf.set_data(buffer, |blocks| { for block in blocks { *block = core.read_block(); } }); } } #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] impl<T> std::io::Read for XofReaderCoreWrapper<T> where T: XofReaderCore, T::BlockSize: IsLess<U256>, Le<T::BlockSize, U256>: NonZero, { #[inline] fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { XofReader::read(self, buf); Ok(buf.len()) } }