Skip to content

Commit

Permalink
Add IndexedMap, and a couple methods on DocStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
justinpombrio committed Mar 19, 2024
1 parent 22d7bba commit 1a36139
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 94 deletions.
100 changes: 100 additions & 0 deletions src/language/indexed_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::borrow::Borrow;
use std::collections::HashMap;
use std::hash::Hash;
use std::ops::{Index, IndexMut};
use std::vec;

#[derive(Debug, Clone)]
pub struct IndexedMap<T> {
map: HashMap<String, usize>,
values: Vec<T>,
}

impl<T> IndexedMap<T> {
pub fn new() -> IndexedMap<T> {

Check failure on line 14 in src/language/indexed_map.rs

View workflow job for this annotation

GitHub Actions / build

you should consider adding a `Default` implementation for `IndexedMap<T>`
IndexedMap {
map: HashMap::new(),
values: Vec::new(),
}
}

/// Inserts name->value into this map. Returns `Err(name)` if already present.
pub fn insert(&mut self, name: String, value: T) -> Result<(), String> {
if self.map.contains_key(&name) {
return Err(name);
}
let new_id = self.values.len();
self.values.push(value);
self.map.insert(name, new_id);
Ok(())
}

pub fn contains_name(&self, name: &str) -> bool {
self.map.contains_key(name)
}

pub fn get(&self, id: usize) -> Option<&T> {
self.values.get(id)
}

pub fn get_mut(&mut self, id: usize) -> Option<&mut T> {
self.values.get_mut(id)
}

pub fn get_by_name(&self, name: &str) -> Option<&T> {
Some(&self.values[*self.map.get(name)?])
}

pub fn get_by_name_mut(&mut self, name: &str) -> Option<&mut T> {
Some(&mut self.values[*self.map.get(name)?])
}

pub fn id(&self, name: &str) -> Option<usize> {
self.map.get(name).copied()
}

pub fn names(&self) -> impl ExactSizeIterator<Item = &str> {
self.map.keys().map(|name| name.as_ref())
}

pub fn len(&self) -> usize {
self.values.len()
}
}

impl<T> Index<&str> for IndexedMap<T> {
type Output = T;

fn index(&self, name: &str) -> &T {
&self.values[self.map[name]]
}
}

impl<T> IndexMut<&str> for IndexedMap<T> {
fn index_mut(&mut self, name: &str) -> &mut T {
&mut self.values[self.map[name]]
}
}

impl<T> Index<usize> for IndexedMap<T> {
type Output = T;

fn index(&self, id: usize) -> &T {
&self.values[id]
}
}

impl<T> IndexMut<usize> for IndexedMap<T> {
fn index_mut(&mut self, id: usize) -> &mut T {
&mut self.values[id]
}
}

impl<'a, T> IntoIterator for &'a IndexedMap<T> {
type Item = usize;
type IntoIter = std::ops::Range<usize>;

fn into_iter(self) -> Self::IntoIter {
0..self.values.len()
}
}
Loading

0 comments on commit 1a36139

Please sign in to comment.