Skip to main content

safe_chains/registry/
mod.rs

1mod build;
2mod dispatch;
3mod docs;
4mod policy;
5pub(crate) mod types;
6
7use std::collections::HashMap;
8use std::sync::LazyLock;
9
10use crate::parse::Token;
11use crate::verdict::Verdict;
12
13pub use build::{build_registry, load_toml};
14pub use dispatch::dispatch_spec;
15pub use types::{CommandSpec, OwnedPolicy};
16
17type HandlerFn = fn(&[Token]) -> Verdict;
18
19static CMD_HANDLERS: LazyLock<HashMap<&'static str, HandlerFn>> =
20    LazyLock::new(crate::handlers::custom_cmd_handlers);
21
22static SUB_HANDLERS: LazyLock<HashMap<&'static str, HandlerFn>> =
23    LazyLock::new(crate::handlers::custom_sub_handlers);
24
25macro_rules! load_commands {
26    ($($file:literal),* $(,)?) => {{
27        let mut all = Vec::new();
28        $(all.extend(load_toml(include_str!(concat!("../../commands/", $file, ".toml"))));)*
29        build_registry(all)
30    }};
31}
32
33static TOML_REGISTRY: LazyLock<HashMap<String, CommandSpec>> = LazyLock::new(|| {
34    load_commands![
35        "ai", "android", "binary", "builtins", "containers", "data",
36        "dotnet", "forges", "fs", "fuzzy", "go", "hash", "jvm", "magick", "net",
37        "node", "php", "python", "r", "ruby", "rust", "search", "swift",
38        "sysinfo", "system", "text", "tools", "vcs", "wrappers", "xcode",
39    ]
40});
41
42pub fn toml_dispatch(tokens: &[Token]) -> Option<Verdict> {
43    let cmd = tokens[0].command_name();
44    TOML_REGISTRY.get(cmd).map(|spec| dispatch_spec(tokens, spec))
45}
46
47pub fn toml_command_names() -> Vec<&'static str> {
48    TOML_REGISTRY
49        .keys()
50        .map(|k| k.as_str())
51        .collect()
52}
53
54pub fn toml_command_docs() -> Vec<crate::docs::CommandDoc> {
55    TOML_REGISTRY
56        .iter()
57        .filter(|(key, spec)| *key == &spec.name)
58        .map(|(_, spec)| spec.to_command_doc())
59        .collect()
60}
61
62#[cfg(test)]
63mod tests;