use std::collections::HashMap;
use std::sync::{Arc, LazyLock, Mutex};
use super::backend_context::BackendContext;
use super::command_trait::Command;
static REGISTRY: LazyLock<Mutex<CommandRegistry>> = LazyLock::new(|| {
let mut registry = CommandRegistry::new();
super::handlers::register_commands(&mut registry);
Mutex::new(registry)
});
pub fn get_registry() -> &'static Mutex<CommandRegistry> {
®ISTRY
}
pub struct CommandRegistry {
commands: Vec<Arc<dyn Command>>,
name_index: HashMap<String, usize>,
}
impl CommandRegistry {
pub fn new() -> Self {
Self {
commands: Vec::new(),
name_index: HashMap::new(),
}
}
pub fn register(&mut self, command: Arc<dyn Command>) {
let idx = self.commands.len();
self.name_index.insert(command.name().to_string(), idx);
for alias in command.aliases() {
self.name_index.insert(alias.to_string(), idx);
}
self.commands.push(command);
}
pub fn find(&self, msg: &str) -> Option<Arc<dyn Command>> {
for cmd in &self.commands {
if cmd.matches(msg) {
return Some(cmd.clone());
}
}
None
}
pub async fn dispatch(&self, msg: &str, ctx: &mut BackendContext<'_>) -> Option<bool> {
let cmd = self.find(msg)?;
Some(cmd.execute(ctx).await)
}
}
impl Default for CommandRegistry {
fn default() -> Self {
Self::new()
}
}