From d376865c185d334d5e19035ce99e125d2ee9285a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Feb 2022 16:51:53 -0600 Subject: [PATCH] refactor: Clarify intent behind requires This is based on the work in #3384 --- src/build/app/mod.rs | 27 ++++++++++++++------------- src/build/arg/mod.rs | 16 ++++++++++------ src/parse/matches/matched_arg.rs | 10 ++++++++++ 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index ab811f0e..74b0f4e7 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -24,7 +24,7 @@ use yaml_rust::Yaml; // Internal use crate::{ - build::{arg::ArgProvider, Arg, ArgGroup, ArgSettings}, + build::{arg::ArgProvider, Arg, ArgGroup, ArgPredicate, ArgSettings}, mkeymap::MKeyMap, output::{fmt::Colorizer, Help, HelpWriter, Usage}, parse::{ArgMatcher, ArgMatches, Input, Parser}, @@ -3239,19 +3239,20 @@ impl<'help> App<'help> { } pub(crate) fn unroll_requirements_for_arg(&self, arg: &Id, matcher: &ArgMatcher) -> Vec { - let requires_if_or_not = |(val, req_arg): &(Option<&str>, Id)| -> Option { - if let Some(v) = val { - if matcher - .get(arg) - .map(|ma| ma.contains_val(v)) - .unwrap_or(false) - { - Some(req_arg.clone()) - } else { - None + let requires_if_or_not = |(val, req_arg): &(ArgPredicate<'_>, Id)| -> Option { + match val { + ArgPredicate::Equals(v) => { + if matcher + .get(arg) + .map(|ma| ma.contains_val_os(v)) + .unwrap_or(false) + { + Some(req_arg.clone()) + } else { + None + } } - } else { - Some(req_arg.clone()) + ArgPredicate::IsPresent => Some(req_arg.clone()), } }; diff --git a/src/build/arg/mod.rs b/src/build/arg/mod.rs index a649b2d1..4c9cdb5d 100644 --- a/src/build/arg/mod.rs +++ b/src/build/arg/mod.rs @@ -74,7 +74,7 @@ pub struct Arg<'help> { pub(crate) settings: ArgFlags, pub(crate) overrides: Vec, pub(crate) groups: Vec, - pub(crate) requires: Vec<(Option<&'help str>, Id)>, + pub(crate) requires: Vec<(ArgPredicate<'help>, Id)>, pub(crate) r_ifs: Vec<(Id, &'help str)>, pub(crate) r_ifs_all: Vec<(Id, &'help str)>, pub(crate) r_unless: Vec, @@ -681,7 +681,7 @@ impl<'help> Arg<'help> { /// [override]: Arg::overrides_with() #[must_use] pub fn requires(mut self, arg_id: T) -> Self { - self.requires.push((None, arg_id.into())); + self.requires.push((ArgPredicate::IsPresent, arg_id.into())); self } @@ -4111,7 +4111,8 @@ impl<'help> Arg<'help> { /// [override]: Arg::overrides_with() #[must_use] pub fn requires_if(mut self, val: &'help str, arg_id: T) -> Self { - self.requires.push((Some(val), arg_id.into())); + self.requires + .push((ArgPredicate::Equals(OsStr::new(val)), arg_id.into())); self } @@ -4163,8 +4164,10 @@ impl<'help> Arg<'help> { /// [override]: Arg::overrides_with() #[must_use] pub fn requires_ifs(mut self, ifs: &[(&'help str, T)]) -> Self { - self.requires - .extend(ifs.iter().map(|(val, arg)| (Some(*val), Id::from(arg)))); + self.requires.extend( + ifs.iter() + .map(|(val, arg)| (ArgPredicate::Equals(OsStr::new(*val)), Id::from(arg))), + ); self } @@ -4234,7 +4237,8 @@ impl<'help> Arg<'help> { /// [override]: Arg::overrides_with() #[must_use] pub fn requires_all(mut self, names: &[T]) -> Self { - self.requires.extend(names.iter().map(|s| (None, s.into()))); + self.requires + .extend(names.iter().map(|s| (ArgPredicate::IsPresent, s.into()))); self } diff --git a/src/parse/matches/matched_arg.rs b/src/parse/matches/matched_arg.rs index b993ec9b..5ea60827 100644 --- a/src/parse/matches/matched_arg.rs +++ b/src/parse/matches/matched_arg.rs @@ -127,6 +127,16 @@ impl MatchedArg { }) } + pub(crate) fn contains_val_os(&self, val: &OsStr) -> bool { + self.vals_flatten().any(|v| { + if self.ignore_case { + eq_ignore_case(&v.to_string_lossy(), &val.to_string_lossy()) + } else { + v.as_os_str() == val + } + }) + } + pub(crate) fn source(&self) -> ValueType { self.ty }