Skip to main content

matrixcode_core/command/
registry.rs

1//! 命令注册表
2//!
3//! 管理所有已注册命令的查找和分发。
4
5use std::collections::HashMap;
6use std::sync::{Arc, LazyLock, Mutex};
7
8use super::backend_context::BackendContext;
9use super::command_trait::Command;
10
11/// 全局命令注册表
12static 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
18/// 获取全局注册表引用
19pub fn get_registry() -> &'static Mutex<CommandRegistry> {
20    &REGISTRY
21}
22
23/// 命令注册表
24///
25/// 存储所有已注册命令,支持按名称查找和分发。
26pub struct CommandRegistry {
27    commands: Vec<Arc<dyn Command>>,
28    name_index: HashMap<String, usize>,
29}
30
31impl CommandRegistry {
32    /// 创建空注册表
33    pub fn new() -> Self {
34        Self {
35            commands: Vec::new(),
36            name_index: HashMap::new(),
37        }
38    }
39
40    /// 注册命令
41    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        // 注册别名
46        for alias in command.aliases() {
47            self.name_index.insert(alias.to_string(), idx);
48        }
49
50        self.commands.push(command);
51    }
52
53    /// 查找匹配的命令
54    pub fn find(&self, msg: &str) -> Option<Arc<dyn Command>> {
55        // 尝试精确匹配或前缀匹配
56        for cmd in &self.commands {
57            if cmd.matches(msg) {
58                return Some(cmd.clone());
59            }
60        }
61        None
62    }
63
64    /// 分发命令执行
65    ///
66    /// 返回值:
67    /// - `Some(true)`:命令执行完成,消息应转发给 agent
68    /// - `Some(false)`:命令已处理,不转发
69    /// - `None`:未找到匹配命令
70    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}