bhcli

A TUI for chatting on LE PHP Chats
git clone https://git.dasho.dev/bhcli.git
Log | Files | Refs | README

registry.rs (3742B)


      1 use crate::chatops::{ChatCommand, ChatOpError, ChatOpResult, CommandContext, UserRole};
      2 use std::collections::HashMap;
      3 
      4 /// Registry for managing ChatOps commands
      5 pub struct CommandRegistry {
      6    commands: HashMap<String, Box<dyn ChatCommand>>,
      7    aliases: HashMap<String, String>,
      8 }
      9 
     10 impl CommandRegistry {
     11    pub fn new() -> Self {
     12        Self {
     13            commands: HashMap::new(),
     14            aliases: HashMap::new(),
     15        }
     16    }
     17 
     18    /// Register a new command
     19    pub fn register(&mut self, command: Box<dyn ChatCommand>) {
     20        let name = command.name().to_string();
     21 
     22        // Register aliases
     23        for alias in command.aliases() {
     24            self.aliases.insert(alias.to_string(), name.clone());
     25        }
     26 
     27        self.commands.insert(name, command);
     28    }
     29 
     30    /// Get command by name or alias
     31    pub fn get_command(&self, name: &str) -> Option<&dyn ChatCommand> {
     32        let actual_name = name.to_string();
     33        let command_name = self.aliases.get(name).unwrap_or(&actual_name);
     34        self.commands.get(command_name).map(|cmd| cmd.as_ref())
     35    }
     36 
     37    /// Execute a command with arguments
     38    pub fn execute_command(
     39        &self,
     40        name: &str,
     41        args: Vec<String>,
     42        context: &CommandContext,
     43    ) -> Result<ChatOpResult, ChatOpError> {
     44        match self.get_command(name) {
     45            Some(command) => {
     46                // Check permissions
     47                if !self.check_permission(&context.role, &command.required_role()) {
     48                    return Err(ChatOpError::PermissionDenied(format!(
     49                        "Command '{}' requires {:?} role or higher",
     50                        name,
     51                        command.required_role()
     52                    )));
     53                }
     54 
     55                command.execute(args, context)
     56            }
     57            None => Err(ChatOpError::Generic(format!("Unknown command: {}", name))),
     58        }
     59    }
     60 
     61    /// List all available commands for a user role
     62    pub fn list_commands(&self, role: &UserRole) -> Vec<(&str, &str)> {
     63        self.commands
     64            .values()
     65            .filter(|cmd| self.check_permission(role, &cmd.required_role()))
     66            .map(|cmd| (cmd.name(), cmd.description()))
     67            .collect()
     68    }
     69 
     70    /// Get help for a specific command
     71    pub fn get_help(&self, name: &str) -> Option<String> {
     72        self.get_command(name).map(|cmd| {
     73            format!(
     74                "**{}** - {}\n\nUsage: {}\n\nAliases: {}",
     75                cmd.name(),
     76                cmd.description(),
     77                cmd.usage(),
     78                if cmd.aliases().is_empty() {
     79                    "none".to_string()
     80                } else {
     81                    cmd.aliases().join(", ")
     82                }
     83            )
     84        })
     85    }
     86 
     87    /// Check if user role has permission for required role
     88    fn check_permission(&self, user_role: &UserRole, required_role: &UserRole) -> bool {
     89        let user_level = self.role_level(user_role);
     90        let required_level = self.role_level(required_role);
     91        user_level >= required_level
     92    }
     93 
     94    /// Convert role to numeric level for comparison
     95    fn role_level(&self, role: &UserRole) -> u8 {
     96        match role {
     97            UserRole::Guest => 0,
     98            UserRole::Member => 1,
     99            UserRole::Staff => 2,
    100            UserRole::Admin => 3,
    101        }
    102    }
    103 
    104    /// Register a user alias for a command
    105    #[allow(dead_code)]
    106    pub fn register_alias(&mut self, alias: String, target: String) {
    107        if self.commands.contains_key(&target) {
    108            self.aliases.insert(alias, target);
    109        }
    110    }
    111 
    112    /// Remove a user alias
    113    #[allow(dead_code)]
    114    pub fn remove_alias(&mut self, alias: &str) {
    115        self.aliases.remove(alias);
    116    }
    117 }