mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 22:32:33 +00:00
Merge #2078
2078: Unify naming cheme r=pksunkara a=CreepySkeleton Co-authored-by: CreepySkeleton <creepy-skeleton@yandex.ru>
This commit is contained in:
commit
025ec3c28b
9 changed files with 160 additions and 135 deletions
|
@ -315,7 +315,7 @@ where
|
|||
.arg(flag("help"))
|
||||
.arg(flag("version").short('V'))
|
||||
// First, set up primary positional/flag arguments.
|
||||
.arg(arg("pattern").required_unless_one(&[
|
||||
.arg(arg("pattern").required_unless_eq_any(&[
|
||||
"file",
|
||||
"files",
|
||||
"help-short",
|
||||
|
|
|
@ -79,7 +79,7 @@ fn main() {
|
|||
Arg::new("package")
|
||||
.about("packages")
|
||||
.multiple(true)
|
||||
.required_unless_one(&["search"])
|
||||
.required_unless_present("search")
|
||||
.takes_value(true),
|
||||
),
|
||||
)
|
||||
|
|
|
@ -138,7 +138,7 @@ pub(crate) fn assert_app(app: &App) {
|
|||
for req in &arg.r_ifs {
|
||||
assert!(
|
||||
app.id_exists(&req.0),
|
||||
"Argument or group '{:?}' specified in 'required_if*' for '{}' does not exist",
|
||||
"Argument or group '{:?}' specified in 'required_if_eq*' for '{}' does not exist",
|
||||
req.0,
|
||||
arg.name
|
||||
);
|
||||
|
|
|
@ -624,10 +624,9 @@ impl<'help> Arg<'help> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets an arg that override this arg's required setting. (i.e. this arg will be required
|
||||
/// unless this other argument is present).
|
||||
/// Set this arg as [required] as long as the specified argument is not present at runtime.
|
||||
///
|
||||
/// **Pro Tip:** Using [`Arg::required_unless`] implies [`Arg::required`] and is therefore not
|
||||
/// **Pro Tip:** Using `Arg::required_unless_present` implies [`Arg::required`] and is therefore not
|
||||
/// mandatory to also set.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -635,19 +634,18 @@ impl<'help> Arg<'help> {
|
|||
/// ```rust
|
||||
/// # use clap::Arg;
|
||||
/// Arg::new("config")
|
||||
/// .required_unless("debug")
|
||||
/// .required_unless_present("debug")
|
||||
/// # ;
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_unless(name)`] requires that the argument be used at runtime
|
||||
/// *unless* `name` is present. In the following example, the required argument is *not*
|
||||
/// provided, but it's not an error because the `unless` arg has been supplied.
|
||||
/// In the following example, the required argument is *not* provided,
|
||||
/// but it's not an error because the `unless` arg has been supplied.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_unless("dbg")
|
||||
/// .required_unless_present("dbg")
|
||||
/// .takes_value(true)
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("dbg")
|
||||
|
@ -659,13 +657,13 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_ok());
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_unless(name)`] and *not* supplying `name` or this arg is an error.
|
||||
/// Setting `Arg::required_unless_present(name)` and *not* supplying `name` or this arg is an error.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_unless("dbg")
|
||||
/// .required_unless_present("dbg")
|
||||
/// .takes_value(true)
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("dbg")
|
||||
|
@ -677,39 +675,38 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_err());
|
||||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
||||
/// ```
|
||||
/// [`Arg::required_unless`]: ./struct.Arg.html#method.required_unless
|
||||
/// [`Arg::required`]: ./struct.Arg.html#method.required
|
||||
/// [`Arg::required_unless(name)`]: ./struct.Arg.html#method.required_unless
|
||||
pub fn required_unless<T: Key>(mut self, arg_id: T) -> Self {
|
||||
/// [required]: ./struct.Arg.html#method.required
|
||||
pub fn required_unless_present<T: Key>(mut self, arg_id: T) -> Self {
|
||||
self.r_unless.push(arg_id.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets args that override this arg's required setting. (i.e. this arg will be required unless
|
||||
/// all these other arguments are present).
|
||||
/// Sets this arg as [required] unless *all* of the specified arguments are present at runtime.
|
||||
///
|
||||
/// In other words, parsing will succeed only if user either
|
||||
/// * supplies the `self` arg.
|
||||
/// * supplies *all* of the `names` arguments.
|
||||
///
|
||||
/// **NOTE:** If you wish for this argument to only be required if *one of* these args are
|
||||
/// present see [`Arg::required_unless_one`]
|
||||
/// present see [`Arg::required_unless_eq_any`]
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::Arg;
|
||||
/// Arg::new("config")
|
||||
/// .required_unless_all(&["cfg", "dbg"])
|
||||
/// .required_unless_eq_all(&["cfg", "dbg"])
|
||||
/// # ;
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_unless_all(names)`] requires that the argument be used at runtime
|
||||
/// *unless* *all* the args in `names` are present. In the following example, the required
|
||||
/// argument is *not* provided, but it's not an error because all the `unless` args have been
|
||||
/// supplied.
|
||||
/// In the following example, the required argument is *not* provided, but it's not an error
|
||||
/// because *all* of the `names` args have been supplied.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_unless_all(&["dbg", "infile"])
|
||||
/// .required_unless_eq_all(&["dbg", "infile"])
|
||||
/// .takes_value(true)
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("dbg")
|
||||
|
@ -724,14 +721,14 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_ok());
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_unless_all(names)`] and *not* supplying *all* of `names` or this
|
||||
/// arg is an error.
|
||||
/// Setting [`Arg::required_unless_eq_all(names)`] and *not* supplying
|
||||
/// either *all* of `unless` args or the `self` arg is an error.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_unless_all(&["dbg", "infile"])
|
||||
/// .required_unless_eq_all(&["dbg", "infile"])
|
||||
/// .takes_value(true)
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("dbg")
|
||||
|
@ -746,29 +743,33 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_err());
|
||||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
||||
/// ```
|
||||
/// [`Arg::required_unless_one`]: ./struct.Arg.html#method.required_unless_one
|
||||
/// [`Arg::required_unless_all(names)`]: ./struct.Arg.html#method.required_unless_all
|
||||
pub fn required_unless_all(mut self, names: &[&str]) -> Self {
|
||||
self.r_unless.extend(names.iter().map(Id::from));
|
||||
/// [`Arg::required_unless_eq_any`]: ./struct.Arg.html#method.required_unless_eq_any
|
||||
/// [`Arg::required_unless_eq_all(names)`]: ./struct.Arg.html#method.required_unless_eq_all
|
||||
pub fn required_unless_eq_all<T, I>(mut self, names: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Key,
|
||||
{
|
||||
self.r_unless.extend(names.into_iter().map(Id::from));
|
||||
self.setting(ArgSettings::RequiredUnlessAll)
|
||||
}
|
||||
|
||||
/// Sets args that override this arg's [required] setting. (i.e. this arg will be required
|
||||
/// unless *at least one of* these other arguments are present).
|
||||
/// Sets this arg as [required] unless *any* of the specified arguments are present at runtime.
|
||||
///
|
||||
/// **NOTE:** If you wish for this argument to only be required if *all of* these args are
|
||||
/// present see [`Arg::required_unless_all`]
|
||||
/// In other words, parsing will succeed only if user either
|
||||
/// * supplies the `self` arg.
|
||||
/// * supplies *one or more* of the `unless` arguments.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::Arg;
|
||||
/// Arg::new("config")
|
||||
/// .required_unless_all(&["cfg", "dbg"])
|
||||
/// .required_unless_eq_all(&["cfg", "dbg"])
|
||||
/// # ;
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_unless_one(names)`] requires that the argument be used at runtime
|
||||
/// Setting [`Arg::required_unless_eq_any(names)`] requires that the argument be used at runtime
|
||||
/// *unless* *at least one of* the args in `names` are present. In the following example, the
|
||||
/// required argument is *not* provided, but it's not an error because one the `unless` args
|
||||
/// have been supplied.
|
||||
|
@ -777,7 +778,7 @@ impl<'help> Arg<'help> {
|
|||
/// # use clap::{App, Arg};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_unless_one(&["dbg", "infile"])
|
||||
/// .required_unless_eq_any(&["dbg", "infile"])
|
||||
/// .takes_value(true)
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("dbg")
|
||||
|
@ -792,14 +793,14 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_ok());
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_unless_one(names)`] and *not* supplying *at least one of* `names`
|
||||
/// Setting [`Arg::required_unless_eq_any(names)`] and *not* supplying *at least one of* `names`
|
||||
/// or this arg is an error.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_unless_one(&["dbg", "infile"])
|
||||
/// .required_unless_eq_any(&["dbg", "infile"])
|
||||
/// .takes_value(true)
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("dbg")
|
||||
|
@ -815,10 +816,14 @@ impl<'help> Arg<'help> {
|
|||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
||||
/// ```
|
||||
/// [required]: ./struct.Arg.html#method.required
|
||||
/// [`Arg::required_unless_one(names)`]: ./struct.Arg.html#method.required_unless_one
|
||||
/// [`Arg::required_unless_all`]: ./struct.Arg.html#method.required_unless_all
|
||||
pub fn required_unless_one(mut self, names: &[&str]) -> Self {
|
||||
self.r_unless.extend(names.iter().map(Id::from));
|
||||
/// [`Arg::required_unless_eq_any(names)`]: ./struct.Arg.html#method.required_unless_eq_any
|
||||
/// [`Arg::required_unless_eq_all`]: ./struct.Arg.html#method.required_unless_eq_all
|
||||
pub fn required_unless_eq_any<T, I>(mut self, names: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
T: Key,
|
||||
{
|
||||
self.r_unless.extend(names.into_iter().map(Id::from));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -866,7 +871,6 @@ impl<'help> Arg<'help> {
|
|||
///
|
||||
/// [`Arg::conflicts_with_all(names)`]: ./struct.Arg.html#method.conflicts_with_all
|
||||
/// [`Arg::exclusive(true)`]: ./struct.Arg.html#method.exclusive
|
||||
|
||||
pub fn conflicts_with<T: Key>(mut self, arg_id: T) -> Self {
|
||||
self.blacklist.push(arg_id.into());
|
||||
self
|
||||
|
@ -1165,8 +1169,11 @@ impl<'help> Arg<'help> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Allows a conditional requirement. The requirement will only become valid if this arg's value
|
||||
/// equals `val`.
|
||||
/// Require another argument if this arg was present on runtime, and its value equals to `val`.
|
||||
///
|
||||
/// This method takes `value, another_arg` pair. At runtime, clap will check
|
||||
/// if this arg (`self`) is is present and its value equals to `val`.
|
||||
/// If it does, `another_arg` will be marked as required.
|
||||
///
|
||||
/// **NOTE:** If using YAML the values should be laid out as follows
|
||||
///
|
||||
|
@ -1286,13 +1293,13 @@ impl<'help> Arg<'help> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Allows specifying that an argument is [required] conditionally. The requirement will only
|
||||
/// become valid if the specified `arg`'s value equals `val`.
|
||||
/// Allows specifying that this argument is [required] only if the specified
|
||||
/// `arg` is present at runtime and its value equals `val`.
|
||||
///
|
||||
/// **NOTE:** If using YAML the values should be laid out as follows
|
||||
///
|
||||
/// ```yaml
|
||||
/// required_if:
|
||||
/// required_if_eq:
|
||||
/// - [arg, val]
|
||||
/// ```
|
||||
///
|
||||
|
@ -1301,20 +1308,16 @@ impl<'help> Arg<'help> {
|
|||
/// ```rust
|
||||
/// # use clap::Arg;
|
||||
/// Arg::new("config")
|
||||
/// .required_if("other_arg", "value")
|
||||
/// .required_if_eq("other_arg", "value")
|
||||
/// # ;
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_if(arg, val)`] makes this arg required if the `arg` is used at
|
||||
/// runtime and it's value is equal to `val`. If the `arg`'s value is anything other than `val`,
|
||||
/// this argument isn't required.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg};
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .takes_value(true)
|
||||
/// .required_if("other", "special")
|
||||
/// .required_if_eq("other", "special")
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("other")
|
||||
/// .long("other")
|
||||
|
@ -1324,17 +1327,11 @@ impl<'help> Arg<'help> {
|
|||
/// ]);
|
||||
///
|
||||
/// assert!(res.is_ok()); // We didn't use --other=special, so "cfg" wasn't required
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_if(arg, val)`] and having `arg` used with a value of `val` but *not*
|
||||
/// using this arg is an error.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .takes_value(true)
|
||||
/// .required_if("other", "special")
|
||||
/// .required_if_eq("other", "special")
|
||||
/// .long("config"))
|
||||
/// .arg(Arg::new("other")
|
||||
/// .long("other")
|
||||
|
@ -1343,25 +1340,26 @@ impl<'help> Arg<'help> {
|
|||
/// "prog", "--other", "special"
|
||||
/// ]);
|
||||
///
|
||||
/// // We did use --other=special so "cfg" had become required but was missing.
|
||||
/// assert!(res.is_err());
|
||||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
||||
/// ```
|
||||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [required]: ./struct.Arg.html#method.required
|
||||
pub fn required_if<T: Key>(mut self, arg_id: T, val: &'help str) -> Self {
|
||||
pub fn required_if_eq<T: Key>(mut self, arg_id: T, val: &'help str) -> Self {
|
||||
self.r_ifs.push((arg_id.into(), val));
|
||||
self
|
||||
}
|
||||
|
||||
/// Allows specifying that an argument is [required] based on multiple conditions. The
|
||||
/// Allows specifying that this argument is [required] based on multiple conditions. The
|
||||
/// conditions are set up in a `(arg, val)` style tuple. The requirement will only become valid
|
||||
/// if one of the specified `arg`'s value equals it's corresponding `val`.
|
||||
///
|
||||
/// **NOTE:** If using YAML the values should be laid out as follows
|
||||
///
|
||||
/// ```yaml
|
||||
/// required_if:
|
||||
/// required_if_eq:
|
||||
/// - [arg, val]
|
||||
/// - [arg2, val2]
|
||||
/// ```
|
||||
|
@ -1371,14 +1369,14 @@ impl<'help> Arg<'help> {
|
|||
/// ```rust
|
||||
/// # use clap::Arg;
|
||||
/// Arg::new("config")
|
||||
/// .required_ifs(&[
|
||||
/// .required_if_eq_any(&[
|
||||
/// ("extra", "val"),
|
||||
/// ("option", "spec")
|
||||
/// ])
|
||||
/// # ;
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_ifs(&[(arg, val)])`] makes this arg required if any of the `arg`s
|
||||
/// Setting [`Arg::required_if_eq_any(&[(arg, val)])`] makes this arg required if any of the `arg`s
|
||||
/// are used at runtime and it's corresponding value is equal to `val`. If the `arg`'s value is
|
||||
/// anything other than `val`, this argument isn't required.
|
||||
///
|
||||
|
@ -1386,7 +1384,7 @@ impl<'help> Arg<'help> {
|
|||
/// # use clap::{App, Arg};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_ifs(&[
|
||||
/// .required_if_eq_any(&[
|
||||
/// ("extra", "val"),
|
||||
/// ("option", "spec")
|
||||
/// ])
|
||||
|
@ -1405,14 +1403,14 @@ impl<'help> Arg<'help> {
|
|||
/// assert!(res.is_ok()); // We didn't use --option=spec, or --extra=val so "cfg" isn't required
|
||||
/// ```
|
||||
///
|
||||
/// Setting [`Arg::required_ifs(&[(arg, val)])`] and having any of the `arg`s used with its
|
||||
/// Setting [`Arg::required_if_eq_any(&[(arg, val)])`] and having any of the `arg`s used with it's
|
||||
/// value of `val` but *not* using this arg is an error.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use clap::{App, Arg, ErrorKind};
|
||||
/// let res = App::new("prog")
|
||||
/// .arg(Arg::new("cfg")
|
||||
/// .required_ifs(&[
|
||||
/// .required_if_eq_any(&[
|
||||
/// ("extra", "val"),
|
||||
/// ("option", "spec")
|
||||
/// ])
|
||||
|
@ -1434,7 +1432,7 @@ impl<'help> Arg<'help> {
|
|||
/// [`Arg::requires(name)`]: ./struct.Arg.html#method.requires
|
||||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [required]: ./struct.Arg.html#method.required
|
||||
pub fn required_ifs<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
|
||||
pub fn required_if_eq_any<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
|
||||
self.r_ifs
|
||||
.extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val)));
|
||||
self
|
||||
|
@ -4279,15 +4277,15 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
a = match k.as_str().unwrap() {
|
||||
"short" => yaml_to_char!(a, v, short),
|
||||
"long" => yaml_to_str!(a, v, long),
|
||||
"aliases" => yaml_vec_or_str!(v, a, alias),
|
||||
"aliases" => yaml_vec_or_str!(a, v, alias),
|
||||
"short_aliases" => yaml_to_chars!(a, v, short_aliases),
|
||||
"about" => yaml_to_str!(a, v, about),
|
||||
"long_about" => yaml_to_str!(a, v, long_about),
|
||||
"help" => yaml_to_str!(a, v, about),
|
||||
"long_help" => yaml_to_str!(a, v, long_about),
|
||||
"required" => yaml_to_bool!(a, v, required),
|
||||
"required_if" => yaml_tuple2!(a, v, required_if),
|
||||
"required_ifs" => yaml_tuple2!(a, v, required_if),
|
||||
"required_if_eq" => yaml_tuple2!(a, v, required_if_eq),
|
||||
"required_if_eq_any" => yaml_tuple2!(a, v, required_if_eq),
|
||||
"takes_value" => yaml_to_bool!(a, v, takes_value),
|
||||
"index" => yaml_to_u64!(a, v, index),
|
||||
"global" => yaml_to_bool!(a, v, global),
|
||||
|
@ -4304,28 +4302,28 @@ impl<'help> From<&'help Yaml> for Arg<'help> {
|
|||
"require_equals" => yaml_to_bool!(a, v, require_equals),
|
||||
"require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
|
||||
"value_delimiter" => yaml_to_str!(a, v, value_delimiter),
|
||||
"required_unless" => yaml_to_str!(a, v, required_unless),
|
||||
"required_unless_present" => yaml_to_str!(a, v, required_unless_present),
|
||||
"display_order" => yaml_to_usize!(a, v, display_order),
|
||||
"default_value" => yaml_to_str!(a, v, default_value),
|
||||
"default_value_if" => yaml_tuple3!(a, v, default_value_if),
|
||||
"default_value_ifs" => yaml_tuple3!(a, v, default_value_if),
|
||||
"default_missing_value" => yaml_to_str!(a, v, default_missing_value),
|
||||
"env" => yaml_to_str!(a, v, env),
|
||||
"value_names" => yaml_vec_or_str!(v, a, value_name),
|
||||
"groups" => yaml_vec_or_str!(v, a, group),
|
||||
"requires" => yaml_vec_or_str!(v, a, requires),
|
||||
"value_names" => yaml_vec_or_str!(a, v, value_name),
|
||||
"groups" => yaml_vec_or_str!(a, v, group),
|
||||
"requires" => yaml_vec_or_str!(a, v, requires),
|
||||
"requires_if" => yaml_tuple2!(a, v, requires_if),
|
||||
"requires_ifs" => yaml_tuple2!(a, v, requires_if),
|
||||
"conflicts_with" => yaml_vec_or_str!(v, a, conflicts_with),
|
||||
"conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
|
||||
"exclusive" => yaml_to_bool!(a, v, exclusive),
|
||||
"value_hint" => yaml_str_parse!(a, v, value_hint),
|
||||
"hide_default_value" => yaml_to_bool!(a, v, hide_default_value),
|
||||
"overrides_with" => yaml_vec_or_str!(v, a, overrides_with),
|
||||
"possible_values" => yaml_vec_or_str!(v, a, possible_value),
|
||||
"overrides_with" => yaml_vec_or_str!(a, v, overrides_with),
|
||||
"possible_values" => yaml_vec_or_str!(a, v, possible_value),
|
||||
"case_insensitive" => yaml_to_bool!(a, v, case_insensitive),
|
||||
"required_unless_one" => yaml_vec_or_str!(v, a, required_unless),
|
||||
"required_unless_all" => {
|
||||
a = yaml_vec_or_str!(v, a, required_unless);
|
||||
"required_unless_eq_any" => yaml_vec!(a, v, required_unless_eq_any),
|
||||
"required_unless_eq_all" => {
|
||||
a = yaml_vec!(a, v, required_unless_eq_all);
|
||||
a.set_mut(ArgSettings::RequiredUnlessAll);
|
||||
a
|
||||
}
|
||||
|
|
|
@ -442,15 +442,15 @@ impl<'help> From<&'help Yaml> for ArgGroup<'help> {
|
|||
a = match k.as_str().unwrap() {
|
||||
"required" => a.required(v.as_bool().unwrap()),
|
||||
"multiple" => a.multiple(v.as_bool().unwrap()),
|
||||
"args" => yaml_vec_or_str!(v, a, arg),
|
||||
"args" => yaml_vec_or_str!(a, v, arg),
|
||||
"arg" => {
|
||||
if let Some(ys) = v.as_str() {
|
||||
a = a.arg(ys);
|
||||
}
|
||||
a
|
||||
}
|
||||
"requires" => yaml_vec_or_str!(v, a, requires),
|
||||
"conflicts_with" => yaml_vec_or_str!(v, a, conflicts_with),
|
||||
"requires" => yaml_vec_or_str!(a, v, requires),
|
||||
"conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
|
||||
"name" => {
|
||||
if let Some(ys) = v.as_str() {
|
||||
a.name = ys;
|
||||
|
|
|
@ -38,7 +38,7 @@ macro_rules! yaml_tuple3 {
|
|||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_vec_or_str {
|
||||
($v:ident, $a:ident, $c:ident) => {{
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
let maybe_vec = $v.as_vec();
|
||||
if let Some(vec) = maybe_vec {
|
||||
for ys in vec {
|
||||
|
@ -62,6 +62,26 @@ macro_rules! yaml_vec_or_str {
|
|||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_vec {
|
||||
($a:ident, $v:ident, $c:ident) => {{
|
||||
let maybe_vec = $v.as_vec();
|
||||
if let Some(vec) = maybe_vec {
|
||||
let content = vec.into_iter().map(|ys| {
|
||||
if let Some(s) = ys.as_str() {
|
||||
s
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a string", ys);
|
||||
}
|
||||
});
|
||||
$a = $a.$c(content)
|
||||
} else {
|
||||
panic!("Failed to convert YAML value {:?} to a vec", $v);
|
||||
}
|
||||
$a
|
||||
}};
|
||||
}
|
||||
|
||||
#[cfg(feature = "yaml")]
|
||||
macro_rules! yaml_opt_str {
|
||||
($v:expr) => {{
|
||||
|
|
|
@ -400,7 +400,7 @@ fn conditional_reqs_fail() {
|
|||
.arg(
|
||||
Arg::new("output")
|
||||
.takes_value(true)
|
||||
.required_if("target", "file")
|
||||
.required_if_eq("target", "file")
|
||||
.long("output"),
|
||||
)
|
||||
.try_get_matches_from(vec!["test", "--input", "some"]);
|
||||
|
@ -431,7 +431,7 @@ fn conditional_reqs_pass() {
|
|||
.arg(
|
||||
Arg::new("output")
|
||||
.takes_value(true)
|
||||
.required_if("target", "file")
|
||||
.required_if_eq("target", "file")
|
||||
.long("output"),
|
||||
)
|
||||
.try_get_matches_from(vec!["test", "--input", "some", "--output", "other"]);
|
||||
|
|
4
tests/fixtures/app.yaml
vendored
4
tests/fixtures/app.yaml
vendored
|
@ -77,7 +77,7 @@ args:
|
|||
long: singlealias
|
||||
about: Tests single alias
|
||||
aliases: [alias]
|
||||
required_if:
|
||||
required_if_eq:
|
||||
- [multvalsmo, two]
|
||||
- multaliases:
|
||||
long: multaliases
|
||||
|
@ -87,7 +87,7 @@ args:
|
|||
long: singleshortalias
|
||||
about: Tests single short alias
|
||||
short_aliases: [a]
|
||||
required_if:
|
||||
required_if_eq:
|
||||
- [multvalsmo, two]
|
||||
- multshortaliases:
|
||||
long: multshortaliases
|
||||
|
|
|
@ -199,25 +199,28 @@ fn issue_753() {
|
|||
))
|
||||
.arg(
|
||||
Arg::from("-i, --iface=[INTERFACE] 'Ethernet interface for fetching NTP packets'")
|
||||
.required_unless("list"),
|
||||
.required_unless_present("list"),
|
||||
)
|
||||
.arg(
|
||||
Arg::from("-f, --file=[TESTFILE] 'Fetch NTP packets from pcap file'")
|
||||
.conflicts_with("iface")
|
||||
.required_unless("list"),
|
||||
.required_unless_present("list"),
|
||||
)
|
||||
.arg(
|
||||
Arg::from("-s, --server=[SERVER_IP] 'NTP server IP address'")
|
||||
.required_unless_present("list"),
|
||||
)
|
||||
.arg(Arg::from("-s, --server=[SERVER_IP] 'NTP server IP address'").required_unless("list"))
|
||||
.arg(Arg::from("-p, --port=[SERVER_PORT] 'NTP server port'").default_value("123"))
|
||||
.try_get_matches_from(vec!["test", "--list"]);
|
||||
assert!(m.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless() {
|
||||
fn required_unless_present() {
|
||||
let res = App::new("unlesstest")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless("dbg")
|
||||
.required_unless_present("dbg")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -235,7 +238,7 @@ fn required_unless_err() {
|
|||
let res = App::new("unlesstest")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless("dbg")
|
||||
.required_unless_present("dbg")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -249,11 +252,11 @@ fn required_unless_err() {
|
|||
// REQUIRED_UNLESS_ALL
|
||||
|
||||
#[test]
|
||||
fn required_unless_all() {
|
||||
fn required_unless_eq_all() {
|
||||
let res = App::new("unlessall")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless_all(&["dbg", "infile"])
|
||||
.required_unless_eq_all(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -273,7 +276,7 @@ fn required_unless_all_err() {
|
|||
let res = App::new("unlessall")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless_all(&["dbg", "infile"])
|
||||
.required_unless_eq_all(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -288,11 +291,11 @@ fn required_unless_all_err() {
|
|||
// REQUIRED_UNLESS_ONE
|
||||
|
||||
#[test]
|
||||
fn required_unless_one() {
|
||||
fn required_unless_eq_any() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.required_unless_eq_any(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -307,13 +310,13 @@ fn required_unless_one() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_2() {
|
||||
// This tests that the required_unless_one works when the second arg in the array is used
|
||||
fn required_unless_any_2() {
|
||||
// This tests that the required_unless_eq_any works when the second arg in the array is used
|
||||
// instead of the first.
|
||||
let res = App::new("unlessone")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.required_unless_eq_any(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -328,48 +331,48 @@ fn required_unless_one_2() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_works_with_short() {
|
||||
fn required_unless_any_works_with_short() {
|
||||
// GitHub issue: https://github.com/kbknapp/clap-rs/issues/1135
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::new("a").conflicts_with("b").short('a'))
|
||||
.arg(Arg::new("b").short('b'))
|
||||
.arg(Arg::new("x").short('x').required_unless_one(&["a", "b"]))
|
||||
.arg(Arg::new("x").short('x').required_unless_eq_any(&["a", "b"]))
|
||||
.try_get_matches_from(vec!["unlessone", "-a"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_works_with_short_err() {
|
||||
fn required_unless_any_works_with_short_err() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::new("a").conflicts_with("b").short('a'))
|
||||
.arg(Arg::new("b").short('b'))
|
||||
.arg(Arg::new("x").short('x').required_unless_one(&["a", "b"]))
|
||||
.arg(Arg::new("x").short('x').required_unless_eq_any(&["a", "b"]))
|
||||
.try_get_matches_from(vec!["unlessone"]);
|
||||
|
||||
assert!(!res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_works_without() {
|
||||
fn required_unless_any_works_without() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::new("a").conflicts_with("b").short('a'))
|
||||
.arg(Arg::new("b").short('b'))
|
||||
.arg(Arg::new("x").required_unless_one(&["a", "b"]))
|
||||
.arg(Arg::new("x").required_unless_eq_any(&["a", "b"]))
|
||||
.try_get_matches_from(vec!["unlessone", "-a"]);
|
||||
|
||||
assert!(res.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_works_with_long() {
|
||||
fn required_unless_any_works_with_long() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(Arg::new("a").conflicts_with("b").short('a'))
|
||||
.arg(Arg::new("b").short('b'))
|
||||
.arg(
|
||||
Arg::new("x")
|
||||
.long("x_is_the_option")
|
||||
.required_unless_one(&["a", "b"]),
|
||||
.required_unless_eq_any(&["a", "b"]),
|
||||
)
|
||||
.try_get_matches_from(vec!["unlessone", "-a"]);
|
||||
|
||||
|
@ -377,11 +380,11 @@ fn required_unless_one_works_with_long() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_1() {
|
||||
fn required_unless_any_1() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.required_unless_eq_any(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -397,11 +400,11 @@ fn required_unless_one_1() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn required_unless_one_err() {
|
||||
fn required_unless_any_err() {
|
||||
let res = App::new("unlessone")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_unless_one(&["dbg", "infile"])
|
||||
.required_unless_eq_any(&["dbg", "infile"])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -496,7 +499,7 @@ fn required_if_val_present_pass() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_if("extra", "val")
|
||||
.required_if_eq("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -511,7 +514,7 @@ fn required_if_val_present_fail() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_if("extra", "val")
|
||||
.required_if_eq("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -578,7 +581,7 @@ fn required_if_val_present_fail_error_output() {
|
|||
.arg(
|
||||
Arg::new("output")
|
||||
.takes_value(true)
|
||||
.required_if("target", "file")
|
||||
.required_if_eq("target", "file")
|
||||
.long("output"),
|
||||
);
|
||||
|
||||
|
@ -595,7 +598,7 @@ fn required_if_wrong_val() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_if("extra", "val")
|
||||
.required_if_eq("extra", "val")
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -610,7 +613,7 @@ fn required_ifs_val_present_pass() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.required_if_eq_any(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -626,7 +629,7 @@ fn required_ifs_val_present_fail() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.required_if_eq_any(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -643,7 +646,7 @@ fn required_ifs_wrong_val() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.required_if_eq_any(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -659,7 +662,7 @@ fn required_ifs_wrong_val_mult_fail() {
|
|||
let res = App::new("ri")
|
||||
.arg(
|
||||
Arg::new("cfg")
|
||||
.required_ifs(&[("extra", "val"), ("option", "spec")])
|
||||
.required_if_eq_any(&[("extra", "val"), ("option", "spec")])
|
||||
.takes_value(true)
|
||||
.long("config"),
|
||||
)
|
||||
|
@ -781,12 +784,12 @@ fn issue_1158_app() -> App<'static> {
|
|||
App::new("example")
|
||||
.arg(
|
||||
Arg::from("-c, --config [FILE] 'Custom config file.'")
|
||||
.required_unless("ID")
|
||||
.required_unless_present("ID")
|
||||
.conflicts_with("ID"),
|
||||
)
|
||||
.arg(
|
||||
Arg::from("[ID] 'ID'")
|
||||
.required_unless("config")
|
||||
.required_unless_present("config")
|
||||
.conflicts_with("config")
|
||||
.requires_all(&["x", "y", "z"]),
|
||||
)
|
||||
|
@ -858,12 +861,12 @@ fn requires_if_invalid_arg() {
|
|||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "Argument or group 'extra' specified in 'required_if*' for 'config' does not exist"]
|
||||
#[should_panic = "Argument or group 'extra' specified in 'required_if_eq*' for 'config' does not exist"]
|
||||
fn required_if_invalid_arg() {
|
||||
let _ = App::new("prog")
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.required_if("extra", "val")
|
||||
.required_if_eq("extra", "val")
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--config"]);
|
||||
|
@ -874,6 +877,10 @@ fn required_if_invalid_arg() {
|
|||
#[should_panic = "Argument or group 'extra' specified in 'required_unless*' for 'config' does not exist"]
|
||||
fn required_unless_invalid_arg() {
|
||||
let _ = App::new("prog")
|
||||
.arg(Arg::new("config").required_unless("extra").long("config"))
|
||||
.arg(
|
||||
Arg::new("config")
|
||||
.required_unless_present("extra")
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue