use crate::prelude::*;
use crate::shared::typed_ids::ScopeId;
pub(crate) struct Repository<K, I, V> {
map : UnorderedMap<(K, ScopeId), I>,
data : Vec<(V, ScopeId)>,
}
impl<K, I, V> Repository<K, I, V> where I: Copy + Into<usize> + From<usize>, K: Hash + Eq {
pub fn new() -> Self {
Repository {
map: UnorderedMap::new(),
data: Vec::new(),
}
}
pub fn insert(self: &mut Self, scope_id: ScopeId, name: Option<K>, element: V) -> I {
let index = I::from(self.data.len());
self.data.push((element, scope_id));
if let Some(name) = name {
self.map.insert((name, scope_id), index);
}
index
}
pub fn alias(self: &mut Self, alias_scope_id: ScopeId, alias_name: K, source_index: I) -> I {
self.map.insert((alias_name, alias_scope_id), source_index);
source_index
}
pub fn value_by_id(self: &Self, index: I) -> &V {
&self.data[index.into()].0
}
pub fn value_by_id_mut(self: &mut Self, index: I) -> &mut V {
&mut self.data[index.into()].0
}
pub fn id_by_name(self: &Self, scope_id: ScopeId, name: K) -> Option<I> {
self.map.get(&(name, scope_id)).map(|i| *i)
}
pub fn name_by_id(self: &Self, index: I, exclude: K) -> Option<&K> where I: PartialEq { self.map.iter().find(|&item| *item.1 == index && item.0.0 != exclude).map(|item| &(item.0).0)
}
pub fn values<'s>(self: &'s Self) -> impl Iterator<Item = &'s V> {
self.data.iter().map(|item| &item.0)
}
pub fn len(self: &Self) -> usize {
self.data.len()
}
}
impl<K, I, V> Into<Vec<V>> for Repository<K, I, V> {
fn into(self: Self) -> Vec<V> {
self.data.into_iter().map(|item| item.0).collect()
}
}