modcli/commands/
help.rs

1use crate::command::Command;
2use crate::loader::CommandRegistry;
3use crate::output::hook;
4
5/// Built-in help command (execution handled by registry internally)
6pub struct HelpCommand;
7
8impl Default for HelpCommand {
9    fn default() -> Self {
10        Self::new()
11    }
12}
13
14impl HelpCommand {
15    pub fn new() -> Self {
16        Self
17    }
18}
19
20impl Command for HelpCommand {
21    fn name(&self) -> &str {
22        "help"
23    }
24
25    fn aliases(&self) -> &[&str] {
26        &["--help", "-h"]
27    }
28
29    fn help(&self) -> Option<&str> {
30        Some("Displays help information")
31    }
32
33    fn validate(&self, args: &[String]) -> Result<(), String> {
34        if args.len() > 1 {
35            Err("Too many arguments. Usage: help [command]".into())
36        } else {
37            Ok(())
38        }
39    }
40
41    fn execute(&self, _args: &[String]) {}
42
43    fn execute_with(&self, args: &[String], registry: &CommandRegistry) {
44        // validate() already ensures args.len() <= 1
45        if args.len() == 1 {
46            let query = &args[0];
47            if let Some(target) = registry.get(query) {
48                if target.hidden() {
49                    println!("No help available for '{query}'");
50                } else {
51                    println!(
52                        "{} - {}",
53                        target.name(),
54                        target.help().unwrap_or("No description.")
55                    );
56                }
57            } else {
58                let unknown =
59                    format!("[{query}]. Type `help` or `--help` for a list of available commands.");
60                hook::unknown(&unknown);
61            }
62            return;
63        }
64
65        println!("Help:");
66        for command in registry.all() {
67            if !command.hidden() {
68                println!(
69                    "  {:<12} {}",
70                    command.name(),
71                    command.help().unwrap_or("No description")
72                );
73            }
74        }
75    }
76}