use crate::{InvalidOutputSize, Reset};
#[cfg(feature = "alloc")]
use alloc::boxed::Box;
pub trait VariableOutput: Sized {
fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
fn output_size(&self) -> usize;
fn finalize_variable(self, f: impl FnOnce(&[u8]));
fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8]));
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
fn finalize_boxed(self) -> Box<[u8]> {
let n = self.output_size();
let mut buf = vec![0u8; n].into_boxed_slice();
self.finalize_variable(|res| buf.copy_from_slice(res));
buf
}
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
fn finalize_boxed_reset(&mut self) -> Box<[u8]> {
let n = self.output_size();
let mut buf = vec![0u8; n].into_boxed_slice();
self.finalize_variable_reset(|res| buf.copy_from_slice(res));
buf
}
}
pub trait VariableOutputDirty: Sized {
fn new(output_size: usize) -> Result<Self, InvalidOutputSize>;
fn output_size(&self) -> usize;
fn finalize_variable_dirty(&mut self, f: impl FnOnce(&[u8]));
}
impl<D: VariableOutputDirty + Reset> VariableOutput for D {
fn new(output_size: usize) -> Result<Self, InvalidOutputSize> {
<Self as VariableOutputDirty>::new(output_size)
}
fn output_size(&self) -> usize {
<Self as VariableOutputDirty>::output_size(self)
}
#[inline]
fn finalize_variable(mut self, f: impl FnOnce(&[u8])) {
self.finalize_variable_dirty(f);
}
#[inline]
fn finalize_variable_reset(&mut self, f: impl FnOnce(&[u8])) {
self.finalize_variable_dirty(f);
self.reset();
}
}