Expand description
Stable content hashing, so a receiver can check that a delta is being applied to the state it was computed against.
std::hash::Hash cannot do this job for two reasons. It is not
implemented for HashSet or HashMap, which are exactly the
collections the unordered field types require, and the hash it feeds a
DefaultHasher is explicitly
allowed to change between Rust releases — fine for a hash table that lives
and dies in one process, useless for a value two processes have to agree
on.
Fingerprint fixes both. Sets and maps are folded commutatively so
iteration order cannot matter, and Hasher is FNV-1a with the constants
written down here, so the same value fingerprints identically on any
platform, any Rust version, forever.
Derive it rather than writing it:
use delta_struct::{fingerprint_of, Fingerprint};
use std::collections::HashSet;
#[derive(Fingerprint)]
struct Device {
services: HashSet<String>,
online: bool,
}
let device = |online| Device {
services: vec!["ssh".to_string(), "http".to_string()].into_iter().collect(),
online,
};
// Set iteration order does not reach the fingerprint.
assert_eq!(fingerprint_of(&device(true)), fingerprint_of(&device(true)));
assert_ne!(fingerprint_of(&device(true)), fingerprint_of(&device(false)));Structs§
- Hasher
- The hasher
Fingerprintwrites into: FNV-1a, 64-bit.
Traits§
- Fingerprint
- A value whose contents can be reduced to a number that two processes will agree on.
Functions§
- fingerprint_
of - Fingerprints a value on its own, which is what you usually want.