refactor(parser): encode all parsing state of FlagSubCommand in Parser

This commit is contained in:
rami3l 2021-05-29 21:26:21 +02:00
parent 65b3892ef6
commit a91ca7fc1b

View file

@ -24,8 +24,7 @@ use crate::{
pub(crate) enum ParseResult { pub(crate) enum ParseResult {
Flag, Flag,
FlagSubCommand(String), FlagSubCommand(String),
// subcommand name, whether there are more shorts args remaining FlagSubCommandShort(String),
FlagSubCommandShort(String, bool),
Opt(Id), Opt(Id),
Pos(Id), Pos(Id),
MaybeHyphenValue, MaybeHyphenValue,
@ -388,7 +387,7 @@ impl<'help, 'app> Parser<'help, 'app> {
subcmd_name = Some(name.to_owned()); subcmd_name = Some(name.to_owned());
break; break;
} }
ParseResult::FlagSubCommandShort(_, _) => unreachable!(), ParseResult::FlagSubCommandShort(_) => unreachable!(),
_ => (), _ => (),
} }
} else if arg_os.starts_with("-") } else if arg_os.starts_with("-")
@ -411,21 +410,18 @@ impl<'help, 'app> Parser<'help, 'app> {
ParseResult::Opt(..) | ParseResult::Flag | ParseResult::ValuesDone => { ParseResult::Opt(..) | ParseResult::Flag | ParseResult::ValuesDone => {
continue; continue;
} }
ParseResult::FlagSubCommandShort(ref name, done) => { ParseResult::FlagSubCommandShort(ref name) => {
// There are more short args, revisit the current short args skipping the subcommand // If there are more short flags to be processed, we should keep the state, and later
keep_state = !done; // revisit the current group of short flags skipping the subcommand.
if keep_state { keep_state = self
it.cursor -= 1; .flag_subcmd_at
// Here `self.flag_subcmd_at` can be safely unwrapped, because the only place to get a true `keep_state` .map(|at| {
// (ie. a false `done`) is in `Parser::parse_short_arg`, during which `self.flag_subcmd_at` should have it.cursor -= 1;
// been set anyway. // Since we are now saving the current state, the number of flags to skip during state recovery should
// If not, it's definitely an internal error! // be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position.
// Since we are now saving the current state, the number of flags to skip during state recovery should self.flag_subcmd_skip = self.cur_idx.get() - at + 1;
// be the current index (`cur_idx`) minus ONE UNIT TO THE LEFT of the starting position. })
self.flag_subcmd_skip = self.cur_idx.get() .is_some();
- self.flag_subcmd_at.expect(INTERNAL_ERROR_MSG)
+ 1;
}
debug!( debug!(
"Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}", "Parser::get_matches_with:FlagSubCommandShort: subcmd_name={}, keep_state={}, flag_subcmd_skip={}",
@ -1166,7 +1162,7 @@ impl<'help, 'app> Parser<'help, 'app> {
if done_short_args { if done_short_args {
self.flag_subcmd_at = None; self.flag_subcmd_at = None;
} }
return Ok(ParseResult::FlagSubCommandShort(name, done_short_args)); return Ok(ParseResult::FlagSubCommandShort(name));
} else { } else {
let arg = format!("-{}", c); let arg = format!("-{}", c);