digest/core_api/
xof_reader.rs

1use super::{AlgorithmName, XofReaderCore};
2use crate::XofReader;
3use block_buffer::EagerBuffer;
4use core::fmt;
5use crypto_common::typenum::{IsLess, Le, NonZero, U256};
6
7/// Wrapper around [`XofReaderCore`] implementations.
8///
9/// It handles data buffering and implements the mid-level traits.
10#[derive(Clone, Default)]
11pub struct XofReaderCoreWrapper<T>
12where
13    T: XofReaderCore,
14    T::BlockSize: IsLess<U256>,
15    Le<T::BlockSize, U256>: NonZero,
16{
17    pub(super) core: T,
18    pub(super) buffer: EagerBuffer<T::BlockSize>,
19}
20
21impl<T> fmt::Debug for XofReaderCoreWrapper<T>
22where
23    T: XofReaderCore + AlgorithmName,
24    T::BlockSize: IsLess<U256>,
25    Le<T::BlockSize, U256>: NonZero,
26{
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
28        T::write_alg_name(f)?;
29        f.write_str(" { .. }")
30    }
31}
32
33impl<T> XofReader for XofReaderCoreWrapper<T>
34where
35    T: XofReaderCore,
36    T::BlockSize: IsLess<U256>,
37    Le<T::BlockSize, U256>: NonZero,
38{
39    #[inline]
40    fn read(&mut self, buffer: &mut [u8]) {
41        let Self { core, buffer: buf } = self;
42        buf.set_data(buffer, |blocks| {
43            for block in blocks {
44                *block = core.read_block();
45            }
46        });
47    }
48}
49
50#[cfg(feature = "std")]
51#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
52impl<T> std::io::Read for XofReaderCoreWrapper<T>
53where
54    T: XofReaderCore,
55    T::BlockSize: IsLess<U256>,
56    Le<T::BlockSize, U256>: NonZero,
57{
58    #[inline]
59    fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
60        XofReader::read(self, buf);
61        Ok(buf.len())
62    }
63}