rush_sync_server/commands/
registry.rs

1use super::command::Command;
2use crate::core::prelude::*;
3use std::collections::HashMap;
4
5pub struct CommandRegistry {
6    commands: Vec<Box<dyn Command>>,
7    name_map: HashMap<String, usize>,
8    initialized: bool,
9}
10
11impl CommandRegistry {
12    pub fn new() -> Self {
13        Self {
14            commands: Vec::new(),
15            name_map: HashMap::new(),
16            initialized: false,
17        }
18    }
19
20    pub fn register<T: Command>(&mut self, command: T) -> &mut Self {
21        let name = command.name().to_lowercase();
22        let index = self.commands.len();
23
24        self.commands.push(Box::new(command));
25        self.name_map.insert(name, index);
26        self
27    }
28
29    pub fn register_boxed(&mut self, command: Box<dyn Command>) -> &mut Self {
30        let name = command.name().to_lowercase();
31        let index = self.commands.len();
32
33        self.commands.push(command);
34        self.name_map.insert(name, index);
35        self
36    }
37
38    pub fn initialize(&mut self) -> &mut Self {
39        if self.initialized {
40            return self;
41        }
42
43        self.name_map.clear();
44        for (new_idx, cmd) in self.commands.iter().enumerate() {
45            self.name_map.insert(cmd.name().to_lowercase(), new_idx);
46        }
47
48        self.initialized = true;
49        self
50    }
51
52    pub fn find_command(&self, input: &str) -> Option<&dyn Command> {
53        let input = input.trim().to_lowercase();
54
55        // Exakte Übereinstimmung
56        if let Some(&index) = self.name_map.get(&input) {
57            return self.commands.get(index).map(|cmd| cmd.as_ref());
58        }
59
60        // Pattern matching
61        for cmd in &self.commands {
62            if cmd.is_available() && cmd.matches(&input) {
63                return Some(cmd.as_ref());
64            }
65        }
66
67        None
68    }
69
70    // FIX: Correct Result type with Error parameter
71    pub fn execute_sync(&self, command: &str, args: &[&str]) -> Option<Result<String>> {
72        self.find_command(command).map(|cmd| cmd.execute_sync(args))
73    }
74
75    // FIX: Correct Result type with Error parameter
76    pub async fn execute_async(&self, command: &str, args: &[&str]) -> Option<Result<String>> {
77        if let Some(cmd) = self.find_command(command) {
78            Some(cmd.execute_async(args).await)
79        } else {
80            None
81        }
82    }
83
84    pub fn list_commands(&self) -> Vec<(&str, &str)> {
85        self.commands
86            .iter()
87            .filter(|cmd| cmd.is_available())
88            .map(|cmd| (cmd.name(), cmd.description()))
89            .collect()
90    }
91
92    pub fn debug_info(&self) -> String {
93        format!(
94            "CommandRegistry: {} commands, initialized: {}",
95            self.commands.len(),
96            self.initialized
97        )
98    }
99
100    pub fn len(&self) -> usize {
101        self.commands.len()
102    }
103    pub fn is_empty(&self) -> bool {
104        self.commands.is_empty()
105    }
106}
107
108impl Default for CommandRegistry {
109    fn default() -> Self {
110        Self::new()
111    }
112}