use std::{collections::HashMap, hash::Hash};
pub enum FrameMap<'a, K, V> {
Root(HashMap<K, V>),
Leaf(HashMap<K, V>, &'a FrameMap<'a, K, V>),
}
impl<K, V> Default for FrameMap<'_, K, V> {
fn default() -> Self {
Self::Root(HashMap::new())
}
}
impl<'a, K, V> FrameMap<'a, K, V>
where
K: Eq + Hash,
{
pub fn new() -> Self {
Self::default()
}
pub fn last_frame(&mut self) -> &mut HashMap<K, V> {
match self {
Self::Root(map) => map,
Self::Leaf(map, _) => map,
}
}
pub fn insert(&mut self, k: K, v: V) {
self.last_frame().insert(k, v);
}
pub fn get(&self, k: &K) -> Option<&V> {
let mut map = self;
loop {
match map {
Self::Root(m) => return m.get(k),
Self::Leaf(m, parent) => {
if let Some(v) = m.get(k) {
return Some(v);
}
map = parent;
}
}
}
}
pub fn branch(&'a self) -> Self {
Self::Leaf(HashMap::new(), self)
}
}