1use jrsonnet_gcmodule::{Cc, Trace};2use jrsonnet_interner::IStr;3use rustc_hash::FxHashMap;45use crate::{gc::WithCapacityExt as _, Thunk, Val};67#[derive(Trace, Debug)]8#[trace(tracking(force))]9pub struct LayeredHashMapInternals {10 parent: Option<LayeredHashMap>,11 current: FxHashMap<IStr, Thunk<Val>>,12}1314#[derive(Trace, Debug)]15pub struct LayeredHashMap(Cc<LayeredHashMapInternals>);1617impl LayeredHashMap {18 pub fn iter_keys(self, mut handler: impl FnMut(IStr)) {19 for k in self.0.current.keys() {20 handler(k.clone());21 }22 if let Some(parent) = self.0.parent.clone() {23 parent.iter_keys(handler);24 }25 }2627 pub(crate) fn new(layer: FxHashMap<IStr, Thunk<Val>>) -> Self {28 Self(Cc::new(LayeredHashMapInternals {29 parent: None,30 current: layer,31 }))32 }3334 pub fn extend(self, new_layer: FxHashMap<IStr, Thunk<Val>>) -> Self {35 Self(Cc::new(LayeredHashMapInternals {36 parent: Some(self),37 current: new_layer,38 }))39 }4041 pub fn get(&self, key: &IStr) -> Option<&Thunk<Val>> {42 (self.0)43 .current44 .get(key)45 .or_else(|| self.0.parent.as_ref().and_then(|p| p.get(key)))46 }4748 pub fn contains_key(&self, key: &IStr) -> bool {49 (self.0).current.contains_key(key)50 || self.0.parent.as_ref().is_some_and(|p| p.contains_key(key))51 }52}5354impl Clone for LayeredHashMap {55 fn clone(&self) -> Self {56 Self(self.0.clone())57 }58}5960impl Default for LayeredHashMap {61 fn default() -> Self {62 Self(Cc::new(LayeredHashMapInternals {63 parent: None,64 current: FxHashMap::new(),65 }))66 }67}