syntax_parser_generator/handles/collections/
handle_map.rs1use std::fmt::{Debug, Formatter};
2use std::marker::PhantomData;
3
4use derive_where::derive_where;
5
6use crate::handles::{Handle, Handled};
7
8#[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 pub fn new() -> Self {
52 Vec::new().into()
53 }
54
55 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 pub fn get(&self, key: Handle<T>) -> Option<&U> {
67 self.contents.get(key.index())?.as_ref()
68 }
69
70 pub fn get_mut(&mut self, key: Handle<T>) -> Option<&mut U> {
73 self.contents.get_mut(key.index())?.as_mut()
74 }
75
76 pub fn contains_key(&self, key: Handle<T>) -> bool {
78 !self.get(key).is_none()
79 }
80
81 pub fn iter(&self) -> impl Iterator<Item=(Handle<T>, &U)> {
83 (&self).into_iter()
84 }
85
86 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
126pub 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}