From 4fd6881031732f2bc288a100099da6a4631d55c3 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 6 Jun 2021 23:03:22 +0100 Subject: [PATCH] otter: Introduce RawArgParserContext Signed-off-by: Ian Jackson --- cli/clisupport.rs | 77 ++++++++++++++++++++++++++++------------------- cli/otter.rs | 7 +++-- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/cli/clisupport.rs b/cli/clisupport.rs index 022351a4..fc8d1629 100644 --- a/cli/clisupport.rs +++ b/cli/clisupport.rs @@ -127,39 +127,52 @@ pub type ExtraMessage<'exh> = pub type ApCompleter<'apc,T,U> = &'apc dyn Fn(T) -> Result; -pub fn run_argparse(parsed: &mut T, apmaker: ApMaker, - args: Vec, - extra_help: Option, - extra_error: Option) - -> String /* us */{ - let ap = apmaker(parsed); - let us = args.get(0).expect("argv[0] must be provided!").clone(); - - let mut stdout = CookedStdout::new(); - let mut stderr = io::stderr(); - - let em_call = |em: Option, f| { - if let Some(em) = em { em(f).unwrap() }; - }; +pub struct RawArgParserContext<'a> { + pub ap: ArgumentParser<'a>, + pub us: String, + pub stdout: CookedStdout, + pub stderr: io::Stderr, +} + +impl<'a> RawArgParserContext<'a> { + pub fn new(args0: &[String], parsed: &'a mut T, apmaker: ApMaker) + -> Self + { + RawArgParserContext { + ap: apmaker(parsed), + us: args0.get(0).expect("argv[0] must be provided!").clone(), + stdout: CookedStdout::new(), + stderr: io::stderr(), + } + } - let r = ap.parse(args, &mut stdout, &mut stderr); - if let Err(rc) = r { - exit(match rc { - 0 => { - em_call(extra_help, &mut stdout); - 0 - }, - 2 => { - em_call(extra_error, &mut stderr); - EXIT_USAGE - }, - _ => panic!("unexpected error rc {} from ArgumentParser::parse", rc), - }); + pub fn run(&mut self, + args: Vec, + extra_help: Option, + extra_error: Option) { + let em_call = |em: Option, f| { + if let Some(em) = em { em(f).unwrap() }; + }; + + let r = self.ap.parse(args, &mut self.stdout, &mut self.stderr); + if let Err(rc) = r { + exit(match rc { + 0 => { + em_call(extra_help, &mut self.stdout); + 0 + }, + 2 => { + em_call(extra_error, &mut self.stderr); + EXIT_USAGE + }, + _ => panic!("unexpected error rc {} from ArgumentParser::parse", rc), + }); + } } - mem::drop(stdout); - mem::drop(ap); - us + pub fn done(self) -> String /* us */ { + self.us + } } pub fn argparse_more(us: String, apmaker: ApMaker, f: F) -> U @@ -176,7 +189,9 @@ pub fn parse_args( extra_help: Option, ) -> U { let mut parsed = default(); - let us = run_argparse(&mut parsed, apmaker, args, extra_help, None); + let mut rapc = RawArgParserContext::new(&args, &mut parsed, apmaker); + rapc.run(args, extra_help, None); + let us = rapc.done(); let completed = argparse_more(us, apmaker, || completer(parsed)); completed } diff --git a/cli/otter.rs b/cli/otter.rs index b8b2a3cc..a2b557be 100644 --- a/cli/otter.rs +++ b/cli/otter.rs @@ -321,8 +321,9 @@ fn main() { let mut parsed: RawMainArgs = default(); let args: Vec = env::args().collect(); - let us = run_argparse(&mut parsed, apmaker, args.clone(), - Some(extra_help), None); + let mut rapc = RawArgParserContext::new(&args, &mut parsed, apmaker); + rapc.run(args.clone(), Some(extra_help), None); + let us = rapc.done(); let completed = argparse_more(us, apmaker, || ap_completer(parsed)); let (subcommand, subargs, mo) = completed; @@ -330,7 +331,7 @@ fn main() { let stdout = CookedStdout::new(); let mut subargs = subargs; subargs.insert(0, format!("{} {}", - env::args().next().unwrap(), + &args[0], &subcommand)); (mo.sc.call)(SubCommandCallArgs { ma: mo, out: stdout, args: subargs }) -- 2.30.2