refactor: Clarify intent of default_value_if

While this doesn't help in the public API (yet), this at least clarifies
the intent in the implementation.

This is building towards #3020.
This commit is contained in:
Ed Page 2022-02-01 16:38:03 -06:00
parent dc035de409
commit c0b12c7260
4 changed files with 25 additions and 6 deletions

View file

@ -0,0 +1,14 @@
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum ArgPredicate<'help> {
IsPresent,
Equals(&'help std::ffi::OsStr),
}
impl<'help> From<Option<&'help std::ffi::OsStr>> for ArgPredicate<'help> {
fn from(other: Option<&'help std::ffi::OsStr>) -> Self {
match other {
Some(other) => Self::Equals(other),
None => Self::IsPresent,
}
}
}

View file

@ -1,3 +1,4 @@
mod arg_predicate;
#[cfg(debug_assertions)]
pub mod debug_asserts;
mod possible_value;
@ -9,6 +10,7 @@ mod value_hint;
pub use self::possible_value::PossibleValue;
pub use self::settings::{ArgFlags, ArgSettings};
pub use self::value_hint::ValueHint;
pub(crate) use arg_predicate::ArgPredicate;
// Std
use std::{
@ -92,7 +94,7 @@ pub struct Arg<'help> {
pub(crate) validator_os: Option<Arc<Mutex<ValidatorOs<'help>>>>,
pub(crate) val_delim: Option<char>,
pub(crate) default_vals: Vec<&'help OsStr>,
pub(crate) default_vals_ifs: Vec<(Id, Option<&'help OsStr>, Option<&'help OsStr>)>,
pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate<'help>, Option<&'help OsStr>)>,
pub(crate) default_missing_vals: Vec<&'help OsStr>,
#[cfg(feature = "env")]
pub(crate) env: Option<(&'help OsStr, Option<OsString>)>,
@ -3486,7 +3488,8 @@ impl<'help> Arg<'help> {
val: Option<&'help OsStr>,
default: Option<&'help OsStr>,
) -> Self {
self.default_vals_ifs.push((arg_id.into(), val, default));
self.default_vals_ifs
.push((arg_id.into(), val.into(), default));
self.takes_value(true)
}

View file

@ -12,3 +12,4 @@ pub use self::{
arg::{Arg, ArgFlags, ArgSettings, PossibleValue, ValueHint},
arg_group::ArgGroup,
};
pub(crate) use arg::ArgPredicate;

View file

@ -1325,10 +1325,11 @@ impl<'help, 'app> Parser<'help, 'app> {
if matcher.get(&arg.id).is_none() {
for (id, val, default) in arg.default_vals_ifs.iter() {
let add = if let Some(a) = matcher.get(id) {
if let Some(v) = val {
a.vals_flatten().any(|value| v == value)
} else {
true
match val {
crate::build::ArgPredicate::Equals(v) => {
a.vals_flatten().any(|value| v == value)
}
crate::build::ArgPredicate::IsPresent => true,
}
} else {
false