use crate::{export::Export, Instance}; use hashbrown::{hash_map::Entry, HashMap}; pub trait ImportResolver { fn get(&self, namespace: &str, name: &str) -> Option; } enum Namespace { Instance(Box), UserSupplied(HashMap), } pub struct Imports { map: HashMap, } impl Imports { pub fn new() -> Self { Self { map: HashMap::new(), } } pub fn register_instance(&mut self, namespace: impl Into, instance: Box) { match self.map.entry(namespace.into()) { Entry::Vacant(empty) => empty.insert(Namespace::Instance(instance)), Entry::Occupied(_) => { panic!("cannot register an instance in a namespace that already exists") } }; } pub fn register_export( &mut self, namespace: impl Into, name: impl Into, export: Export, ) { let namespace_item = self .map .entry(namespace.into()) .or_insert_with(|| Namespace::UserSupplied(HashMap::new())); match namespace_item { Namespace::UserSupplied(ref mut map) => map.insert(name.into(), export), Namespace::Instance(_) => panic!("cannot register an export in a namespace that has already been used to register an instance"), }; } } impl ImportResolver for Imports { fn get(&self, namespace: &str, name: &str) -> Option { match self.map.get(namespace)? { Namespace::UserSupplied(map) => map.get(name).cloned(), Namespace::Instance(instance) => instance.get_export(name).ok(), } } }