esl_compiler/
map.rs

1use std::collections::btree_map::Entry;
2use std::collections::BTreeMap;
3
4/// An insert-only mapping where the data is stored in an internal vector.
5#[derive(Clone, Debug, PartialEq)]
6pub struct Map<K: Ord, V> {
7    /// Values vector containing the actual values.
8    pub values: Vec<V>,
9    /// Map of keys to positions in the values vector.
10    pub map: BTreeMap<K, usize>,
11}
12impl<K: Ord, V> Map<K, V> {
13    /// Insert a new value into the map, returning the attempted value as an error if it was already
14    /// occupied.
15    pub fn insert(&mut self, key: K, value: V) -> Result<usize, V> {
16        if let Entry::Vacant(e) = self.map.entry(key) {
17            let index = self.values.len();
18            self.values.push(value);
19            e.insert(index);
20            Ok(index)
21        } else {
22            Err(value)
23        }
24    }
25    /// Get a reference to an entry.
26    pub fn get(&self, key: &K) -> Option<&V> {
27        let index = *self.map.get(key)?;
28        self.values.get(index)
29    }
30    /// Get a mutable reference to an entry.
31    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
32        let index = *self.map.get(key)?;
33        self.values.get_mut(index)
34    }
35}
36impl<K: Ord, V> Default for Map<K, V> {
37    fn default() -> Self {
38        Self {
39            values: vec![],
40            map: BTreeMap::new(),
41        }
42    }
43}