refactor: Make it easier to get groups

This commit is contained in:
Ed Page 2021-12-23 11:15:11 -06:00
parent a37f2908c8
commit f24b9f50de
2 changed files with 38 additions and 60 deletions

View file

@ -3055,6 +3055,10 @@ impl<'help> App<'help> {
.map(|grp| grp.id.clone()) .map(|grp| grp.id.clone())
} }
pub(crate) fn find_group(&self, group_id: &Id) -> Option<&ArgGroup<'help>> {
self.groups.iter().find(|g| g.id == *group_id)
}
/// Iterate through all the names of all subcommands (not recursively), including aliases. /// Iterate through all the names of all subcommands (not recursively), including aliases.
/// Used for suggestions. /// Used for suggestions.
pub(crate) fn all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures<'help> { pub(crate) fn all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures<'help> {

View file

@ -228,7 +228,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
usg, usg,
)) ))
}) })
} else if let Some(g) = self.p.app.groups.iter().find(|x| x.id == *name) { } else if let Some(g) = self.p.app.find_group(name) {
let usg = Usage::new(self.p).create_usage_with_title(&[]); let usg = Usage::new(self.p).create_usage_with_title(&[]);
let args_in_group = self.p.app.unroll_args_in_group(&g.id); let args_in_group = self.p.app.unroll_args_in_group(&g.id);
let first = matcher let first = matcher
@ -263,30 +263,28 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
.filter(|&name| { .filter(|&name| {
debug!("Validator::validate_conflicts:iter:{:?}", name); debug!("Validator::validate_conflicts:iter:{:?}", name);
// Filter out the conflicting cases. // Filter out the conflicting cases.
if let Some(g) = self if let Some(g) = self.p.app.find_group(name) {
.p if !g.multiple {
.app let conf_with_self = || {
.groups self.p
.iter() .app
.find(|g| !g.multiple && g.id == *name) .unroll_args_in_group(&g.id)
{ .iter()
let conf_with_self = || { .filter(|&a| matcher.contains(a))
self.p .count()
.app > 1
.unroll_args_in_group(&g.id) };
.iter() let conf_with_arg = || g.conflicts.iter().any(|x| matcher.contains(x));
.filter(|&a| matcher.contains(a)) let arg_conf_with_gr = || {
.count() matcher
> 1 .arg_names()
}; .filter_map(|x| self.p.app.find(x))
let conf_with_arg = || g.conflicts.iter().any(|x| matcher.contains(x)); .any(|x| x.blacklist.iter().any(|c| *c == g.id))
let arg_conf_with_gr = || { };
matcher conf_with_self() || conf_with_arg() || arg_conf_with_gr()
.arg_names() } else {
.filter_map(|x| self.p.app.find(x)) false
.any(|x| x.blacklist.iter().any(|c| *c == g.id)) }
};
conf_with_self() || conf_with_arg() || arg_conf_with_gr()
} else if let Some(ma) = matcher.get(name) { } else if let Some(ma) = matcher.get(name) {
debug!( debug!(
"Validator::validate_conflicts:iter:{:?}: matcher contains it...", "Validator::validate_conflicts:iter:{:?}: matcher contains it...",
@ -351,45 +349,23 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
if let Some(arg) = self.p.app.find(name) { if let Some(arg) = self.p.app.find(name) {
// Since an arg was used, every arg it conflicts with is added to the conflicts // Since an arg was used, every arg it conflicts with is added to the conflicts
for conf in &arg.blacklist { for conf in &arg.blacklist {
/*
for g_arg in self.p.app.unroll_args_in_group(&g.name) {
if &g_arg != name {
c.insert(g.id.clone()); // TODO ERROR is here - groups allow one arg but this line disallows all group args
}
}
*/
c.insert(conf.clone()); c.insert(conf.clone());
} }
// Now we need to know which groups this arg was a member of, to add all other // Now we need to know which groups this arg was a member of, to add all other
// args in that group to the conflicts, as well as any args those args conflict // args in that group to the conflicts, as well as any args those args conflict
// with // with
for grp in self.p.app.groups_for_arg(name) { for grp in self.p.app.groups_for_arg(name) {
if let Some(g) = self if let Some(g) = self.p.app.find_group(&grp) {
.p if !g.multiple {
.app c.insert(g.id.clone());
.groups
.iter()
.find(|g| !g.multiple && g.id == grp)
{
/*
for g_arg in self.p.app.unroll_args_in_group(&g.name) {
if &g_arg != name {
c.insert(g.id.clone());
}
} }
*/
c.insert(g.id.clone());
} }
} }
} else if let Some(g) = self } else if let Some(g) = self.p.app.find_group(name) {
.p if !g.multiple {
.app debug!("Validator::gather_conflicts:iter:{:?}:group", name);
.groups c.insert(g.id.clone());
.iter() }
.find(|g| !g.multiple && g.id == *name)
{
debug!("Validator::gather_conflicts:iter:{:?}:group", name);
c.insert(g.id.clone());
} }
}); });
@ -404,7 +380,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
for req in self.p.app.unroll_requirements_for_arg(&arg.id, matcher) { for req in self.p.app.unroll_requirements_for_arg(&arg.id, matcher) {
self.p.required.insert(req); self.p.required.insert(req);
} }
} else if let Some(g) = self.p.app.groups.iter().find(|grp| grp.id == *name) { } else if let Some(g) = self.p.app.find_group(name) {
debug!("Validator::gather_requirements:iter:{:?}:group", name); debug!("Validator::gather_requirements:iter:{:?}:group", name);
for r in &g.requires { for r in &g.requires {
self.p.required.insert(r.clone()); self.p.required.insert(r.clone());
@ -549,7 +525,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
if !self.is_missing_required_ok(arg, matcher) { if !self.is_missing_required_ok(arg, matcher) {
return self.missing_required_error(matcher, vec![]); return self.missing_required_error(matcher, vec![]);
} }
} else if let Some(group) = self.p.app.groups.iter().find(|g| g.id == *arg_or_group) { } else if let Some(group) = self.p.app.find_group(arg_or_group) {
debug!("Validator::validate_required:iter: This is a group"); debug!("Validator::validate_required:iter: This is a group");
if !self if !self
.p .p
@ -596,9 +572,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
|| self || self
.p .p
.app .app
.groups .find_group(conf)
.iter()
.find(|g| g.id == *conf)
.map_or(false, |g| g.args.iter().any(|arg| matcher.contains(arg))) .map_or(false, |g| g.args.iter().any(|arg| matcher.contains(arg)))
}) })
} }