use alloc::{collections::BTreeMap, sync::Arc};
use miden_core::{Word, mast::MastForest};
use miden_mast_package::{PackageDebugInfoError, debug_info::PackageDebugInfo};
#[derive(Debug, Clone)]
pub struct LoadedMastForest {
mast_forest: Arc<MastForest>,
debug_info: Result<Option<Arc<PackageDebugInfo>>, Arc<PackageDebugInfoError>>,
}
impl LoadedMastForest {
pub fn new(mast_forest: Arc<MastForest>) -> Self {
Self { mast_forest, debug_info: Ok(None) }
}
pub fn with_package_debug_info(
mast_forest: Arc<MastForest>,
debug_info: Result<Option<PackageDebugInfo>, PackageDebugInfoError>,
) -> Self {
Self {
mast_forest,
debug_info: debug_info.map(|debug_info| debug_info.map(Arc::new)).map_err(Arc::new),
}
}
pub fn mast_forest(&self) -> &Arc<MastForest> {
&self.mast_forest
}
pub fn package_debug_info(
&self,
) -> Result<Option<Arc<PackageDebugInfo>>, Arc<PackageDebugInfoError>> {
self.debug_info.clone()
}
}
pub trait MastForestStore {
fn get(&self, procedure_hash: &Word) -> Option<LoadedMastForest>;
}
#[derive(Debug, Default, Clone)]
pub struct MemMastForestStore {
mast_forests: BTreeMap<Word, LoadedMastForest>,
}
impl MemMastForestStore {
pub fn insert(&mut self, mast_forest: Arc<MastForest>) {
self.insert_loaded(LoadedMastForest::new(mast_forest));
}
pub fn insert_loaded(&mut self, loaded_mast_forest: LoadedMastForest) {
for proc_digest in loaded_mast_forest.mast_forest.local_procedure_digests() {
self.mast_forests.insert(proc_digest, loaded_mast_forest.clone());
}
}
}
impl MastForestStore for MemMastForestStore {
fn get(&self, procedure_hash: &Word) -> Option<LoadedMastForest> {
self.mast_forests.get(procedure_hash).cloned()
}
}