use std::collections::HashMap; #[derive(PartialEq, Eq, Debug, Clone, Copy, Hash)] pub struct Key(u32); /// Hash map with auto-generated surrogate key. pub struct AnonTable { next: u32, inner: HashMap, } impl AnonTable { pub fn new() -> AnonTable { AnonTable { next: 0, inner: HashMap::new(), } } /// Generate a free key and insert a table under that key. pub fn insert(&mut self, value: V) -> Key { let id = self.next; self.next += 1; self.inner.insert(id, value); // should be always empty Key(id) } pub fn get_mut(&mut self, key: Key) -> Option<&mut V> { self.inner.get_mut(&key.0) } pub fn get(&self, key: Key) -> Option<&V> { self.inner.get(&key.0) } pub fn pop(&mut self, key: Key) -> Option { self.inner.remove(&key.0) } pub fn len(&self) -> usize { self.inner.len() } } pub struct AnonTableIterator<'a, V>(<&'a HashMap as IntoIterator>::IntoIter); impl<'a, V> Iterator for AnonTableIterator<'a, V> { type Item = &'a V; fn next(&mut self) -> Option<&'a V> { self.0.next().map(|a| a.1) } } impl<'a, V> IntoIterator for &'a AnonTable { type Item = &'a V; type IntoIter = AnonTableIterator<'a, V>; fn into_iter(self) -> Self::IntoIter { AnonTableIterator(IntoIterator::into_iter(&self.inner)) } } pub struct AnonTableMutIterator<'a, V>(<&'a mut HashMap as IntoIterator>::IntoIter); impl<'a, V> Iterator for AnonTableMutIterator<'a, V> { type Item = &'a mut V; fn next(&mut self) -> Option<&'a mut V> { self.0.next().map(|a| a.1) } } impl<'a, V> IntoIterator for &'a mut AnonTable { type Item = &'a mut V; type IntoIter = AnonTableMutIterator<'a, V>; fn into_iter(self) -> Self::IntoIter { AnonTableMutIterator(IntoIterator::into_iter(&mut self.inner)) } }