nautilus_core/
collections.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Abstraction layer over common hash-based containers.
17
18use std::{
19    collections::{HashMap, HashSet},
20    fmt::{Debug, Display},
21    hash::Hash,
22};
23
24/// Represents a generic set-like container with members.
25pub trait SetLike {
26    /// The type of items stored in the set.
27    type Item: Hash + Eq + Display + Clone;
28
29    /// Returns `true` if the set contains the specified item.
30    fn contains(&self, item: &Self::Item) -> bool;
31    /// Returns `true` if the set is empty.
32    fn is_empty(&self) -> bool;
33}
34
35impl<T, S> SetLike for HashSet<T, S>
36where
37    T: Eq + Hash + Display + Clone,
38    S: std::hash::BuildHasher,
39{
40    type Item = T;
41
42    #[inline]
43    fn contains(&self, v: &T) -> bool {
44        Self::contains(self, v)
45    }
46
47    #[inline]
48    fn is_empty(&self) -> bool {
49        Self::is_empty(self)
50    }
51}
52
53impl<T, S> SetLike for indexmap::IndexSet<T, S>
54where
55    T: Eq + Hash + Display + Clone,
56    S: std::hash::BuildHasher,
57{
58    type Item = T;
59
60    #[inline]
61    fn contains(&self, v: &T) -> bool {
62        Self::contains(self, v)
63    }
64
65    #[inline]
66    fn is_empty(&self) -> bool {
67        Self::is_empty(self)
68    }
69}
70
71impl<T, S> SetLike for ahash::AHashSet<T, S>
72where
73    T: Eq + Hash + Display + Clone,
74    S: std::hash::BuildHasher,
75{
76    type Item = T;
77
78    #[inline]
79    fn contains(&self, v: &T) -> bool {
80        self.get(v).is_some()
81    }
82
83    #[inline]
84    fn is_empty(&self) -> bool {
85        self.len() == 0
86    }
87}
88
89/// Represents a generic map-like container with key-value pairs.
90pub trait MapLike {
91    /// The type of keys stored in the map.
92    type Key: Hash + Eq + Display + Clone;
93    /// The type of values stored in the map.
94    type Value: Debug;
95
96    /// Returns `true` if the map contains the specified key.
97    fn contains_key(&self, key: &Self::Key) -> bool;
98    /// Returns `true` if the map is empty.
99    fn is_empty(&self) -> bool;
100}
101
102impl<K, V, S> MapLike for HashMap<K, V, S>
103where
104    K: Eq + Hash + Display + Clone,
105    V: Debug,
106    S: std::hash::BuildHasher,
107{
108    type Key = K;
109    type Value = V;
110
111    #[inline]
112    fn contains_key(&self, k: &K) -> bool {
113        self.contains_key(k)
114    }
115
116    #[inline]
117    fn is_empty(&self) -> bool {
118        self.is_empty()
119    }
120}
121
122impl<K, V, S> MapLike for indexmap::IndexMap<K, V, S>
123where
124    K: Eq + Hash + Display + Clone,
125    V: Debug,
126    S: std::hash::BuildHasher,
127{
128    type Key = K;
129    type Value = V;
130
131    #[inline]
132    fn contains_key(&self, k: &K) -> bool {
133        self.get(k).is_some()
134    }
135
136    #[inline]
137    fn is_empty(&self) -> bool {
138        self.is_empty()
139    }
140}
141
142impl<K, V, S> MapLike for ahash::AHashMap<K, V, S>
143where
144    K: Eq + Hash + Display + Clone,
145    V: Debug,
146    S: std::hash::BuildHasher,
147{
148    type Key = K;
149    type Value = V;
150
151    #[inline]
152    fn contains_key(&self, k: &K) -> bool {
153        self.get(k).is_some()
154    }
155
156    #[inline]
157    fn is_empty(&self) -> bool {
158        self.len() == 0
159    }
160}