From 33689acc689b217a8c0ee439f1b1225590c38355 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Thu, 23 Jun 2016 10:01:19 -0400 Subject: [PATCH] feat(Groups): one can now specify groups which require AT LEAST one of the args Unlike the previous ArgGroups, which made all args in the group mutually exclusive, one can now use `ArgGroup::multiple(true)` which allows using more than one arg in the group (i.e. they're not all mutually exclusive). When combined with `ArgGroup::required(true)` this effectively says, "At least one of the args must be used, and using morethan one is also OK." Closes #533 --- src/app/macros.rs | 6 ++++-- src/args/group.rs | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/app/macros.rs b/src/app/macros.rs index 03456628036..022b05fcb65 100644 --- a/src/app/macros.rs +++ b/src/app/macros.rs @@ -91,8 +91,10 @@ macro_rules! _handle_group_reqs{ if found { vec_remove_all!($me.required, &grp.args); debugln!("Adding args from group to blacklist...{:?}", grp.args); - $me.blacklist.extend(&grp.args); - vec_remove!($me.blacklist, &$arg.name()); + if !grp.multiple { + $me.blacklist.extend(&grp.args); + vec_remove!($me.blacklist, &$arg.name()); + } } } }) diff --git a/src/args/group.rs b/src/args/group.rs index d95ba7db3b1..ffb5b53689a 100644 --- a/src/args/group.rs +++ b/src/args/group.rs @@ -61,6 +61,8 @@ pub struct ArgGroup<'a> { pub requires: Option>, #[doc(hidden)] pub conflicts: Option>, + #[doc(hidden)] + pub multiple: bool, } impl<'a> ArgGroup<'a> { @@ -81,6 +83,7 @@ impl<'a> ArgGroup<'a> { args: vec![], requires: None, conflicts: None, + multiple: false, } } @@ -140,6 +143,26 @@ impl<'a> ArgGroup<'a> { self } + /// Allows more than one of the ['Arg']s in this group to be used. (Default: `false`) + /// + /// # Examples + /// + /// ```rust + /// # use clap::{ArgGroup, Arg}; + /// let cfg_arg = Arg::with_name("config"); + /// let in_arg = Arg::with_name("input"); + /// // ... + /// ArgGroup::with_name("files") + /// .args(&["config", "input"]) + /// .multiple(true) + /// # ; + /// ``` + /// ['Arg']: ./struct.Arg.html + pub fn multiple(mut self, m: bool) -> Self { + self.multiple = m; + self + } + /// Sets the group as required or not. A required group will be displayed in the usage string /// of the application in the format `[arg|arg2|arg3]`. A required `ArgGroup` simply states /// that one, and only one argument from this group *must* be present at runtime (unless @@ -310,6 +333,7 @@ impl<'a, 'z> From<&'z ArgGroup<'a>> for ArgGroup<'a> { args: g.args.clone(), requires: g.requires.clone(), conflicts: g.conflicts.clone(), + multiple: g.multiple, } } } @@ -507,6 +531,7 @@ impl<'a> Clone for ArgGroup<'a> { args: self.args.clone(), requires: self.requires.clone(), conflicts: self.conflicts.clone(), + multiple: self.multiple, } } }