noncrypto_digests/
xxh3.rs1use 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}