1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
use std::hash::{ Hash, Hasher }; use std::collections::hash_map::DefaultHasher; use super::*; pub trait KeyConstraint: ValueConstraint + Hash { } impl<T: ?Sized + ValueConstraint + Hash> KeyConstraint for T { } pub trait Key: Value { fn hashcode(&self) -> u64 { self.memory_address() as u64 } as_trait!(Key); as_boxed!(Key); } impl<T: ?Sized + KeyConstraint> Key for T { fn hashcode(&self) -> u64 { let mut hasher = DefaultHasher::default(); self.hash(&mut hasher); hasher.finish() } as_trait!(impl Key); as_boxed!(impl Key); } #[macro_export] macro_rules! boxed_key_trait { ($trait: tt) => { as_boxed!(impl Hash for $trait); boxed_value_trait!($trait); }; } boxed_key_trait!(Key); #[cfg(test)] mod tests { use super::*; use std::collections::HashMap; #[derive(Hash, PartialEq, Eq, Debug, Clone)] struct S1 { a: i32, b: u32 } #[test] fn hashcode() { let s = S1 { a: 1, b: 2 }; assert_eq!(s.hashcode(), s.clone().hashcode()); let bs: Box<dyn Key> = Box::new(s); assert_eq!(bs.hashcode(), bs.clone().hashcode()); let mut hasher = DefaultHasher::new(); bs.hash(&mut hasher); hasher.finish(); } #[test] fn hashmap() { let k = S1 { a: 1, b: 2 }; let v = S1 { a: 11, b: 22 }; let key: Box<dyn Key> = Box::new(k.clone()); let value: Box<dyn Value> = Box::new(v.clone()); let mut map = HashMap::<Box<dyn Key>, Box<dyn Value>>::new(); map.insert(key.clone(), value.clone()); assert_eq!(&value, map.get(&key).unwrap()); } }