safe_chains/registry/
mod.rs1mod 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;