Mercurial > public > mercurial-scm > hg
changeset 52522:92c6c8ab6f94
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.
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Fri, 13 Dec 2024 15:43:50 +0000 |
parents | b52f2b365eff |
children | 021c1b1671e5 |
files | rust/rhg/src/main.rs |
diffstat | 1 files changed, 39 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- 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> {