1#![cfg(feature = "ordered")]
2use std::borrow::Borrow;
10use std::hash::Hash;
11
12use heapless::LinearMap;
13
14#[derive(Debug, Clone)]
46pub struct HeaplessOrderedMap<K: Eq + Hash, V, const N: usize> {
47 map: LinearMap<K, V, N>,
48}
49
50impl<K: Eq + Hash, V, const N: usize> HeaplessOrderedMap<K, V, N> {
51 pub fn new() -> Self {
53 const {
54 assert!(
55 std::mem::size_of::<Self>() <= 16 * 1024,
56 "HeaplessOrderedMap is too large! The struct size exceeds the 16KB limit. Reduce N."
57 );
58 }
59 Self {
60 map: LinearMap::new(),
61 }
62 }
63
64 pub fn len(&self) -> usize {
66 self.map.len()
67 }
68
69 pub fn is_empty(&self) -> bool {
71 self.map.is_empty()
72 }
73
74 pub fn is_full(&self) -> bool {
78 self.map.len() == N
79 }
80
81 pub fn clear(&mut self) {
83 self.map.clear();
84 }
85
86 pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>, (K, V)> {
98 if self.map.len() == N && !self.map.contains_key(&key) {
99 return Err((key, value));
100 }
101 Ok(self.map.insert(key, value).ok().flatten())
102 }
103
104 pub fn get<Q>(&self, key: &Q) -> Option<&V>
109 where
110 K: Borrow<Q>,
111 Q: Hash + Eq + ?Sized,
112 {
113 self.map
114 .iter()
115 .find(|&(k, _)| <K as Borrow<Q>>::borrow(k) == key)
116 .map(|(_, v)| v)
117 }
118
119 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
124 where
125 K: Borrow<Q>,
126 Q: Hash + Eq + ?Sized,
127 {
128 self.map
129 .iter_mut()
130 .find(|(k, _)| <K as Borrow<Q>>::borrow(k) == key)
131 .map(|(_, v)| v)
132 }
133
134 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
144 where
145 K: Borrow<Q>,
146 Q: Hash + Eq + ?Sized,
147 {
148 let mut temp: LinearMap<K, V, N> = LinearMap::new();
151 let mut removed = None;
152
153 let old = core::mem::replace(&mut self.map, LinearMap::new());
154 for (k, v) in old.into_iter() {
155 if k.borrow() == key && removed.is_none() {
156 removed = Some(v);
157 } else {
158 let _ = temp.insert(k, v);
159 }
160 }
161 self.map = temp;
162 removed
163 }
164
165 pub fn contains_key<Q>(&self, key: &Q) -> bool
170 where
171 K: Borrow<Q>,
172 Q: Hash + Eq + ?Sized,
173 {
174 self.get(key).is_some()
175 }
176
177 pub fn iter(&self) -> heapless::linear_map::Iter<'_, K, V> {
179 self.map.iter()
180 }
181
182 pub fn into_inner(self) -> LinearMap<K, V, N> {
186 self.map
187 }
188}
189
190impl<K, V, const N: usize> PartialEq for HeaplessOrderedMap<K, V, N>
191where
192 K: Eq + Hash,
193 V: PartialEq,
194{
195 fn eq(&self, other: &Self) -> bool {
196 if self.len() != other.len() {
197 return false;
198 }
199 self.iter().all(|(k, v)| other.get(k) == Some(v))
200 }
201}
202
203impl<K, V, const N: usize> Eq for HeaplessOrderedMap<K, V, N>
204where
205 K: Eq + Hash,
206 V: Eq,
207{
208}
209
210impl<K: Eq + Hash, V, const N: usize> Default for HeaplessOrderedMap<K, V, N> {
211 fn default() -> Self {
213 Self::new()
214 }
215}
216
217impl<K: Eq + Hash, V, const N: usize> IntoIterator for HeaplessOrderedMap<K, V, N> {
218 type Item = (K, V);
219 type IntoIter = heapless::linear_map::IntoIter<K, V, N>;
220
221 fn into_iter(self) -> Self::IntoIter {
223 self.map.into_iter()
224 }
225}
226
227#[cfg(test)]
228mod tests {
229 use super::*;
230
231 #[test]
232 fn test_heapless_ordered_map_stack_ops_insertion_order() {
233 let mut map: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
234 map.insert(3, 30).unwrap();
235 map.insert(1, 10).unwrap();
236 map.insert(2, 20).unwrap();
237
238 let keys: Vec<_> = map.iter().map(|(k, _)| *k).collect();
239 assert_eq!(keys, vec![3, 1, 2]);
240 }
241
242 #[test]
243 fn test_heapless_ordered_map_stack_ops_update() {
244 let mut map: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
245 assert_eq!(map.insert(1, 10), Ok(None));
246 assert_eq!(map.insert(1, 20), Ok(Some(10)));
247 assert_eq!(map.get(&1), Some(&20));
248 }
249
250 #[test]
251 fn test_heapless_ordered_map_stack_ops_remove() {
252 let mut map: HeaplessOrderedMap<String, i32, 4> = HeaplessOrderedMap::new();
253 map.insert("a".into(), 1).unwrap();
254 map.insert("b".into(), 2).unwrap();
255 assert_eq!(map.remove("a"), Some(1));
256 assert_eq!(map.len(), 1);
257 assert_eq!(map.get("b"), Some(&2));
258 }
259
260 #[test]
261 fn test_heapless_ordered_map_stack_ops_full_returns_err() {
262 let mut map: HeaplessOrderedMap<i32, i32, 2> = HeaplessOrderedMap::new();
263 map.insert(1, 10).unwrap();
264 map.insert(2, 20).unwrap();
265 assert!(map.is_full());
266 assert_eq!(map.insert(3, 30), Err((3, 30)));
267 }
268
269 #[test]
270 fn test_heapless_ordered_map_stack_ops_get_mut() {
271 let mut map: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
272 map.insert(1, 10).unwrap();
273 if let Some(v) = map.get_mut(&1) {
274 *v = 42;
275 }
276 assert_eq!(map.get(&1), Some(&42));
277 }
278
279 #[test]
280 fn test_heapless_ordered_map_stack_ops_contains_key() {
281 let mut map: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
282 map.insert(1, 10).unwrap();
283 assert!(map.contains_key(&1));
284 assert!(!map.contains_key(&2));
285 }
286
287 #[test]
288 fn test_heapless_ordered_map_traits_clone_default() {
289 let map1: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::default();
290 let mut map2 = map1.clone();
291 map2.insert(7, 70).unwrap();
292 assert_eq!(map1.len(), 0);
293 assert_eq!(map2.len(), 1);
294 }
295
296 #[test]
297 fn test_heapless_ordered_map_stack_ops_borrow_lookup() {
298 let mut map: HeaplessOrderedMap<String, i32, 4> = HeaplessOrderedMap::new();
299 map.insert("Apple".to_string(), 100).unwrap();
300 assert_eq!(map.get("Apple"), Some(&100));
301 assert_eq!(map.get_mut("Apple"), Some(&mut 100));
302 }
303}
304
305#[cfg(test)]
306mod heapless_ordered_map_coverage_tests {
307 use super::*;
308
309 #[test]
310 fn test_is_empty_false() {
311 let mut map: HeaplessOrderedMap<i32, i32, 2> = HeaplessOrderedMap::new();
312 map.insert(1, 10).unwrap();
313 assert!(!map.is_empty());
314 }
315
316 #[test]
317 fn test_get_get_mut_missing() {
318 let mut map: HeaplessOrderedMap<i32, i32, 2> = HeaplessOrderedMap::new();
319 map.insert(1, 10).unwrap();
320
321 assert_eq!(map.get(&2), None);
322 assert_eq!(map.get_mut(&2), None);
323 }
324
325 #[test]
326 fn test_into_inner() {
327 let mut map: HeaplessOrderedMap<i32, i32, 2> = HeaplessOrderedMap::new();
328 map.insert(1, 10).unwrap();
329 let inner = map.into_inner();
330 assert_eq!(inner.len(), 1);
331 assert_eq!(inner.get(&1), Some(&10));
332 }
333
334 #[test]
335 fn test_partial_eq_variants() {
336 let mut m1: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
337 m1.insert(1, 10).unwrap();
338
339 let mut m2: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
340 m2.insert(1, 10).unwrap();
341
342 let mut m3: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
343 m3.insert(1, 10).unwrap();
344 m3.insert(2, 20).unwrap();
345
346 let mut m4: HeaplessOrderedMap<i32, i32, 4> = HeaplessOrderedMap::new();
347 m4.insert(1, 99).unwrap();
348
349 assert_eq!(m1, m2);
350 assert_ne!(m1, m3); assert_ne!(m1, m4); }
353}