hud_slice_by_8/crc32c/
hasher.rs1use crate::crc32c::slice_by_8_with_seed;
2use core::hash::{BuildHasher, BuildHasherDefault, Hasher};
3
4#[derive(Debug, Default)]
6pub struct CRC32CHasher {
7 key: u32,
8}
9
10impl CRC32CHasher {
11 pub fn with_seed(seed: u32) -> CRC32CHasher {
13 CRC32CHasher { key: seed }
14 }
15}
16
17impl Hasher for CRC32CHasher {
18 fn finish(&self) -> u64 {
30 self.key as u64
31 }
32
33 fn write(&mut self, bytes: &[u8]) {
45 self.key = slice_by_8_with_seed(bytes, self.key);
46 }
47}
48
49impl BuildHasher for CRC32CHasher {
50 type Hasher = CRC32CHasher;
51
52 fn build_hasher(&self) -> Self::Hasher {
54 CRC32CHasher::default()
55 }
56}
57
58pub type CRC32CBuildHasher = BuildHasherDefault<CRC32CHasher>;
60
61#[cfg(test)]
62mod tests {
63
64 use super::{CRC32CBuildHasher, CRC32CHasher};
65 use crate::crc32c;
66 use core::hash::{BuildHasher, Hasher};
67
68 #[test]
69 fn hasher_default() {
70 let hasher = CRC32CHasher::default();
71 assert_eq!(hasher.finish(), 0);
72 }
73
74 #[test]
75 fn hasher_with_seed() {
76 let hasher = CRC32CHasher::with_seed(0x9B9BEFFB);
77 assert_eq!(hasher.finish(), 0x9B9BEFFB);
78 }
79
80 #[test]
81 fn build_hasher() {
82 let build_hasher = CRC32CHasher::default();
83 let mut hasher = build_hasher.build_hasher();
84 hasher.write(b"abcdefghijklmnopqrstuvwxyz");
85 assert_eq!(hasher.finish(), 0x9EE6EF25);
86 }
87
88 #[test]
89 fn build_hasher_results_are_coherent_with_free_function() {
90 let build_hasher = CRC32CHasher::default();
91 let mut hasher = build_hasher.build_hasher();
92
93 const HASH_ME: &[u8] = b"abcdefghijklmnopqrstuvwxyz";
94
95 let hash_free_function = crc32c::slice_by_8(HASH_ME);
97 hasher.write(HASH_ME);
98 assert_eq!(hasher.finish(), hash_free_function as u64);
99
100 let hash_free_function = crc32c::slice_by_8_with_seed(HASH_ME, hash_free_function);
102 hasher.write(HASH_ME);
103 assert_eq!(hasher.finish(), hash_free_function as u64);
104 }
105
106 #[test]
107 fn hasher_is_usable_in_std_collections() {
108 extern crate std;
109 use std::collections::HashMap;
110 const HASH_ME: &str = "hash me!";
111 const VALUE: &str = "Hi";
112
113 let mut map = HashMap::with_hasher(CRC32CBuildHasher::default());
114 map.insert(HASH_ME, VALUE);
115 assert_eq!(map.get(&HASH_ME), Some(&VALUE));
116 }
117}