decorum/
hash.rs

1//! Hashing of IEEE 754 floating-point values.
2//!
3//! This module provides hashing for primitive floating-point values. Given the set of zero
4//! representations $Z$ and set of `NaN` representations $N$, hashing coalesces their
5//! representations such that:
6//!
7//! $$
8//! \begin{aligned}
9//! h(a)=h(b)&\mid a\in{Z},~b\in{Z}\cr\[1em\]
10//! h(a)=h(b)&\mid a\in{N},~b\in{N}
11//! \end{aligned}
12//! $$
13//!
14//! The [`CanonicalHash`] trait agrees with the ordering and equivalence relations of the
15//! [`CanonicalOrd`] and [`CanonicalEq`] traits.
16//!
17//! [`CanonicalEq`]: crate::cmp::CanonicalEq
18//! [`CanonicalOrd`]: crate::cmp::CanonicalOrd
19
20use core::hash::{Hash, Hasher};
21
22use crate::ToCanonical;
23
24pub trait CanonicalHash {
25    fn hash_canonical<H>(&self, state: &mut H)
26    where
27        H: Hasher;
28}
29
30// TODO: This implementation conflicts with implementations over references to a type `T` where
31//       `T: CanonicalHash`. However, this is because `rustc` claims that "sealed" traits can be
32//       implemented downstream, which isn't true. Write reference implementations when possible
33//       (or consider removing this blanket implementation).
34impl<T> CanonicalHash for T
35where
36    T: ToCanonical,
37{
38    fn hash_canonical<H>(&self, state: &mut H)
39    where
40        H: Hasher,
41    {
42        self.to_canonical().hash(state)
43    }
44}
45
46impl<T> CanonicalHash for [T]
47where
48    T: CanonicalHash,
49{
50    fn hash_canonical<H>(&self, state: &mut H)
51    where
52        H: Hasher,
53    {
54        for item in self {
55            item.hash_canonical(state);
56        }
57    }
58}