syntax_parser_generator/handles/collections/
handle_map.rs

1use std::fmt::{Debug, Formatter};
2use std::marker::PhantomData;
3
4use derive_where::derive_where;
5
6use crate::handles::{Handle, Handled};
7
8/// An efficient implementation of a mapping between handles and arbitrary data.
9///
10/// This collection implements the classic "map" data-structure functionality, in the special case
11/// in which the keys are actually instances of [Handle]. This restriction enables this more
12/// efficient implementation of a map.
13///
14/// # Type Arguments
15///
16/// * `T`: The [Handled] type whose handles are used to index into the map.
17/// * `U`: The type of the target values being mapped.
18///
19/// # Example
20/// ```rust
21/// # use syntax_parser_generator::handles::{Handle, Handled};
22/// # use syntax_parser_generator::handles::collections::{HandledVec, HandleMap};
23/// struct LinkedListNode { next: Option<Handle<LinkedListNode>> }
24/// impl Handled for LinkedListNode { type HandleCoreType = u8; }
25///
26/// let mut nodes = HandledVec::new();
27/// let tail_handle = nodes.insert(LinkedListNode { next: None });
28/// let head_handle = nodes.insert(LinkedListNode { next: Some(tail_handle) });
29///
30/// let mut metadata = HandleMap::new();
31/// metadata.insert(head_handle, "Head Node");
32/// metadata.insert(tail_handle, "Tail Node");
33///
34/// assert_eq!(metadata.get(tail_handle), Some("Tail Node").as_ref());
35/// ```
36// TODO "complete map", where everything is known (no "Option<U>", just U). Why? to half tne space
37#[derive_where(PartialEq, Eq, Clone; U)]
38pub struct HandleMap<T, U>
39where
40    T: Handled + ?Sized,
41{
42    contents: Vec<Option<U>>,
43    phantom_data: PhantomData<Handle<T>>,
44}
45
46impl<T, U> HandleMap<T, U>
47where
48    T: Handled + ?Sized,
49{
50    /// Create a new, empty, map.
51    pub fn new() -> Self {
52        Vec::new().into()
53    }
54
55    /// Insert a key-value pair to the map.
56    pub fn insert(&mut self, key: Handle<T>, item: U) -> bool {
57        let result = self.get(key).is_none();
58        if key.index() >= self.contents.len() {
59            self.contents.resize_with(key.index() + 1, || None);
60        }
61        self.contents[key.index()] = Some(item);
62        result
63    }
64
65    /// Get a reference to the value mapped to a given key, or [None] if the key is not present.
66    pub fn get(&self, key: Handle<T>) -> Option<&U> {
67        self.contents.get(key.index())?.as_ref()
68    }
69
70    /// Get a mutable reference to the value mapped to a given key, or [None] if the key was never
71    /// inserted.
72    pub fn get_mut(&mut self, key: Handle<T>) -> Option<&mut U> {
73        self.contents.get_mut(key.index())?.as_mut()
74    }
75
76    /// Check whether a given key is present in the map.
77    pub fn contains_key(&self, key: Handle<T>) -> bool {
78        !self.get(key).is_none()
79    }
80
81    /// Get an iterator of references to the values held in the maps, and their corresponding keys.
82    pub fn iter(&self) -> impl Iterator<Item=(Handle<T>, &U)> {
83        (&self).into_iter()
84    }
85
86    /// Get an iterator over the available keys in the map.
87    pub fn keys<'a>(&'a self) -> impl Iterator<Item=Handle<T>> + 'a {
88        self.iter().map(|(key, _)| key)
89    }
90}
91
92impl<T, U> Debug for HandleMap<T, U>
93where
94    T: Handled,
95    U: Debug,
96{
97    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
98        self.iter().collect::<Vec<(Handle<T>, &U)>>().fmt(f)
99    }
100}
101
102impl<T, U> From<Vec<Option<U>>> for HandleMap<T, U>
103where
104    T: Handled + ?Sized,
105{
106    fn from(contents: Vec<Option<U>>) -> Self {
107        Self {
108            contents,
109            phantom_data: Default::default(),
110        }
111    }
112}
113
114impl<'a, T, U> IntoIterator for &'a HandleMap<T, U>
115where
116    T: Handled + ?Sized,
117{
118    type Item = (Handle<T>, &'a U);
119    type IntoIter = Iter<'a, T, U>;
120
121    fn into_iter(self) -> Self::IntoIter {
122        Iter::new(self)
123    }
124}
125
126/// An iterator over references to [HandleMap] values, and their keys.
127pub struct Iter<'a, T, U>
128where
129    T: Handled + ?Sized,
130{
131    map: &'a HandleMap<T, U>,
132    curr_index: usize,
133}
134
135impl<'a, T, U> Iter<'a, T, U>
136where
137    T: Handled + ?Sized,
138{
139    fn new(map: &'a HandleMap<T, U>) -> Self {
140        Self { map, curr_index: 0 }
141    }
142}
143
144impl<'a, T, U> Iterator for Iter<'a, T, U>
145where
146    T: Handled + ?Sized,
147{
148    type Item = (Handle<T>, &'a U);
149
150    fn next(&mut self) -> Option<Self::Item> {
151        loop {
152            match self.map.contents.get(self.curr_index)? {
153                None => self.curr_index += 1,
154                Some(content) => {
155                    let handle: Handle<T> = self.curr_index.into();
156                    self.curr_index += 1;
157                    break Some((handle, content));
158                }
159            }
160        }
161    }
162}
163
164#[cfg(test)]
165mod tests {
166    use super::*;
167
168    struct DummyHandled {}
169
170    impl Handled for DummyHandled {
171        type HandleCoreType = u16;
172    }
173
174    #[test]
175    fn test_handle_map() {
176        let mut map: HandleMap<DummyHandled, i32> = HandleMap::new();
177
178        assert_eq!(map.insert(1.into(), 1), true);
179        assert_eq!(map.insert(50.into(), 50), true);
180        assert_eq!(map.insert(1.into(), 1), false);
181        assert_eq!(map.get(2.into()), None);
182        assert_eq!(map.get(1.into()), Some(&1));
183    }
184
185    #[test]
186    fn test_into_iter() {
187        let mut map: HandleMap<DummyHandled, i32> = HandleMap::new();
188        map.insert(1.into(), 1);
189        map.insert(50.into(), 32);
190        map.insert(2.into(), 2);
191
192        assert_eq!(
193            map.into_iter()
194                .collect::<Vec<(Handle<DummyHandled>, &i32)>>(),
195            vec![(1.into(), &1), (2.into(), &2), (50.into(), &32)]
196        )
197    }
198}