1 #![cfg(feature = "alloc")]
2 use alloc::boxed::Box;
3 
4 use super::{FixedOutput, Reset, Update};
5 use generic_array::typenum::Unsigned;
6 
7 /// The `DynDigest` trait is a modification of `Digest` trait suitable
8 /// for trait objects.
9 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
10 pub trait DynDigest {
11     /// Digest input data.
12     ///
13     /// This method can be called repeatedly for use with streaming messages.
update(&mut self, data: &[u8])14     fn update(&mut self, data: &[u8]);
15 
16     /// Retrieve result and reset hasher instance
finalize_reset(&mut self) -> Box<[u8]>17     fn finalize_reset(&mut self) -> Box<[u8]>;
18 
19     /// Retrieve result and consume boxed hasher instance
finalize(self: Box<Self>) -> Box<[u8]>20     fn finalize(self: Box<Self>) -> Box<[u8]>;
21 
22     /// Reset hasher instance to its initial state.
reset(&mut self)23     fn reset(&mut self);
24 
25     /// Get output size of the hasher
output_size(&self) -> usize26     fn output_size(&self) -> usize;
27 
28     /// Clone hasher state into a boxed trait object
box_clone(&self) -> Box<dyn DynDigest>29     fn box_clone(&self) -> Box<dyn DynDigest>;
30 }
31 
32 impl<D: Update + FixedOutput + Reset + Clone + 'static> DynDigest for D {
update(&mut self, data: &[u8])33     fn update(&mut self, data: &[u8]) {
34         Update::update(self, data);
35     }
36 
finalize_reset(&mut self) -> Box<[u8]>37     fn finalize_reset(&mut self) -> Box<[u8]> {
38         let res = self.finalize_fixed_reset().to_vec().into_boxed_slice();
39         Reset::reset(self);
40         res
41     }
42 
finalize(self: Box<Self>) -> Box<[u8]>43     fn finalize(self: Box<Self>) -> Box<[u8]> {
44         self.finalize_fixed().to_vec().into_boxed_slice()
45     }
46 
reset(&mut self)47     fn reset(&mut self) {
48         Reset::reset(self);
49     }
50 
output_size(&self) -> usize51     fn output_size(&self) -> usize {
52         <Self as FixedOutput>::OutputSize::to_usize()
53     }
54 
box_clone(&self) -> Box<dyn DynDigest>55     fn box_clone(&self) -> Box<dyn DynDigest> {
56         Box::new(self.clone())
57     }
58 }
59 
60 impl Clone for Box<dyn DynDigest> {
clone(&self) -> Self61     fn clone(&self) -> Self {
62         self.box_clone()
63     }
64 }
65