chiark / gitweb /
otter: Introduce extra_error message hook
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 6 Jun 2021 21:49:53 +0000 (22:49 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 6 Jun 2021 21:49:53 +0000 (22:49 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
cli/clisupport.rs
cli/otter.rs

index 15b6da285b9a12db2bff5374f3353458a03c6779..022351a40b49fc0976416a9e2089f04eea877406 100644 (file)
@@ -121,14 +121,16 @@ pub fn noargs(_sa: &mut NoArgs) -> ArgumentParser { ArgumentParser::new() }
 pub type ApMaker<'apm, T> =
   &'apm dyn for <'a> Fn(&'a mut T) -> ArgumentParser<'a>;
 
-pub type ExtraHelp<'exh> =
+pub type ExtraMessage<'exh> =
   &'exh dyn Fn(&mut dyn Write) -> Result<(), io::Error>;
 
 pub type ApCompleter<'apc,T,U> =
   &'apc dyn Fn(T) -> Result<U, ArgumentParseError>;
 
 pub fn run_argparse<T>(parsed: &mut T, apmaker: ApMaker<T>,
-                       args: Vec<String>, extra_help: Option<ExtraHelp>)
+                       args: Vec<String>,
+                       extra_help: Option<ExtraMessage>,
+                       extra_error: Option<ExtraMessage>)
                        -> String /* us */{
   let ap = apmaker(parsed);
   let us = args.get(0).expect("argv[0] must be provided!").clone();
@@ -136,16 +138,21 @@ pub fn run_argparse<T>(parsed: &mut T, apmaker: ApMaker<T>,
   let mut stdout = CookedStdout::new();
   let mut stderr = io::stderr();
 
+  let em_call = |em: Option<ExtraMessage>, f| {
+    if let Some(em) = em { em(f).unwrap() };
+  };
+
   let r = ap.parse(args, &mut stdout, &mut stderr);
   if let Err(rc) = r {
     exit(match rc {
       0 => {
-        if let Some(eh) = extra_help {
-          eh(&mut stdout).unwrap();
-        }
+        em_call(extra_help, &mut stdout);
         0
       },
-      2 => EXIT_USAGE,
+      2 => {
+        em_call(extra_error, &mut stderr);
+        EXIT_USAGE
+      },
       _ => panic!("unexpected error rc {} from ArgumentParser::parse", rc),
     });
   }
@@ -166,10 +173,10 @@ pub fn parse_args<T:Default,U>(
   args: Vec<String>,
   apmaker: ApMaker<T>,
   completer: ApCompleter<T,U>,
-  extra_help: Option<ExtraHelp>,
+  extra_help: Option<ExtraMessage>,
 ) -> U {
   let mut parsed = default();
-  let us = run_argparse(&mut parsed, apmaker, args, extra_help);
+  let us = run_argparse(&mut parsed, apmaker, args, extra_help, None);
   let completed = argparse_more(us, apmaker, || completer(parsed));
   completed
 }
index 8808ff28e878bf07508cb4fb4064f67eaf995e61..b8b2a3cc3e01953459e114d858f4090db75aac68 100644 (file)
@@ -307,7 +307,7 @@ fn main() {
     }))
   };
 
-  let extra_help: ExtraHelp = &|w|{
+  let extra_help: ExtraMessage = &|w|{
     writeln!(w, "\nSubcommands:")?;
     let maxlen = inventory::iter::<Subcommand>.into_iter()
       .map(|Subcommand{verb,..}| verb.len())
@@ -321,7 +321,8 @@ fn main() {
   let mut parsed: RawMainArgs = default();
   let args: Vec<String> = env::args().collect();
 
-  let us = run_argparse(&mut parsed, apmaker, args.clone(), Some(extra_help));
+  let us = run_argparse(&mut parsed, apmaker, args.clone(),
+                        Some(extra_help), None);
 
   let completed = argparse_more(us, apmaker, || ap_completer(parsed));
   let (subcommand, subargs, mo) = completed;