mirror of
https://github.com/clap-rs/clap
synced 2024-12-14 23:02:31 +00:00
Assert for require* on args
This commit is contained in:
parent
f632aedc72
commit
00a0b9660a
3 changed files with 88 additions and 15 deletions
|
@ -1523,13 +1523,44 @@ impl<'b> App<'b> {
|
|||
} else {
|
||||
acc
|
||||
}) < 2,
|
||||
"Argument '{}' has the same index as another positional \
|
||||
argument\n\n\tUse Arg::setting(ArgSettings::MultipleValues) to allow one \
|
||||
"Argument '{}' has the same index as another positional argument\n\n\t \
|
||||
Use Arg::setting(ArgSettings::MultipleValues) to allow one \
|
||||
positional argument to take multiple values",
|
||||
arg.name
|
||||
);
|
||||
}
|
||||
|
||||
// requires, r_if, r_unless
|
||||
if let Some(reqs) = &arg.requires {
|
||||
for req in reqs {
|
||||
assert!(
|
||||
self.args.args.iter().any(|x| x.id == req.1),
|
||||
"Argument specified in 'requires*' for '{}' does not exist",
|
||||
arg.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(reqs) = &arg.r_ifs {
|
||||
for req in reqs {
|
||||
assert!(
|
||||
self.args.args.iter().any(|x| x.id == req.0),
|
||||
"Argument specified in 'required_if*' for '{}' does not exist",
|
||||
arg.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(reqs) = &arg.r_unless {
|
||||
for req in reqs {
|
||||
assert!(
|
||||
self.args.args.iter().any(|x| x.id == *req),
|
||||
"Argument specified in 'required_unless*' for '{}' does not exist",
|
||||
arg.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// blacklist
|
||||
if let Some(reqs) = &arg.blacklist {
|
||||
for req in reqs {
|
||||
|
|
|
@ -64,10 +64,11 @@ pub struct Arg<'help> {
|
|||
#[doc(hidden)]
|
||||
pub blacklist: Option<Vec<Id>>,
|
||||
pub(crate) settings: ArgFlags,
|
||||
pub(crate) r_unless: Option<Vec<Id>>,
|
||||
pub(crate) overrides: Option<Vec<Id>>,
|
||||
pub(crate) groups: Option<Vec<Id>>,
|
||||
pub(crate) requires: Option<Vec<(Option<&'help str>, Id)>>,
|
||||
pub(crate) r_ifs: Option<Vec<(Id, &'help str)>>,
|
||||
pub(crate) r_unless: Option<Vec<Id>>,
|
||||
#[doc(hidden)]
|
||||
pub short: Option<char>,
|
||||
#[doc(hidden)]
|
||||
|
@ -90,7 +91,6 @@ pub struct Arg<'help> {
|
|||
pub(crate) terminator: Option<&'help str>,
|
||||
#[doc(hidden)]
|
||||
pub index: Option<u64>,
|
||||
pub(crate) r_ifs: Option<Vec<(Id, &'help str)>>,
|
||||
#[doc(hidden)]
|
||||
pub help_heading: Option<&'help str>,
|
||||
pub(crate) global: bool,
|
||||
|
@ -1114,13 +1114,11 @@ impl<'help> Arg<'help> {
|
|||
/// [Conflicting]: ./struct.Arg.html#method.conflicts_with
|
||||
/// [override]: ./struct.Arg.html#method.overrides_with
|
||||
pub fn requires<T: Key>(mut self, arg_id: T) -> Self {
|
||||
let name = arg_id.key();
|
||||
let arg = arg_id.key();
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
vec.push((None, name));
|
||||
vec.push((None, arg));
|
||||
} else {
|
||||
let mut vec = vec![];
|
||||
vec.push((None, name));
|
||||
self.requires = Some(vec);
|
||||
self.requires = Some(vec![(None, arg)]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -1496,11 +1494,7 @@ impl<'help> Arg<'help> {
|
|||
vec.push((None, s.key()));
|
||||
}
|
||||
} else {
|
||||
let mut vec = vec![];
|
||||
for s in names {
|
||||
vec.push((None, s.key()));
|
||||
}
|
||||
self.requires = Some(vec);
|
||||
self.requires = Some(names.iter().map(|s| (None, s.key())).collect());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
|
|
@ -728,3 +728,51 @@ fn issue_1643_args_mutually_require_each_other() {
|
|||
|
||||
app.get_matches_from(&["test", "-u", "hello", "-r", "farewell"]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic(expected = "Argument specified in 'requires*' for 'config' does not exist")]
|
||||
fn requires_invalid_arg() {
|
||||
let _ = App::new("prog")
|
||||
.arg(Arg::with_name("config").requires("extra").long("config"))
|
||||
.try_get_matches_from(vec!["", "--config"]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic(expected = "Argument specified in 'requires*' for 'config' does not exist")]
|
||||
fn requires_if_invalid_arg() {
|
||||
let _ = App::new("prog")
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.requires_if("val", "extra")
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--config"]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic(expected = "Argument specified in 'required_if*' for 'config' does not exist")]
|
||||
fn required_if_invalid_arg() {
|
||||
let _ = App::new("prog")
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.required_if("extra", "val")
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec!["", "--config"]);
|
||||
}
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic(expected = "Argument specified in 'required_unless*' for 'config' does not exist")]
|
||||
fn required_unless_invalid_arg() {
|
||||
let _ = App::new("prog")
|
||||
.arg(
|
||||
Arg::with_name("config")
|
||||
.required_unless("extra")
|
||||
.long("config"),
|
||||
)
|
||||
.try_get_matches_from(vec![""]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue