1use digest::Digest;
2#[cfg(feature = "hex")]
3use hex::ToHex as _;
4
5#[derive(Debug, Default)]
6pub enum HashState<T> {
7 #[default]
8 Created,
9 Started,
10 HasValues(T),
11}
12
13impl<T: Digest + Clone> HashState<T> {
14 #[inline]
15 pub fn add_null(&mut self) {
16 if let Self::Created = self {
17 *self = Self::Started;
18 }
19 }
20
21 #[inline]
22 pub fn add_value(&mut self, value: &[u8]) {
23 match self {
24 Self::Created | Self::Started => {
25 let mut hasher = T::new();
26 hasher.update(value);
27 *self = Self::HasValues(hasher);
28 }
29 Self::HasValues(hasher) => {
30 hasher.update(value);
31 }
32 }
33 }
34
35 #[inline]
36 pub fn finalize(self) -> Option<Vec<u8>> {
37 match self {
38 Self::Created | Self::Started => None,
39 Self::HasValues(hasher) => Some(hasher.finalize().to_vec()),
40 }
41 }
42
43 #[inline]
44 #[cfg(feature = "hex")]
45 pub fn finalize_hex(self) -> Option<String> {
46 match self {
47 Self::Created => None,
48 Self::Started => Some(String::new()),
49 Self::HasValues(hasher) => Some(hasher.finalize().to_vec().encode_hex_upper()),
50 }
51 }
52}