sqlite_hashes/
state.rs

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}