heapless/linear_map.rs
1use crate::Vec;
2use core::{borrow::Borrow, fmt, iter::FromIterator, mem, ops, slice};
3
4/// A fixed capacity map / dictionary that performs lookups via linear search
5///
6/// Note that as this map doesn't use hashing so most operations are **O(N)** instead of O(1)
7
8pub struct LinearMap<K, V, const N: usize> {
9 pub(crate) buffer: Vec<(K, V), N>,
10}
11
12impl<K, V, const N: usize> LinearMap<K, V, N> {
13 /// Creates an empty `LinearMap`
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// use heapless::LinearMap;
19 ///
20 /// // allocate the map on the stack
21 /// let mut map: LinearMap<&str, isize, 8> = LinearMap::new();
22 ///
23 /// // allocate the map in a static variable
24 /// static mut MAP: LinearMap<&str, isize, 8> = LinearMap::new();
25 /// ```
26 pub const fn new() -> Self {
27 Self { buffer: Vec::new() }
28 }
29}
30
31impl<K, V, const N: usize> LinearMap<K, V, N>
32where
33 K: Eq,
34{
35 /// Returns the number of elements that the map can hold
36 ///
37 /// Computes in **O(1)** time
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// use heapless::LinearMap;
43 ///
44 /// let map: LinearMap<&str, isize, 8> = LinearMap::new();
45 /// assert_eq!(map.capacity(), 8);
46 /// ```
47 pub fn capacity(&self) -> usize {
48 N
49 }
50
51 /// Clears the map, removing all key-value pairs
52 ///
53 /// Computes in **O(1)** time
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use heapless::LinearMap;
59 ///
60 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
61 /// map.insert(1, "a").unwrap();
62 /// map.clear();
63 /// assert!(map.is_empty());
64 /// ```
65 pub fn clear(&mut self) {
66 self.buffer.clear()
67 }
68
69 /// Returns true if the map contains a value for the specified key.
70 ///
71 /// Computes in **O(N)** time
72 ///
73 /// # Examples
74 ///
75 /// ```
76 /// use heapless::LinearMap;
77 ///
78 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
79 /// map.insert(1, "a").unwrap();
80 /// assert_eq!(map.contains_key(&1), true);
81 /// assert_eq!(map.contains_key(&2), false);
82 /// ```
83 pub fn contains_key(&self, key: &K) -> bool {
84 self.get(key).is_some()
85 }
86
87 /// Returns a reference to the value corresponding to the key
88 ///
89 /// Computes in **O(N)** time
90 ///
91 /// # Examples
92 ///
93 /// ```
94 /// use heapless::LinearMap;
95 ///
96 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
97 /// map.insert(1, "a").unwrap();
98 /// assert_eq!(map.get(&1), Some(&"a"));
99 /// assert_eq!(map.get(&2), None);
100 /// ```
101 pub fn get<Q>(&self, key: &Q) -> Option<&V>
102 where
103 K: Borrow<Q>,
104 Q: Eq + ?Sized,
105 {
106 self.iter()
107 .find(|&(k, _)| k.borrow() == key)
108 .map(|(_, v)| v)
109 }
110
111 /// Returns a mutable reference to the value corresponding to the key
112 ///
113 /// Computes in **O(N)** time
114 ///
115 /// # Examples
116 ///
117 /// ```
118 /// use heapless::LinearMap;
119 ///
120 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
121 /// map.insert(1, "a").unwrap();
122 /// if let Some(x) = map.get_mut(&1) {
123 /// *x = "b";
124 /// }
125 /// assert_eq!(map[&1], "b");
126 /// ```
127 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
128 where
129 K: Borrow<Q>,
130 Q: Eq + ?Sized,
131 {
132 self.iter_mut()
133 .find(|&(k, _)| k.borrow() == key)
134 .map(|(_, v)| v)
135 }
136
137 /// Returns the number of elements in this map
138 ///
139 /// Computes in **O(1)** time
140 ///
141 /// # Examples
142 ///
143 /// ```
144 /// use heapless::LinearMap;
145 ///
146 /// let mut a: LinearMap<_, _, 8> = LinearMap::new();
147 /// assert_eq!(a.len(), 0);
148 /// a.insert(1, "a").unwrap();
149 /// assert_eq!(a.len(), 1);
150 /// ```
151 pub fn len(&self) -> usize {
152 self.buffer.len()
153 }
154
155 /// Inserts a key-value pair into the map.
156 ///
157 /// If the map did not have this key present, `None` is returned.
158 ///
159 /// If the map did have this key present, the value is updated, and the old value is returned.
160 ///
161 /// Computes in **O(N)** time
162 ///
163 /// # Examples
164 ///
165 /// ```
166 /// use heapless::LinearMap;
167 ///
168 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
169 /// assert_eq!(map.insert(37, "a").unwrap(), None);
170 /// assert_eq!(map.is_empty(), false);
171 ///
172 /// map.insert(37, "b").unwrap();
173 /// assert_eq!(map.insert(37, "c").unwrap(), Some("b"));
174 /// assert_eq!(map[&37], "c");
175 /// ```
176 pub fn insert(&mut self, key: K, mut value: V) -> Result<Option<V>, (K, V)> {
177 if let Some((_, v)) = self.iter_mut().find(|&(k, _)| *k == key) {
178 mem::swap(v, &mut value);
179 return Ok(Some(value));
180 }
181
182 self.buffer.push((key, value))?;
183 Ok(None)
184 }
185
186 /// Returns true if the map contains no elements
187 ///
188 /// Computes in **O(1)** time
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// use heapless::LinearMap;
194 ///
195 /// let mut a: LinearMap<_, _, 8> = LinearMap::new();
196 /// assert!(a.is_empty());
197 /// a.insert(1, "a").unwrap();
198 /// assert!(!a.is_empty());
199 /// ```
200 pub fn is_empty(&self) -> bool {
201 self.len() == 0
202 }
203
204 /// An iterator visiting all key-value pairs in arbitrary order.
205 ///
206 /// # Examples
207 ///
208 /// ```
209 /// use heapless::LinearMap;
210 ///
211 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
212 /// map.insert("a", 1).unwrap();
213 /// map.insert("b", 2).unwrap();
214 /// map.insert("c", 3).unwrap();
215 ///
216 /// for (key, val) in map.iter() {
217 /// println!("key: {} val: {}", key, val);
218 /// }
219 /// ```
220 pub fn iter(&self) -> Iter<'_, K, V> {
221 Iter {
222 iter: self.buffer.as_slice().iter(),
223 }
224 }
225
226 /// An iterator visiting all key-value pairs in arbitrary order, with mutable references to the
227 /// values
228 ///
229 /// # Examples
230 ///
231 /// ```
232 /// use heapless::LinearMap;
233 ///
234 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
235 /// map.insert("a", 1).unwrap();
236 /// map.insert("b", 2).unwrap();
237 /// map.insert("c", 3).unwrap();
238 ///
239 /// // Update all values
240 /// for (_, val) in map.iter_mut() {
241 /// *val = 2;
242 /// }
243 ///
244 /// for (key, val) in &map {
245 /// println!("key: {} val: {}", key, val);
246 /// }
247 /// ```
248 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
249 IterMut {
250 iter: self.buffer.as_mut_slice().iter_mut(),
251 }
252 }
253
254 /// An iterator visiting all keys in arbitrary order
255 ///
256 /// # Examples
257 ///
258 /// ```
259 /// use heapless::LinearMap;
260 ///
261 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
262 /// map.insert("a", 1).unwrap();
263 /// map.insert("b", 2).unwrap();
264 /// map.insert("c", 3).unwrap();
265 ///
266 /// for key in map.keys() {
267 /// println!("{}", key);
268 /// }
269 /// ```
270 pub fn keys(&self) -> impl Iterator<Item = &K> {
271 self.iter().map(|(k, _)| k)
272 }
273
274 /// Removes a key from the map, returning the value at the key if the key was previously in the
275 /// map
276 ///
277 /// Computes in **O(N)** time
278 ///
279 /// # Examples
280 ///
281 /// ```
282 /// use heapless::LinearMap;
283 ///
284 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
285 /// map.insert(1, "a").unwrap();
286 /// assert_eq!(map.remove(&1), Some("a"));
287 /// assert_eq!(map.remove(&1), None);
288 /// ```
289 pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
290 where
291 K: Borrow<Q>,
292 Q: Eq + ?Sized,
293 {
294 let idx = self
295 .keys()
296 .enumerate()
297 .find(|&(_, k)| k.borrow() == key)
298 .map(|(idx, _)| idx);
299
300 idx.map(|idx| self.buffer.swap_remove(idx).1)
301 }
302
303 /// An iterator visiting all values in arbitrary order
304 ///
305 /// # Examples
306 ///
307 /// ```
308 /// use heapless::LinearMap;
309 ///
310 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
311 /// map.insert("a", 1).unwrap();
312 /// map.insert("b", 2).unwrap();
313 /// map.insert("c", 3).unwrap();
314 ///
315 /// for val in map.values() {
316 /// println!("{}", val);
317 /// }
318 /// ```
319 pub fn values(&self) -> impl Iterator<Item = &V> {
320 self.iter().map(|(_, v)| v)
321 }
322
323 /// An iterator visiting all values mutably in arbitrary order
324 ///
325 /// # Examples
326 ///
327 /// ```
328 /// use heapless::LinearMap;
329 ///
330 /// let mut map: LinearMap<_, _, 8> = LinearMap::new();
331 /// map.insert("a", 1).unwrap();
332 /// map.insert("b", 2).unwrap();
333 /// map.insert("c", 3).unwrap();
334 ///
335 /// for val in map.values_mut() {
336 /// *val += 10;
337 /// }
338 ///
339 /// for val in map.values() {
340 /// println!("{}", val);
341 /// }
342 /// ```
343 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
344 self.iter_mut().map(|(_, v)| v)
345 }
346}
347
348impl<'a, K, V, Q, const N: usize> ops::Index<&'a Q> for LinearMap<K, V, N>
349where
350 K: Borrow<Q> + Eq,
351 Q: Eq + ?Sized,
352{
353 type Output = V;
354
355 fn index(&self, key: &Q) -> &V {
356 self.get(key).expect("no entry found for key")
357 }
358}
359
360impl<'a, K, V, Q, const N: usize> ops::IndexMut<&'a Q> for LinearMap<K, V, N>
361where
362 K: Borrow<Q> + Eq,
363 Q: Eq + ?Sized,
364{
365 fn index_mut(&mut self, key: &Q) -> &mut V {
366 self.get_mut(key).expect("no entry found for key")
367 }
368}
369
370impl<K, V, const N: usize> Default for LinearMap<K, V, N>
371where
372 K: Eq,
373{
374 fn default() -> Self {
375 Self::new()
376 }
377}
378
379impl<K, V, const N: usize> Clone for LinearMap<K, V, N>
380where
381 K: Eq + Clone,
382 V: Clone,
383{
384 fn clone(&self) -> Self {
385 Self {
386 buffer: self.buffer.clone(),
387 }
388 }
389}
390
391impl<K, V, const N: usize> fmt::Debug for LinearMap<K, V, N>
392where
393 K: Eq + fmt::Debug,
394 V: fmt::Debug,
395{
396 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
397 f.debug_map().entries(self.iter()).finish()
398 }
399}
400
401impl<K, V, const N: usize> FromIterator<(K, V)> for LinearMap<K, V, N>
402where
403 K: Eq,
404{
405 fn from_iter<I>(iter: I) -> Self
406 where
407 I: IntoIterator<Item = (K, V)>,
408 {
409 let mut out = Self::new();
410 out.buffer.extend(iter);
411 out
412 }
413}
414
415pub struct IntoIter<K, V, const N: usize>
416where
417 K: Eq,
418{
419 inner: <Vec<(K, V), N> as IntoIterator>::IntoIter,
420}
421
422impl<K, V, const N: usize> Iterator for IntoIter<K, V, N>
423where
424 K: Eq,
425{
426 type Item = (K, V);
427 fn next(&mut self) -> Option<Self::Item> {
428 self.inner.next()
429 }
430}
431
432impl<'a, K, V, const N: usize> IntoIterator for &'a LinearMap<K, V, N>
433where
434 K: Eq,
435{
436 type Item = (&'a K, &'a V);
437 type IntoIter = Iter<'a, K, V>;
438
439 fn into_iter(self) -> Self::IntoIter {
440 self.iter()
441 }
442}
443
444pub struct Iter<'a, K, V> {
445 iter: slice::Iter<'a, (K, V)>,
446}
447
448impl<'a, K, V> Iterator for Iter<'a, K, V> {
449 type Item = (&'a K, &'a V);
450
451 fn next(&mut self) -> Option<Self::Item> {
452 self.iter.next().map(|&(ref k, ref v)| (k, v))
453 }
454}
455
456impl<'a, K, V> Clone for Iter<'a, K, V> {
457 fn clone(&self) -> Self {
458 Self {
459 iter: self.iter.clone(),
460 }
461 }
462}
463
464pub struct IterMut<'a, K, V> {
465 iter: slice::IterMut<'a, (K, V)>,
466}
467
468impl<'a, K, V> Iterator for IterMut<'a, K, V> {
469 type Item = (&'a K, &'a mut V);
470
471 fn next(&mut self) -> Option<Self::Item> {
472 self.iter.next().map(|&mut (ref k, ref mut v)| (k, v))
473 }
474}
475
476impl<K, V, const N: usize, const N2: usize> PartialEq<LinearMap<K, V, N2>> for LinearMap<K, V, N>
477where
478 K: Eq,
479 V: PartialEq,
480{
481 fn eq(&self, other: &LinearMap<K, V, N2>) -> bool {
482 self.len() == other.len()
483 && self
484 .iter()
485 .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v))
486 }
487}
488
489impl<K, V, const N: usize> Eq for LinearMap<K, V, N>
490where
491 K: Eq,
492 V: PartialEq,
493{
494}
495
496#[cfg(test)]
497mod test {
498 use crate::LinearMap;
499
500 #[test]
501 fn static_new() {
502 static mut _L: LinearMap<i32, i32, 8> = LinearMap::new();
503 }
504
505 #[test]
506 fn partial_eq() {
507 {
508 let mut a = LinearMap::<_, _, 1>::new();
509 a.insert("k1", "v1").unwrap();
510
511 let mut b = LinearMap::<_, _, 2>::new();
512 b.insert("k1", "v1").unwrap();
513
514 assert!(a == b);
515
516 b.insert("k2", "v2").unwrap();
517
518 assert!(a != b);
519 }
520
521 {
522 let mut a = LinearMap::<_, _, 2>::new();
523 a.insert("k1", "v1").unwrap();
524 a.insert("k2", "v2").unwrap();
525
526 let mut b = LinearMap::<_, _, 2>::new();
527 b.insert("k2", "v2").unwrap();
528 b.insert("k1", "v1").unwrap();
529
530 assert!(a == b);
531 }
532 }
533
534 #[test]
535 fn drop() {
536 droppable!();
537
538 {
539 let mut v: LinearMap<i32, Droppable, 2> = LinearMap::new();
540 v.insert(0, Droppable::new()).ok().unwrap();
541 v.insert(1, Droppable::new()).ok().unwrap();
542 v.remove(&1).unwrap();
543 }
544
545 assert_eq!(Droppable::count(), 0);
546
547 {
548 let mut v: LinearMap<i32, Droppable, 2> = LinearMap::new();
549 v.insert(0, Droppable::new()).ok().unwrap();
550 v.insert(1, Droppable::new()).ok().unwrap();
551 }
552
553 assert_eq!(Droppable::count(), 0);
554 }
555}