1use indexmap::IndexMap;
2
3use crate::value::{BuiltinFn, Value};
4
5pub struct Module {
8 pub name: String,
9 functions: IndexMap<String, (String, BuiltinFn)>,
10 values: IndexMap<String, Value>,
11 submodules: IndexMap<String, Module>,
12}
13
14impl Module {
15 pub fn new(name: impl Into<String>) -> Self {
16 Self {
17 name: name.into(),
18 functions: IndexMap::new(),
19 values: IndexMap::new(),
20 submodules: IndexMap::new(),
21 }
22 }
23
24 pub fn register_fn(&mut self, name: &str, func: BuiltinFn) {
26 let qualified = format!("{}::{}", self.name, name);
27 self.functions
28 .insert(name.to_string(), (qualified, func));
29 }
30
31 pub fn set(&mut self, name: &str, value: Value) {
33 self.values.insert(name.to_string(), value);
34 }
35
36 pub fn register_submodule(&mut self, sub: Module) {
38 self.submodules.insert(sub.name.clone(), sub);
39 }
40
41 pub fn to_value(&self) -> Value {
44 let mut map = IndexMap::new();
45
46 for (name, (qualified, func)) in &self.functions {
47 map.insert(name.clone(), Value::BuiltinFn(qualified.clone(), *func));
48 }
49
50 for (name, value) in &self.values {
51 map.insert(name.clone(), value.clone());
52 }
53
54 for (name, sub) in &self.submodules {
55 map.insert(name.clone(), sub.to_value());
56 }
57
58 Value::Dict(map)
59 }
60
61 pub fn names(&self) -> Vec<String> {
63 let mut names: Vec<String> = self.functions.keys().cloned().collect();
64 names.extend(self.values.keys().cloned());
65 names.extend(self.submodules.keys().cloned());
66 names
67 }
68}