parry3d/utils/
hashset.rs

1//! A hash-map that behaves deterministically when the
2//! `enhanced-determinism` feature is enabled.
3
4#[cfg(all(feature = "enhanced-determinism", feature = "serde-serialize"))]
5use indexmap::IndexSet as StdHashSet;
6#[cfg(all(not(feature = "enhanced-determinism"), feature = "serde-serialize"))]
7use std::collections::HashSet as StdHashSet;
8
9/// Serializes only the capacity of a hash-set instead of its actual content.
10#[cfg(feature = "serde-serialize")]
11pub fn serialize_hashset_capacity<S: serde::Serializer, K, H: core::hash::BuildHasher>(
12    set: &StdHashSet<K, H>,
13    s: S,
14) -> Result<S::Ok, S::Error> {
15    s.serialize_u64(set.capacity() as u64)
16}
17
18/// Creates a new hash-set with its capacity deserialized from `d`.
19#[cfg(feature = "serde-serialize")]
20pub fn deserialize_hashset_capacity<
21    'de,
22    D: serde::Deserializer<'de>,
23    K,
24    V,
25    H: core::hash::BuildHasher + Default,
26>(
27    d: D,
28) -> Result<StdHashSet<K, H>, D::Error> {
29    struct CapacityVisitor;
30    impl serde::de::Visitor<'_> for CapacityVisitor {
31        type Value = u64;
32
33        fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
34            write!(formatter, "an integer between 0 and 2^64")
35        }
36
37        fn visit_u64<E: serde::de::Error>(self, val: u64) -> Result<Self::Value, E> {
38            Ok(val)
39        }
40    }
41
42    let capacity = d.deserialize_u64(CapacityVisitor)? as usize;
43    Ok(StdHashSet::with_capacity_and_hasher(
44        capacity,
45        Default::default(),
46    ))
47}
48
49/// Deterministic hashset using [`indexmap::IndexSet`]
50#[cfg(feature = "enhanced-determinism")]
51pub type FxHashSet32<K> =
52    indexmap::IndexSet<K, core::hash::BuildHasherDefault<super::fx_hasher::FxHasher32>>;
53#[cfg(feature = "enhanced-determinism")]
54pub use self::FxHashSet32 as HashSet;
55
56#[cfg(not(feature = "enhanced-determinism"))]
57pub use hashbrown::hash_set::Entry;
58/// Hashset using [`hashbrown::HashSet`]
59#[cfg(not(feature = "enhanced-determinism"))]
60pub type HashSet<K> = hashbrown::hash_set::HashSet<K, hashbrown::DefaultHashBuilder>;