rhg: simplify the subcommands macro
Reduce the scope of the macro to only generate individual `SubCommand`
values. This way, it will be easy to tweak the behavior of
`add_subcommand_args` and `subcommand_run_fn` without having
to understand the details of the macro.
It also lets us easy add commands that don't fit the idiom,
for example the "admin::" commands or "script::" commands.
--- a/rust/rhg/src/main.rs Mon Dec 16 03:04:44 2024 -0500
+++ b/rust/rhg/src/main.rs Fri Dec 13 15:43:50 2024 +0000
@@ -536,39 +536,51 @@
pub mod status;
}
-macro_rules! subcommands {
- ($( $command: ident )+) => {
-
- fn add_subcommand_args(app: clap::Command) -> clap::Command {
- app
- $(
- .subcommand(commands::$command::args())
- )+
- }
+pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
- pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
+struct SubCommand {
+ run: RunFn,
+ args: clap::Command,
+ name: String,
+}
- fn subcommand_run_fn(name: &str) -> Option<RunFn> {
- match name {
- $(
- stringify!($command) => Some(commands::$command::run),
- )+
- _ => None,
- }
+macro_rules! subcommand {
+ ($command: ident) => {
+ SubCommand {
+ args: commands::$command::args(),
+ run: commands::$command::run,
+ name: stringify!($command).to_string(),
}
};
}
+fn subcommands() -> Vec<SubCommand> {
+ vec![
+ subcommand!(cat),
+ subcommand!(debugdata),
+ subcommand!(debugrequirements),
+ subcommand!(debugignorerhg),
+ subcommand!(debugrhgsparse),
+ subcommand!(files),
+ subcommand!(root),
+ subcommand!(config),
+ subcommand!(status),
+ ]
+}
-subcommands! {
- cat
- debugdata
- debugrequirements
- debugignorerhg
- debugrhgsparse
- files
- root
- config
- status
+fn add_subcommand_args(mut app: clap::Command) -> clap::Command {
+ for s in subcommands() {
+ app = app.subcommand(s.args)
+ }
+ app
+}
+
+fn subcommand_run_fn(name: &str) -> Option<RunFn> {
+ for s in subcommands() {
+ if s.name == name {
+ return Some(s.run);
+ }
+ }
+ None
}
pub struct CliInvocation<'a> {