1 use std::{
2     fmt::Display,
3     hash::{Hash, Hasher},
4 };
5 
6 const MAGIC_INIT: u64 = 0x811C_9DC5;
7 
8 // TODO: Docs
9 pub trait Key: Hash + Display {
key(&self) -> u6410     fn key(&self) -> u64;
11 }
12 
13 impl<T> Key for T
14 where
15     T: Hash + Display,
16 {
key(&self) -> u6417     fn key(&self) -> u64 {
18         let mut hasher = FnvHasher::new();
19         self.hash(&mut hasher);
20         hasher.finish()
21     }
22 }
23 
24 pub(crate) struct FnvHasher(u64);
25 
26 impl FnvHasher {
new() -> Self27     pub(crate) fn new() -> Self {
28         FnvHasher(MAGIC_INIT)
29     }
30 }
31 
32 impl Hasher for FnvHasher {
finish(&self) -> u6433     fn finish(&self) -> u64 {
34         self.0
35     }
write(&mut self, bytes: &[u8])36     fn write(&mut self, bytes: &[u8]) {
37         let FnvHasher(mut hash) = *self;
38 
39         for byte in bytes.iter() {
40             hash ^= u64::from(*byte);
41             hash = hash.wrapping_mul(0x0100_0000_01b3);
42         }
43 
44         *self = FnvHasher(hash);
45     }
46 }
47