##// END OF EJS Templates
rhg: Replace subcommand boilerplate with a macro...
Simon Sapin -
r47252:95d37db3 default
parent child Browse files
Show More
@@ -4,7 +4,6 b' use clap::AppSettings;'
4 use clap::ArgMatches;
4 use clap::ArgMatches;
5 use format_bytes::format_bytes;
5 use format_bytes::format_bytes;
6
6
7 mod commands;
8 mod error;
7 mod error;
9 mod exitcode;
8 mod exitcode;
10 mod ui;
9 mod ui;
@@ -16,23 +15,27 b' fn main() {'
16 .setting(AppSettings::AllowInvalidUtf8)
15 .setting(AppSettings::AllowInvalidUtf8)
17 .setting(AppSettings::SubcommandRequired)
16 .setting(AppSettings::SubcommandRequired)
18 .setting(AppSettings::VersionlessSubcommands)
17 .setting(AppSettings::VersionlessSubcommands)
19 .version("0.0.1")
18 .version("0.0.1");
20 .subcommand(commands::root::args())
19 let app = add_subcommand_args(app);
21 .subcommand(commands::files::args())
22 .subcommand(commands::cat::args())
23 .subcommand(commands::debugdata::args())
24 .subcommand(commands::debugrequirements::args());
25
26 let matches = app.clone().get_matches_safe().unwrap_or_else(|err| {
27 let _ = ui::Ui::new().writeln_stderr_str(&err.message);
28 std::process::exit(exitcode::UNIMPLEMENTED)
29 });
30
20
31 let ui = ui::Ui::new();
21 let ui = ui::Ui::new();
32
22
33 let command_result = match_subcommand(matches, &ui);
23 let matches = app.clone().get_matches_safe().unwrap_or_else(|err| {
24 let _ = ui.writeln_stderr_str(&err.message);
25 std::process::exit(exitcode::UNIMPLEMENTED)
26 });
27 let (subcommand_name, subcommand_matches) = matches.subcommand();
28 let run = subcommand_run_fn(subcommand_name)
29 .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
30 let args = subcommand_matches
31 .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
34
32
35 let exit_code = match command_result {
33 let result = (|| -> Result<(), CommandError> {
34 let config = hg::config::Config::load()?;
35 run(&ui, &config, args)
36 })();
37
38 let exit_code = match result {
36 Ok(_) => exitcode::OK,
39 Ok(_) => exitcode::OK,
37
40
38 // Exit with a specific code and no error message to let a potential
41 // Exit with a specific code and no error message to let a potential
@@ -52,22 +55,40 b' fn main() {'
52 std::process::exit(exit_code)
55 std::process::exit(exit_code)
53 }
56 }
54
57
55 fn match_subcommand(
58 macro_rules! subcommands {
56 matches: ArgMatches,
59 ($( $command: ident )+) => {
57 ui: &ui::Ui,
60 mod commands {
58 ) -> Result<(), CommandError> {
61 $(
59 let config = hg::config::Config::load()?;
62 pub mod $command;
63 )+
64 }
65
66 fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
67 app
68 $(
69 .subcommand(commands::$command::args())
70 )+
71 }
60
72
61 match matches.subcommand() {
73 fn subcommand_run_fn(name: &str) -> Option<fn(
62 ("root", Some(matches)) => commands::root::run(ui, &config, matches),
74 &ui::Ui,
63 ("files", Some(matches)) => commands::files::run(ui, &config, matches),
75 &hg::config::Config,
64 ("cat", Some(matches)) => commands::cat::run(ui, &config, matches),
76 &ArgMatches,
65 ("debugdata", Some(matches)) => {
77 ) -> Result<(), CommandError>> {
66 commands::debugdata::run(ui, &config, matches)
78 match name {
79 $(
80 stringify!($command) => Some(commands::$command::run),
81 )+
82 _ => None,
83 }
67 }
84 }
68 ("debugrequirements", Some(matches)) => {
85 };
69 commands::debugrequirements::run(ui, &config, matches)
70 }
71 _ => unreachable!(), // Because of AppSettings::SubcommandRequired,
72 }
73 }
86 }
87
88 subcommands! {
89 cat
90 debugdata
91 debugrequirements
92 files
93 root
94 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now