rust/rhg/src/main.rs
changeset 45529 f17caf8f3fef
parent 45440 a6a000ab135b
child 45530 b1cea0dc9db0
--- a/rust/rhg/src/main.rs	Wed Sep 09 12:07:05 2020 +0200
+++ b/rust/rhg/src/main.rs	Mon Aug 17 16:56:39 2020 +0200
@@ -1,15 +1,21 @@
 use clap::App;
 use clap::AppSettings;
+use clap::Arg;
+use clap::ArgGroup;
+use clap::ArgMatches;
 use clap::SubCommand;
+use hg::operations::DebugDataKind;
+use std::convert::TryFrom;
 
 mod commands;
 mod error;
 mod exitcode;
 mod ui;
 use commands::Command;
+use error::CommandError;
 
 fn main() {
-    let mut app = App::new("rhg")
+    let app = App::new("rhg")
         .setting(AppSettings::AllowInvalidUtf8)
         .setting(AppSettings::SubcommandRequired)
         .setting(AppSettings::VersionlessSubcommands)
@@ -19,6 +25,33 @@
         )
         .subcommand(
             SubCommand::with_name("files").about(commands::files::HELP_TEXT),
+        )
+        .subcommand(
+            SubCommand::with_name("debugdata")
+                .about(commands::debugdata::HELP_TEXT)
+                .arg(
+                    Arg::with_name("changelog")
+                        .help("open changelog")
+                        .short("-c")
+                        .long("--changelog"),
+                )
+                .arg(
+                    Arg::with_name("manifest")
+                        .help("open manifest")
+                        .short("-m")
+                        .long("--manifest"),
+                )
+                .group(
+                    ArgGroup::with_name("")
+                        .args(&["changelog", "manifest"])
+                        .required(true),
+                )
+                .arg(
+                    Arg::with_name("rev")
+                        .help("revision")
+                        .required(true)
+                        .value_name("REV"),
+                ),
         );
 
     let matches = app.clone().get_matches_safe().unwrap_or_else(|err| {
@@ -28,19 +61,7 @@
 
     let ui = ui::Ui::new();
 
-    let command_result = match matches.subcommand_name() {
-        Some(name) => match name {
-            "root" => commands::root::RootCommand::new().run(&ui),
-            "files" => commands::files::FilesCommand::new().run(&ui),
-            _ => std::process::exit(exitcode::UNIMPLEMENTED_COMMAND),
-        },
-        _ => {
-            match app.print_help() {
-                Ok(_) => std::process::exit(exitcode::OK),
-                Err(_) => std::process::exit(exitcode::ABORT),
-            };
-        }
-    };
+    let command_result = match_subcommand(matches, &ui);
 
     match command_result {
         Ok(_) => std::process::exit(exitcode::OK),
@@ -56,3 +77,43 @@
         }
     }
 }
+
+fn match_subcommand(
+    matches: ArgMatches,
+    ui: &ui::Ui,
+) -> Result<(), CommandError> {
+    match matches.subcommand() {
+        ("root", _) => commands::root::RootCommand::new().run(&ui),
+        ("files", _) => commands::files::FilesCommand::new().run(&ui),
+        ("debugdata", Some(matches)) => {
+            commands::debugdata::DebugDataCommand::try_from(matches)?.run(&ui)
+        }
+        _ => unreachable!(), // Because of AppSettings::SubcommandRequired,
+    }
+}
+
+impl<'a> TryFrom<&'a ArgMatches<'_>>
+    for commands::debugdata::DebugDataCommand<'a>
+{
+    type Error = CommandError;
+
+    fn try_from(args: &'a ArgMatches) -> Result<Self, Self::Error> {
+        let rev = args
+            .value_of("rev")
+            .expect("rev should be a required argument");
+        let kind = match (
+            args.is_present("changelog"),
+            args.is_present("manifest"),
+        ) {
+            (true, false) => DebugDataKind::Changelog,
+            (false, true) => DebugDataKind::Manifest,
+            (true, true) => {
+                unreachable!("Should not happen since options are exclusive")
+            }
+            (false, false) => {
+                unreachable!("Should not happen since options are required")
+            }
+        };
+        Ok(commands::debugdata::DebugDataCommand::new(rev, kind))
+    }
+}