noncrypto_digests/
xxh3.rs

1use std::hash::Hasher as _;
2
3pub use ::xxhash_rust::xxh3::Xxh3 as Xxh3Hasher;
4use digest::typenum::{U16, U8};
5use digest::{FixedOutput, HashMarker, Output, OutputSizeUser, Update};
6
7use crate::common::{impl_hash_wrapper, HashWrapper};
8
9macro_rules! make_hasher {
10    ($hash_wrapper:ident, $hasher:ty, $digest:expr, $output_size:ident) => {
11        #[derive(Clone, Default)]
12        pub struct $hash_wrapper($hasher);
13
14        impl_hash_wrapper!($hash_wrapper, $hasher, $output_size);
15
16        impl Update for $hash_wrapper {
17            fn update(&mut self, data: &[u8]) {
18                self.0.write(data);
19            }
20        }
21
22        impl FixedOutput for $hash_wrapper {
23            fn finalize_into(self, out: &mut Output<Self>) {
24                let result = $digest(&self.0);
25                let bytes = result.to_be_bytes();
26                out.copy_from_slice(&bytes);
27            }
28        }
29    };
30}
31
32make_hasher!(Xxh3_64, Xxh3Hasher, Xxh3Hasher::digest, U8);
33make_hasher!(Xxh3_128, Xxh3Hasher, Xxh3Hasher::digest128, U16);
34
35#[cfg(test)]
36mod tests {
37    use insta::assert_snapshot;
38    use xxhash_rust::xxh3::{xxh3_128, xxh3_64};
39
40    use super::{Xxh3_128, Xxh3_64};
41    use crate::tests::hash;
42
43    #[test]
44    fn test_xxh3_64() {
45        let default = xxh3_64(&[]);
46        assert_eq!(hash::<Xxh3_64>(""), format!("{default:X}"));
47        assert_snapshot!(hash::<Xxh3_64>(""), @"2D06800538D394C2");
48        assert_snapshot!(hash::<Xxh3_64>("hello"), @"9555E8555C62DCFD");
49    }
50
51    #[test]
52    fn test_xxh3_128() {
53        let default = xxh3_128(&[]);
54        assert_eq!(hash::<Xxh3_128>(""), format!("{default:X}"));
55        assert_snapshot!(hash::<Xxh3_128>(""), @"99AA06D3014798D86001C324468D497F");
56        assert_snapshot!(hash::<Xxh3_128>("hello"), @"B5E9C1AD071B3E7FC779CFAA5E523818");
57    }
58}