From dd8435d8f34d8343db2a1bda76f05b699e08fbb3 Mon Sep 17 00:00:00 2001
From: Ed Page
Date: Thu, 22 Dec 2022 12:17:22 -0600
Subject: [PATCH] perf(parser): Reduce duplicate lookups
Didn't actually see much of a gain because this isn't in a hot loop but
thought I'd keep it.
---
src/parser/validator.rs | 54 ++++++++++++++++++++---------------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/src/parser/validator.rs b/src/parser/validator.rs
index 7b7cbf13bf5..088259ffd9f 100644
--- a/src/parser/validator.rs
+++ b/src/parser/validator.rs
@@ -54,8 +54,8 @@ impl<'cmd> Validator<'cmd> {
if !has_subcmd && self.cmd.is_arg_required_else_help_set() {
let num_user_values = matcher
- .arg_ids()
- .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
.count();
if num_user_values == 0 {
let message = self.cmd.write_help_err(false);
@@ -97,10 +97,10 @@ impl<'cmd> Validator<'cmd> {
ok!(self.validate_exclusive(matcher));
- for arg_id in matcher
- .arg_ids()
- .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
- .filter(|arg_id| self.cmd.find(arg_id).is_some())
+ for (arg_id, _) in matcher
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+ .filter(|(arg_id, _)| self.cmd.find(arg_id).is_some())
{
debug!("Validator::validate_conflicts::iter: id={:?}", arg_id);
let conflicts = conflicts.gather_conflicts(self.cmd, arg_id);
@@ -113,9 +113,9 @@ impl<'cmd> Validator<'cmd> {
fn validate_exclusive(&self, matcher: &ArgMatcher) -> ClapResult<()> {
debug!("Validator::validate_exclusive");
let args_count = matcher
- .arg_ids()
- .filter(|arg_id| {
- matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
+ .args()
+ .filter(|(arg_id, matched)| {
+ matched.check_explicit(&crate::builder::ArgPredicate::IsPresent)
// Avoid including our own groups by checking none of them. If a group is present, the
// args for the group will be.
&& self.cmd.find(arg_id).is_some()
@@ -127,14 +127,12 @@ impl<'cmd> Validator<'cmd> {
}
matcher
- .arg_ids()
- .filter(|arg_id| {
- matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
- })
- .filter_map(|name| {
- debug!("Validator::validate_exclusive:iter:{:?}", name);
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&crate::builder::ArgPredicate::IsPresent))
+ .filter_map(|(id, _)| {
+ debug!("Validator::validate_exclusive:iter:{:?}", id);
self.cmd
- .find(name)
+ .find(id)
// Find `arg`s which are exclusive but also appear with other args.
.filter(|&arg| arg.is_exclusive_set() && args_count > 1)
})
@@ -196,8 +194,9 @@ impl<'cmd> Validator<'cmd> {
conflicting_keys: &[Id],
) -> Option {
let used_filtered: Vec = matcher
- .arg_ids()
- .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+ .map(|(n, _)| n)
.filter(|n| {
// Filter out the args we don't want to specify.
self.cmd.find(n).map_or(false, |a| !a.is_hide_set())
@@ -220,14 +219,14 @@ impl<'cmd> Validator<'cmd> {
fn gather_requires(&mut self, matcher: &ArgMatcher) {
debug!("Validator::gather_requires");
- for name in matcher
- .arg_ids()
- .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+ for (name, matched) in matcher
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
{
debug!("Validator::gather_requires:iter:{:?}", name);
if let Some(arg) = self.cmd.find(name) {
let is_relevant = |(val, req_arg): &(ArgPredicate, Id)| -> Option {
- let required = matcher.check_explicit(arg.get_id(), val);
+ let required = matched.check_explicit(val);
required.then(|| req_arg.clone())
};
@@ -251,9 +250,9 @@ impl<'cmd> Validator<'cmd> {
let mut highest_index = 0;
let is_exclusive_present = matcher
- .arg_ids()
- .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
- .any(|id| {
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+ .any(|(id, _)| {
self.cmd
.find(id)
.map(|arg| arg.is_exclusive_set())
@@ -432,8 +431,9 @@ impl<'cmd> Validator<'cmd> {
);
let used: Vec = matcher
- .arg_ids()
- .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+ .args()
+ .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+ .map(|(n, _)| n)
.filter(|n| {
// Filter out the args we don't want to specify.
self.cmd.find(n).map_or(false, |a| !a.is_hide_set())