Fix positional count usage

This commit is contained in:
Donough Liu 2020-12-27 04:11:30 +08:00
parent 120e942e7a
commit 0f115f18ad
2 changed files with 13 additions and 10 deletions

View file

@ -10,8 +10,12 @@ pub(crate) struct Key {
#[derive(Default, PartialEq, Debug, Clone)] #[derive(Default, PartialEq, Debug, Clone)]
pub(crate) struct MKeyMap<'help> { pub(crate) struct MKeyMap<'help> {
keys: Vec<Key>, /// All of the arguments.
args: Vec<Arg<'help>>, args: Vec<Arg<'help>>,
// Cache part:
/// Will be set after `_build()`.
keys: Vec<Key>,
} }
#[derive(Debug, PartialEq, Eq, Hash, Clone)] #[derive(Debug, PartialEq, Eq, Hash, Clone)]
@ -112,6 +116,8 @@ impl<'help> MKeyMap<'help> {
self.args.iter_mut() self.args.iter_mut()
} }
/// We need a lazy build here since some we may change args after creating
/// the map, you can checkout who uses `args_mut`.
pub(crate) fn _build(&mut self) { pub(crate) fn _build(&mut self) {
for (i, arg) in self.args.iter_mut().enumerate() { for (i, arg) in self.args.iter_mut().enumerate() {
for k in _get_keys(arg) { for k in _get_keys(arg) {

View file

@ -109,6 +109,7 @@ impl<'help, 'app> Parser<'help, 'app> {
} }
} }
#[cfg(debug_assertions)]
fn _verify_positionals(&self) -> bool { fn _verify_positionals(&self) -> bool {
debug!("Parser::_verify_positionals"); debug!("Parser::_verify_positionals");
// Because you must wait until all arguments have been supplied, this is the first chance // Because you must wait until all arguments have been supplied, this is the first chance
@ -134,10 +135,10 @@ impl<'help, 'app> Parser<'help, 'app> {
//_highest_idx(&self.positionals); //_highest_idx(&self.positionals);
let num_p = self.app.args.keys().filter(|x| x.is_position()).count(); let num_p = self.app.args.keys().filter(|x| x.is_position()).count() as u64;
assert!( assert!(
highest_idx == num_p as u64, highest_idx == num_p,
"Found positional argument whose index is {} but there \ "Found positional argument whose index is {} but there \
are only {} positional arguments defined", are only {} positional arguments defined",
highest_idx, highest_idx,
@ -237,10 +238,7 @@ impl<'help, 'app> Parser<'help, 'app> {
// Check that if a required positional argument is found, all positions with a lower // Check that if a required positional argument is found, all positions with a lower
// index are also required // index are also required
let mut found = false; let mut found = false;
for p in (1..=num_p) for p in (1..=num_p).rev().filter_map(|n| self.app.args.get(&n)) {
.rev()
.filter_map(|n| self.app.args.get(&(n as u64)))
{
if found { if found {
assert!( assert!(
p.is_set(ArgSettings::Required), p.is_set(ArgSettings::Required),
@ -524,7 +522,7 @@ impl<'help, 'app> Parser<'help, 'app> {
// Came to -- and one positional has .last(true) set, so we go immediately // Came to -- and one positional has .last(true) set, so we go immediately
// to the last (highest index) positional // to the last (highest index) positional
debug!("Parser::get_matches_with: .last(true) and --, setting last pos"); debug!("Parser::get_matches_with: .last(true) and --, setting last pos");
pos_counter = self.app.args.keys().filter(|x| x.is_position()).count(); pos_counter = positional_count;
} }
if let Some(p) = self if let Some(p) = self
@ -543,8 +541,7 @@ impl<'help, 'app> Parser<'help, 'app> {
} }
if !self.is_set(AS::TrailingValues) if !self.is_set(AS::TrailingValues)
&& (self.is_set(AS::TrailingVarArg) && (self.is_set(AS::TrailingVarArg) && pos_counter == positional_count)
&& pos_counter == self.app.args.keys().filter(|x| x.is_position()).count())
{ {
self.app.settings.set(AS::TrailingValues); self.app.settings.set(AS::TrailingValues);
} }