noncrypto_digests/
fnv.rs

1use std::hash::Hasher as StdHasher;
2
3pub use ::fnv::FnvHasher;
4use digest::typenum::U8;
5use digest::{FixedOutput, HashMarker, Output, OutputSizeUser, Update};
6
7use crate::common::{impl_hash_wrapper, HashWrapper};
8
9#[derive(Default)]
10pub struct Fnv(FnvHasher);
11
12impl_hash_wrapper!(Fnv, FnvHasher, U8);
13
14impl Clone for Fnv {
15    fn clone(&self) -> Self {
16        Self(FnvHasher::with_key(self.0.finish()))
17    }
18}
19
20impl Update for Fnv {
21    fn update(&mut self, data: &[u8]) {
22        self.0.write(data);
23    }
24}
25
26impl FixedOutput for Fnv {
27    fn finalize_into(self, out: &mut Output<Self>) {
28        let result = self.0.finish();
29        let bytes = result.to_be_bytes();
30        out.copy_from_slice(&bytes);
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use insta::assert_snapshot;
37
38    use super::*;
39    use crate::tests::hash;
40
41    #[test]
42    fn test_fnv() {
43        let default = FnvHasher::default().finish();
44        assert_eq!(hash::<Fnv>(""), format!("{default:X}"));
45        assert_snapshot!(hash::<Fnv>(""), @"CBF29CE484222325");
46        assert_snapshot!(hash::<Fnv>("hello"), @"A430D84680AABD0B");
47    }
48}