Skip to content

Commit 18237f4

Browse files
committed
Auto merge of #542 - brianp:issue-426, r=kbknapp
imp(ArgGroup): Add multiple ArgGroups per Arg Add the function `Arg.groups` that can take a `Vec<&'a str>` to add the `Arg` to multiple `ArgGroup`'s at once. ex: ```rust Arg::with_name("arg") .groups(&["grp1", "grp2"]) ``` Closes #426
2 parents 3803b94 + 902e182 commit 18237f4

File tree

2 files changed

+61
-7
lines changed

2 files changed

+61
-7
lines changed

src/app/parser.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,11 @@ impl<'a, 'b> Parser<'a, 'b>
103103
self.opts.iter().any(|o| o.name == a.name) ||
104104
self.positionals.values().any(|p| p.name == a.name)),
105105
format!("Non-unique argument name: {} is already in use", a.name));
106-
if let Some(grp) = a.group {
107-
let ag = self.groups.entry(grp).or_insert_with(|| ArgGroup::with_name(grp));
108-
ag.args.push(a.name);
106+
if let Some(ref grps) = a.group {
107+
for g in grps {
108+
let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g));
109+
ag.args.push(a.name);
110+
}
109111
}
110112
if let Some(s) = a.short {
111113
debug_assert!(!self.short_list.contains(&s),

src/args/arg.rs

+56-4
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ pub struct Arg<'a, 'b>
5252
#[doc(hidden)]
5353
pub requires: Option<Vec<&'a str>>,
5454
#[doc(hidden)]
55-
pub group: Option<&'a str>,
55+
pub group: Option<Vec<&'a str>>,
5656
#[doc(hidden)]
5757
pub val_names: Option<VecMap<&'b str>>,
5858
#[doc(hidden)]
@@ -176,6 +176,14 @@ impl<'a, 'b> Arg<'a, 'b> {
176176
}
177177
a
178178
}
179+
"groups" => {
180+
for ys in v.as_vec().unwrap() {
181+
if let Some(s) = ys.as_str() {
182+
a = a.group(s);
183+
}
184+
}
185+
a
186+
}
179187
"requires" => {
180188
for ys in v.as_vec().unwrap() {
181189
if let Some(s) = ys.as_str() {
@@ -1612,7 +1620,51 @@ impl<'a, 'b> Arg<'a, 'b> {
16121620
/// ```
16131621
/// [`ArgGroup`]: ./struct.ArgGroup.html
16141622
pub fn group(mut self, name: &'a str) -> Self {
1615-
self.group = Some(name);
1623+
if let Some(ref mut vec) = self.requires {
1624+
vec.push(name);
1625+
} else {
1626+
self.group = Some(vec![name]);
1627+
}
1628+
self
1629+
}
1630+
1631+
/// Specifies the names of multiple [`ArgGroup`]'s the argument belongs to.
1632+
///
1633+
/// # Examples
1634+
///
1635+
/// ```rust
1636+
/// # use clap::{App, Arg};
1637+
/// Arg::with_name("debug")
1638+
/// .long("debug")
1639+
/// .groups(&["mode", "verbosity"])
1640+
/// # ;
1641+
/// ```
1642+
///
1643+
/// Arguments can be members of multiple groups and then the group checked as if it
1644+
/// was one of said arguments.
1645+
///
1646+
/// ```rust
1647+
/// # use clap::{App, Arg};
1648+
/// let m = App::new("groups")
1649+
/// .arg(Arg::with_name("debug")
1650+
/// .long("debug")
1651+
/// .groups(&["mode", "verbosity"]))
1652+
/// .arg(Arg::with_name("verbose")
1653+
/// .long("verbose")
1654+
/// .groups(&["mode", "verbosity"]))
1655+
/// .get_matches_from(vec!["posvals", "--debug"]);
1656+
/// assert!(m.is_present("mode"));
1657+
/// assert!(m.is_present("verbosity"));
1658+
/// ```
1659+
/// [`ArgGroup`]: ./struct.ArgGroup.html
1660+
pub fn groups(mut self, names: &[&'a str]) -> Self {
1661+
if let Some(ref mut vec) = self.group {
1662+
for s in names {
1663+
vec.push(s);
1664+
}
1665+
} else {
1666+
self.group = Some(names.into_iter().map(|s| *s).collect::<Vec<_>>());
1667+
}
16161668
self
16171669
}
16181670

@@ -2234,7 +2286,7 @@ impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
22342286
min_vals: a.min_vals,
22352287
max_vals: a.max_vals,
22362288
val_names: a.val_names.clone(),
2237-
group: a.group,
2289+
group: a.group.clone(),
22382290
validator: a.validator.clone(),
22392291
overrides: a.overrides.clone(),
22402292
settings: a.settings,
@@ -2261,7 +2313,7 @@ impl<'a, 'b> Clone for Arg<'a, 'b> {
22612313
min_vals: self.min_vals,
22622314
max_vals: self.max_vals,
22632315
val_names: self.val_names.clone(),
2264-
group: self.group,
2316+
group: self.group.clone(),
22652317
validator: self.validator.clone(),
22662318
overrides: self.overrides.clone(),
22672319
settings: self.settings,

0 commit comments

Comments
 (0)