matrixcode_core/command/
registry.rs1use std::collections::HashMap;
6use std::sync::{Arc, LazyLock, Mutex};
7
8use super::backend_context::BackendContext;
9use super::command_trait::Command;
10
11static REGISTRY: LazyLock<Mutex<CommandRegistry>> = LazyLock::new(|| {
13 let mut registry = CommandRegistry::new();
14 super::handlers::register_commands(&mut registry);
15 Mutex::new(registry)
16});
17
18pub fn get_registry() -> &'static Mutex<CommandRegistry> {
20 ®ISTRY
21}
22
23pub struct CommandRegistry {
27 commands: Vec<Arc<dyn Command>>,
28 name_index: HashMap<String, usize>,
29}
30
31impl CommandRegistry {
32 pub fn new() -> Self {
34 Self {
35 commands: Vec::new(),
36 name_index: HashMap::new(),
37 }
38 }
39
40 pub fn register(&mut self, command: Arc<dyn Command>) {
42 let idx = self.commands.len();
43 self.name_index.insert(command.name().to_string(), idx);
44
45 for alias in command.aliases() {
47 self.name_index.insert(alias.to_string(), idx);
48 }
49
50 self.commands.push(command);
51 }
52
53 pub fn find(&self, msg: &str) -> Option<Arc<dyn Command>> {
55 for cmd in &self.commands {
57 if cmd.matches(msg) {
58 return Some(cmd.clone());
59 }
60 }
61 None
62 }
63
64 pub async fn dispatch(&self, msg: &str, ctx: &mut BackendContext<'_>) -> Option<bool> {
71 let cmd = self.find(msg)?;
72 Some(cmd.execute(ctx).await)
73 }
74}
75
76impl Default for CommandRegistry {
77 fn default() -> Self {
78 Self::new()
79 }
80}