use super::instance::*;
use super::mem::*;
use super::module::*;
use super::register::*;
use super::signal::*;
use typed_arena::Arena;
use std::cell::{Ref, RefCell};
use std::collections::BTreeMap;
#[must_use]
pub struct Context<'a> {
module_arena: Arena<Module<'a>>,
pub(super) signal_arena: Arena<Signal<'a>>,
pub(super) register_data_arena: Arena<RegisterData<'a>>,
pub(super) register_arena: Arena<Register<'a>>,
pub(super) instance_arena: Arena<Instance<'a>>,
pub(super) mem_arena: Arena<Mem<'a>>,
pub(super) modules: RefCell<BTreeMap<String, &'a Module<'a>>>,
}
impl<'a> Context<'a> {
pub fn new() -> Context<'a> {
Context {
module_arena: Arena::new(),
signal_arena: Arena::new(),
register_data_arena: Arena::new(),
register_arena: Arena::new(),
instance_arena: Arena::new(),
mem_arena: Arena::new(),
modules: RefCell::new(BTreeMap::new()),
}
}
pub fn module<S: Into<String>>(&'a self, name: S) -> &Module {
let name = name.into();
let mut modules = self.modules.borrow_mut();
if modules.contains_key(&name) {
panic!(
"A module with the name \"{}\" already exists in this context.",
name
);
}
let module = self.module_arena.alloc(Module::new(self, name.clone()));
modules.insert(name, module);
module
}
pub fn modules(&'a self) -> Ref<BTreeMap<String, &'a Module<'a>>> {
self.modules.borrow()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic(expected = "A module with the name \"A\" already exists in this context.")]
fn unique_module_names() {
let c = Context::new();
let _ = c.module("A"); let _ = c.module("B");
let _ = c.module("A");
}
#[test]
fn new_context_has_no_modules() {
let c = Context::new();
assert!(c.modules().is_empty());
}
}