use super::traits::SlashCommand;
pub fn is_slash_command(input: &str) -> bool {
input.starts_with('/')
}
pub fn parse_command(input: &str) -> Option<(&str, &str)> {
if !is_slash_command(input) {
return None;
}
let trimmed = input.trim_start_matches('/');
let mut parts = trimmed.splitn(2, ' ');
let name = parts.next()?;
let args = parts.next().unwrap_or("").trim();
Some((name, args))
}
pub fn filter_commands<'a>(
commands: &'a [Box<dyn SlashCommand>],
input: &str,
) -> Vec<&'a dyn SlashCommand> {
let search_term = input.trim_start_matches('/').to_lowercase();
commands
.iter()
.filter(|cmd| cmd.name().to_lowercase().starts_with(&search_term))
.map(|c| c.as_ref())
.collect()
}
pub fn get_command_by_name<'a>(
commands: &'a [Box<dyn SlashCommand>],
name: &str,
) -> Option<&'a dyn SlashCommand> {
let name = name.trim_start_matches('/');
commands.iter().find(|cmd| cmd.name() == name).map(|c| c.as_ref())
}
pub fn generate_help_message(commands: &[Box<dyn SlashCommand>]) -> String {
let mut help = String::from("Available commands:\n\n");
for cmd in commands {
help.push_str(&format!(" /{} - {}\n", cmd.name(), cmd.description()));
}
help
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_slash_command() {
assert!(is_slash_command("/help"));
assert!(is_slash_command("/"));
assert!(!is_slash_command("help"));
assert!(!is_slash_command(""));
}
#[test]
fn test_parse_command() {
assert_eq!(parse_command("/help"), Some(("help", "")));
assert_eq!(parse_command("/echo hello world"), Some(("echo", "hello world")));
assert_eq!(parse_command("/cmd spaced args"), Some(("cmd", "spaced args")));
assert_eq!(parse_command("not a command"), None);
assert_eq!(parse_command(""), None);
}
}