linear_collections/vec/
map.rs

1use crate::{AsMutSlice, LinearMap};
2
3///A map type backed by a Vector. Useful for small collections whose size can change.
4#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
5pub struct VecMap<K: Eq, V: Sized + PartialEq> {
6    vector: Vec<(K, V)>,
7}
8impl<K: Eq, V: Sized + PartialEq> VecMap<K, V> {
9    ///Creates a new, empty VecMap.
10    ///Calls Vec::new() internally.
11    pub fn new() -> VecMap<K, V> {
12        VecMap { vector: Vec::new() }
13    }
14
15    ///**Please only use this method to create map literals if the "macros" feature is unavailable to you**
16    ///"macros" provides safe, checked alternatives to initialize linear maps with compile time checking
17    ///of the invariants of each type.
18    ///
19    ///Creates a new VecMap from the supplied vector.
20    ///
21    ///SAFETY: improper use of this method - initializing with duplicate keys - will NOT create memory unsafety, but will result in every
22    ///identical key beyond the first never getting accessed as LinearMaps short circuit on the first matching key.
23    pub const unsafe fn from_vec_unchecked(vector: Vec<(K, V)>) -> VecMap<K, V> {
24        VecMap { vector }
25    }
26
27    ///Returns the number of elements in the container
28    pub fn len(&self) -> usize {
29        self.vector.len()
30    }
31
32    ///Returns true if the store is empty, false otherwise.
33    pub fn is_empty(&self) -> bool {
34        self.len() == 0
35    }
36
37    ///Creates a new, empty VecMap with capacity set to the provide value.
38    ///Calls Vec::with_capacity() internally.
39    pub fn with_capacity(capacity: usize) -> VecMap<K, V> {
40        VecMap {
41            vector: Vec::with_capacity(capacity),
42        }
43    }
44    ///Tries to remove the value associated with the given key, returning None if it is not found.
45    pub fn remove(&mut self, key: &K) -> Option<V> {
46        self.remove_entry(key).map(|(_, v)| v)
47    }
48
49    ///Tries to remove the entry associated with the given key, returning None if it is not found.
50    pub fn remove_entry(&mut self, key: &K) -> Option<(K, V)> {
51        let idx = self
52            .vector
53            .iter()
54            .enumerate()
55            .find(|(_, (k, _))| k == key)
56            .map(|(i, _)| i)?;
57
58        Some(self.vector.remove(idx))
59    }
60
61    ///Inserts the provided value into the VecMap. If the provided key is
62    ///found it will update the value. and return the old value. If not, this will allocate for a new key value pair.    
63    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
64        match self.vector.iter_mut().find(|(k, _)| *k == key) {
65            Some((_, v)) => Some(std::mem::replace(v, value)),
66            None => {
67                self.vector.push((key, value));
68                None
69            }
70        }
71    }
72}
73
74impl<K: Eq, V: Sized + PartialEq> LinearMap<K, V> for VecMap<K, V> {
75    type Backing = Vec<(K, V)>;
76    fn as_slice(&self) -> &[(K, V)] {
77        self.vector.as_slice()
78    }
79
80    fn into_inner(self) -> Self::Backing {
81        self.vector
82    }
83}
84
85impl<K: Eq, V: Sized + PartialEq> AsMutSlice<K, V> for VecMap<K, V> {
86    fn as_mut_slice(&mut self) -> &mut [(K, V)] {
87        self.vector.as_mut_slice()
88    }
89}