use std::{ cell::RefCell, collections::{HashMap, HashSet}, rc::Rc, }; use super::{ mod_tree::Module, nodes, path::{ItemPath, OwnedItemPath}, }; // requires mappings: // names -> sets of references to individual objects // paths -> individual objects // glob paths -> sets of object refs // (OPT/LATER) names (fuzzy) ~> sets of objects #[derive(Debug)] pub struct Registry { defs: Vec>, mods: Vec>, names: HashMap>, paths: HashMap, } impl Registry { pub fn new() -> Self { Self { defs: Vec::new(), mods: Vec::new(), names: HashMap::new(), paths: HashMap::new(), } } // TODO: rewrite. has lots of flaws pub fn insert_mod(&mut self, path: ItemPath<'_>, module: Rc) -> Option { let idx = self.mods.len(); let Some(name) = path.name() else { return None }; self.mods.push(StoreObj::new(&name, Mod { module })); if let Some(set) = self.names.get_mut(&name) { set.insert(RegistryIdx::Mod(idx)); } else { self.names .insert(name, HashSet::from([RegistryIdx::Mod(idx)])); } if self .paths .get(&path.clone().into()) .is_some_and(|other_idx| *other_idx != RegistryIdx::Mod(idx)) { return None; } else { self.paths.insert(path.into(), RegistryIdx::Mod(idx)) } } } impl Default for Registry { fn default() -> Self { Self::new() } } #[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)] pub enum RegistryIdx { Def(usize), Mod(usize), } #[derive(Debug)] struct StoreObj { inner: Rc>, } impl StoreObj { pub fn new(name: impl ToString, item: T) -> Self { Self { inner: Rc::new(InnerStoreObj { name: name.to_string(), obj: item, }), } } } #[derive(Debug)] struct InnerStoreObj { name: String, obj: T, } #[derive(Debug)] struct Mod { module: Rc, } #[derive(Debug)] struct Def { node: nodes::Def, }