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<ExtraMessage>,
- extra_error: Option<ExtraMessage>)
- -> 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<ExtraMessage>, 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<T>(args0: &[String], parsed: &'a mut T, apmaker: ApMaker<T>)
+ -> 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<String>,
+ extra_help: Option<ExtraMessage>,
+ extra_error: Option<ExtraMessage>) {
+ let em_call = |em: Option<ExtraMessage>, 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<T,U,F>(us: String, apmaker: ApMaker<T>, f: F) -> U
extra_help: Option<ExtraMessage>,
) -> 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
}
let mut parsed: RawMainArgs = default();
let args: Vec<String> = 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;
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 })