1use jrsonnet_gcmodule::{Cc, Trace};2use jrsonnet_interner::IStr;34use crate::{GcHashMap, Thunk, Val};56#[derive(Trace)]7#[trace(tracking(force))]8pub struct LayeredHashMapInternals {9 parent: Option<LayeredHashMap>,10 current: GcHashMap<IStr, Thunk<Val>>,11}1213#[derive(Trace)]14pub struct LayeredHashMap(Cc<LayeredHashMapInternals>);1516impl LayeredHashMap {17 pub fn iter_keys(self, mut handler: impl FnMut(IStr)) {18 for (k, _) in &*self.0.current {19 handler(k.clone());20 }21 if let Some(parent) = self.0.parent.clone() {22 parent.iter_keys(handler);23 }24 }2526 pub(crate) fn new(layer: GcHashMap<IStr, Thunk<Val>>) -> Self {27 Self(Cc::new(LayeredHashMapInternals {28 parent: None,29 current: layer,30 }))31 }3233 pub fn extend(self, new_layer: GcHashMap<IStr, Thunk<Val>>) -> Self {34 Self(Cc::new(LayeredHashMapInternals {35 parent: Some(self),36 current: new_layer,37 }))38 }3940 pub fn get(&self, key: &IStr) -> Option<&Thunk<Val>> {41 (self.0)42 .current43 .get(key)44 .or_else(|| self.0.parent.as_ref().and_then(|p| p.get(key)))45 }4647 pub fn contains_key(&self, key: &IStr) -> bool {48 (self.0).current.contains_key(key)49 || self50 .051 .parent52 .as_ref()53 .map_or(false, |p| p.contains_key(key))54 }55}5657impl Clone for LayeredHashMap {58 fn clone(&self) -> Self {59 Self(self.0.clone())60 }61}6263impl Default for LayeredHashMap {64 fn default() -> Self {65 Self(Cc::new(LayeredHashMapInternals {66 parent: None,67 current: GcHashMap::new(),68 }))69 }70}