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.insert(name.to_string(), (qualified, func));
28 }
29
30 pub fn set(&mut self, name: &str, value: Value) {
32 self.values.insert(name.to_string(), value);
33 }
34
35 pub fn register_submodule(&mut self, sub: Module) {
37 self.submodules.insert(sub.name.clone(), sub);
38 }
39
40 pub fn to_value(&self) -> Value {
43 let mut map = IndexMap::new();
44
45 for (name, (qualified, func)) in &self.functions {
46 map.insert(name.clone(), Value::BuiltinFn(qualified.clone(), *func));
47 }
48
49 for (name, value) in &self.values {
50 map.insert(name.clone(), value.clone());
51 }
52
53 for (name, sub) in &self.submodules {
54 map.insert(name.clone(), sub.to_value());
55 }
56
57 Value::Dict(map)
58 }
59
60 pub fn names(&self) -> Vec<String> {
62 let mut names: Vec<String> = self.functions.keys().cloned().collect();
63 names.extend(self.values.keys().cloned());
64 names.extend(self.submodules.keys().cloned());
65 names
66 }
67}