use indexmap::IndexMap;
use crate::value::{BuiltinFn, Value};
pub struct Module {
pub name: String,
functions: IndexMap<String, (String, BuiltinFn)>,
values: IndexMap<String, Value>,
submodules: IndexMap<String, Module>,
}
impl Module {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
functions: IndexMap::new(),
values: IndexMap::new(),
submodules: IndexMap::new(),
}
}
pub fn register_fn(&mut self, name: &str, func: BuiltinFn) {
let qualified = format!("{}::{}", self.name, name);
self.functions
.insert(name.to_string(), (qualified, func));
}
pub fn set(&mut self, name: &str, value: Value) {
self.values.insert(name.to_string(), value);
}
pub fn register_submodule(&mut self, sub: Module) {
self.submodules.insert(sub.name.clone(), sub);
}
pub fn to_value(&self) -> Value {
let mut map = IndexMap::new();
for (name, (qualified, func)) in &self.functions {
map.insert(name.clone(), Value::BuiltinFn(qualified.clone(), *func));
}
for (name, value) in &self.values {
map.insert(name.clone(), value.clone());
}
for (name, sub) in &self.submodules {
map.insert(name.clone(), sub.to_value());
}
Value::Dict(map)
}
pub fn names(&self) -> Vec<String> {
let mut names: Vec<String> = self.functions.keys().cloned().collect();
names.extend(self.values.keys().cloned());
names.extend(self.submodules.keys().cloned());
names
}
}