fts_core/models/
map.rs

1use std::hash::Hash;
2
3/// A wrapper around an implementation of a HashMap, defaulting to values of f64.
4///
5/// Predictable and consistent ordering is important to ensure identical solutions
6/// from repeated solves, so we replace the std::collections::HashMap with
7/// indexmap::IndexMap. However, this is an implementation detail, so we wrap it
8/// in a newtype, allowing us to replace it at a future date without breaking
9/// semver. This unfortunately leads to additional boiler-plate, but at least it
10/// is not particularly complicated.
11#[derive(Debug, Clone, PartialEq)]
12#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
13#[cfg_attr(
14    feature = "serde",
15    derive(serde::Serialize, serde::Deserialize),
16    serde(transparent)
17)]
18pub struct Map<K: Eq + Hash, V = f64>(indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>);
19
20impl<K: Eq + Hash, V> Default for Map<K, V> {
21    fn default() -> Self {
22        Self(indexmap::IndexMap::default())
23    }
24}
25
26impl<K: Eq + Hash, V> std::ops::Deref for Map<K, V> {
27    type Target = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
28
29    fn deref(&self) -> &Self::Target {
30        &self.0
31    }
32}
33
34impl<K: Eq + Hash, V> std::ops::DerefMut for Map<K, V> {
35    fn deref_mut(&mut self) -> &mut Self::Target {
36        &mut self.0
37    }
38}
39
40impl<K: Eq + Hash, V> IntoIterator for Map<K, V> {
41    type Item = (K, V);
42    type IntoIter = indexmap::map::IntoIter<K, V>;
43
44    fn into_iter(self) -> Self::IntoIter {
45        self.0.into_iter()
46    }
47}
48
49impl<K: Eq + Hash, V> FromIterator<(K, V)> for Map<K, V> {
50    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
51        Self(indexmap::IndexMap::from_iter(iter))
52    }
53}