use std::collections::HashMap;
use std::sync::OnceLock;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StdModuleKind {
RuntimeBacked,
Embedded,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StdModuleDef {
pub name: &'static str,
pub kind: StdModuleKind,
pub runtime_features: &'static [&'static str],
}
const RUNTIME_STD_MODULES: &[(&str, &[&str])] = &[
("std.assert", &[]),
("std.datetime", &[]),
("std.io", &[]),
("std.math", &[]),
("std.random", &[]),
("std.env", &[]),
("std.net", &["net"]),
("std.net.http", &["net"]),
("std.sync", &["sync"]),
("std.sql", &["sql"]),
("std.data", &["json", "csv"]),
("std.data.json", &["json"]),
("std.data.csv", &["csv"]),
];
const EMBEDDED_STD_MODULES: &[&str] = &[
"std.dsa",
"std.dsa.algorithm",
"std.dsa.bintree",
"std.dsa.collection",
"std.dsa.graph",
"std.dsa.heap",
"std.dsa.queue",
"std.dsa.stack",
];
fn insert_std_module(
registry: &mut HashMap<&'static str, StdModuleDef>,
name: &'static str,
kind: StdModuleKind,
runtime_features: &'static [&'static str],
) {
registry.insert(
name,
StdModuleDef {
name,
kind,
runtime_features,
},
);
}
fn build_std_module_registry() -> HashMap<&'static str, StdModuleDef> {
let mut registry = HashMap::new();
for (name, runtime_features) in RUNTIME_STD_MODULES {
insert_std_module(
&mut registry,
name,
StdModuleKind::RuntimeBacked,
runtime_features,
);
}
for name in EMBEDDED_STD_MODULES {
insert_std_module(&mut registry, name, StdModuleKind::Embedded, &[]);
}
registry
}
pub fn std_module_registry() -> &'static HashMap<&'static str, StdModuleDef> {
static REGISTRY: OnceLock<HashMap<&'static str, StdModuleDef>> = OnceLock::new();
REGISTRY.get_or_init(build_std_module_registry)
}
pub fn all_runtime_features() -> Vec<&'static str> {
let registry = std_module_registry();
let mut features = std::collections::HashSet::new();
for def in registry.values() {
for feature in def.runtime_features {
features.insert(*feature);
}
}
let mut result: Vec<_> = features.into_iter().collect();
result.sort();
result
}