surrealdb_types/
hashmap.rs1use std::collections::hash_map::RandomState;
30use std::{cmp, hash};
31
32use papaya::Equivalent;
33
34#[derive(Debug, Clone, Default)]
46pub struct HashMap<K, V, S = RandomState>(papaya::HashMap<K, V, S>)
47where
48 K: hash::Hash + cmp::Eq,
49 V: Clone,
50 S: hash::BuildHasher + Default;
51
52impl<K, V, S> HashMap<K, V, S>
53where
54 K: hash::Hash + cmp::Eq,
55 V: Clone,
56 S: hash::BuildHasher + Default,
57{
58 pub fn new() -> Self {
60 Self(Default::default())
61 }
62
63 pub fn insert(&self, key: K, value: V) {
67 self.0.pin().insert(key, value);
68 }
69
70 pub fn get<Q>(&self, key: &Q) -> Option<V>
74 where
75 Q: Equivalent<K> + hash::Hash + ?Sized,
76 {
77 self.0.pin().get(key).cloned()
78 }
79
80 pub fn contains_key<Q>(&self, key: &Q) -> bool
82 where
83 Q: Equivalent<K> + hash::Hash + ?Sized,
84 {
85 self.0.pin().contains_key(key)
86 }
87
88 pub fn values(&self) -> Vec<V> {
90 self.0.pin().values().cloned().collect()
91 }
92
93 pub fn to_vec(&self) -> Vec<(K, V)>
95 where
96 K: Clone,
97 {
98 let map = self.0.pin();
99 let mut vec = Vec::with_capacity(map.len());
100 for (k, v) in map.iter() {
101 vec.push((k.clone(), v.clone()));
102 }
103 vec
104 }
105
106 pub fn remove<Q>(&self, key: &Q)
112 where
113 Q: Equivalent<K> + hash::Hash + ?Sized,
114 {
115 self.0.pin().remove(key);
116 }
117
118 pub fn take<Q>(&self, key: &Q) -> Option<V>
120 where
121 Q: Equivalent<K> + hash::Hash + ?Sized,
122 {
123 self.0.pin().remove(key).cloned()
124 }
125
126 pub fn clear(&self) {
128 self.0.pin().clear();
129 }
130
131 pub fn len(&self) -> usize {
133 self.0.pin().len()
134 }
135
136 pub fn is_empty(&self) -> bool {
138 self.0.pin().is_empty()
139 }
140
141 pub fn retain<F>(&self, f: F)
145 where
146 F: FnMut(&K, &V) -> bool,
147 {
148 self.0.pin().retain(f);
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 #[test]
157 fn test_basic_operations() {
158 let map: HashMap<String, i32> = HashMap::new();
159
160 map.insert("key1".to_string(), 1);
162 map.insert("key2".to_string(), 2);
163
164 assert_eq!(map.get(&"key1".to_string()), Some(1));
165 assert_eq!(map.get(&"key2".to_string()), Some(2));
166 assert_eq!(map.get(&"key3".to_string()), None);
167
168 assert!(map.contains_key(&"key1".to_string()));
170 assert!(!map.contains_key(&"key3".to_string()));
171
172 assert_eq!(map.len(), 2);
174 assert!(!map.is_empty());
175
176 map.remove(&"key1".to_string());
178 assert_eq!(map.get(&"key1".to_string()), None);
179 assert_eq!(map.len(), 1);
180
181 map.clear();
183 assert!(map.is_empty());
184 }
185
186 #[test]
187 fn test_values_and_to_vec() {
188 let map: HashMap<String, i32> = HashMap::new();
189 map.insert("a".to_string(), 1);
190 map.insert("b".to_string(), 2);
191 map.insert("c".to_string(), 3);
192
193 let values = map.values();
194 assert_eq!(values.len(), 3);
195
196 let vec = map.to_vec();
197 assert_eq!(vec.len(), 3);
198 }
199
200 #[test]
201 fn test_retain() {
202 let map: HashMap<String, i32> = HashMap::new();
203 map.insert("a".to_string(), 1);
204 map.insert("b".to_string(), 2);
205 map.insert("c".to_string(), 3);
206 map.insert("d".to_string(), 4);
207
208 map.retain(|_, v| *v % 2 == 0);
210
211 assert_eq!(map.len(), 2);
212 assert!(map.contains_key(&"b".to_string()));
213 assert!(map.contains_key(&"d".to_string()));
214 assert!(!map.contains_key(&"a".to_string()));
215 assert!(!map.contains_key(&"c".to_string()));
216 }
217
218 #[test]
219 fn test_clone() {
220 let map: HashMap<String, i32> = HashMap::new();
221 map.insert("key".to_string(), 42);
222
223 let cloned = map.clone();
224 assert_eq!(cloned.get(&"key".to_string()), Some(42));
225
226 cloned.insert("key".to_string(), 100);
228 assert_eq!(map.get(&"key".to_string()), Some(42));
229 assert_eq!(cloned.get(&"key".to_string()), Some(100));
230 }
231}