Custom attributes
The Hash
trait supports the following attributes:
- Container attributes
- Field attributes
Ignoring a field
You can use derivative to ignore fields from a Hash
implementation:
#![allow(unused)] fn main() { extern crate derivative; use derivative::Derivative; #[derive(Derivative)] #[derivative(Hash)] struct Foo { foo: u8, #[derivative(Hash="ignore")] bar: i32, } #[derive(Hash)] struct Bar { foo: u8, } fn hash<T: std::hash::Hash>(t: &T) -> u64 { use std::hash::Hasher; let mut s = std::collections::hash_map::DefaultHasher::new(); t.hash(&mut s); s.finish() } assert_eq!(hash(&Foo { foo: 42, bar: -1337 }), hash(&Bar { foo: 42 })); }
Hash with
You can pass a field to a hash function:
#![allow(unused)] fn main() { extern crate derivative; use derivative::Derivative; mod path { pub struct SomeTypeThatMightNotBeHash; pub mod to { pub fn my_hash_fn<H>(_: &super::SomeTypeThatMightNotBeHash, state: &mut H) where H: std::hash::Hasher { unimplemented!() } } } use path::SomeTypeThatMightNotBeHash; #[derive(Derivative)] #[derivative(Hash)] struct Foo { foo: u32, #[derivative(Hash(hash_with="path::to::my_hash_fn"))] bar: SomeTypeThatMightNotBeHash, } }
The field bar
will be hashed with path::to::my_hash_fn(&bar, &mut state)
where state
is the current Hasher
.
The function must the following prototype:
fn my_hash_fn<H>(&T, state: &mut H) where H: Hasher;
Limitations
On structure, derivative(Hash)
will produce the same hash as derive(Hash)
.
On unions however, it will produces the same hashes only for unitary
variants!
Custom bound
As most other traits, Hash
supports a custom bound on container and fields.
See Debug
's documentation for more information.