2015-09-01 03:14:00 +00:00
|
|
|
#[cfg(feature = "yaml")]
|
|
|
|
use std::collections::BTreeMap;
|
2015-04-27 02:03:11 +00:00
|
|
|
use std::fmt::{Debug, Formatter, Result};
|
|
|
|
|
2015-09-01 03:14:00 +00:00
|
|
|
#[cfg(feature = "yaml")]
|
|
|
|
use yaml_rust::Yaml;
|
|
|
|
|
2016-01-26 19:02:10 +00:00
|
|
|
/// `ArgGroup`s are a family of related arguments and way for you to express, "Any of these
|
|
|
|
/// arguments". By placing arguments in a logical group, you can create easier requirement and
|
|
|
|
/// exclusion rules instead of having to list each argument individually, or when you want a rule
|
|
|
|
/// to apply "any but not all" arguments.
|
2015-04-28 02:52:50 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// For instance, you can make an entire `ArgGroup` required, this means that one (and *only* one)
|
|
|
|
/// argument from that group must be present. Using more than one argument from an `ArgGroup`
|
|
|
|
/// causes a parsing failure.
|
2015-05-01 18:44:20 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// You can also do things such as name an entire `ArgGroup` as a conflict or requirement for
|
|
|
|
/// another argument, meaning any of the arguments that belong to that group will cause a failure
|
|
|
|
/// if present, or must present respectively.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2015-05-01 18:44:20 +00:00
|
|
|
/// Perhaps the most common use of `ArgGroup`s is to require one and *only* one argument to be
|
|
|
|
/// present out of a given set. Imagine that you had multiple arguments, and you want one of them
|
|
|
|
/// to be required, but making all of them required isn't feasible because perhaps they conflict
|
|
|
|
/// with each other. For example, lets say that you were building an application where one could
|
|
|
|
/// set a given version number by supplying a string with an option argument, i.e.
|
|
|
|
/// `--set-ver v1.2.3`, you also wanted to support automatically using a previous version number
|
|
|
|
/// and simply incrementing one of the three numbers. So you create three flags `--major`,
|
|
|
|
/// `--minor`, and `--patch`. All of these arguments shouldn't be used at one time but you want to
|
2015-05-01 18:38:27 +00:00
|
|
|
/// specify that *at least one* of them is used. For this, you can create a group.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// Finally, you may use `ArgGroup`s to pull a value from a group of arguments when you don't care
|
|
|
|
/// exaclty which argument was actually used at runtime.
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-28 02:52:50 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// The following example demonstrates using an `ArgGroup` to ensure that one, and only one, of
|
|
|
|
/// the arguments from the specified group is present at runtime.
|
|
|
|
///
|
|
|
|
/// ```rust
|
2015-04-27 02:03:11 +00:00
|
|
|
/// # use clap::{App, ArgGroup};
|
2016-01-26 19:02:10 +00:00
|
|
|
/// App::new("app")
|
|
|
|
/// .args_from_usage(
|
|
|
|
/// "--set-ver [ver] 'set the version manually'
|
|
|
|
/// --major 'auto increase major'
|
|
|
|
/// --minor 'auto increase minor'
|
|
|
|
/// --patch 'auto increase patch'")
|
|
|
|
/// .group(ArgGroup::with_name("vers")
|
|
|
|
/// .args(&["set-ver", "major", "minor","patch"])
|
|
|
|
/// .required(true))
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-02-04 06:10:37 +00:00
|
|
|
#[derive(Default)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub struct ArgGroup<'a> {
|
2015-04-27 02:03:11 +00:00
|
|
|
#[doc(hidden)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub name: &'a str,
|
2015-04-27 02:03:11 +00:00
|
|
|
#[doc(hidden)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub args: Vec<&'a str>,
|
2015-04-27 02:03:11 +00:00
|
|
|
#[doc(hidden)]
|
|
|
|
pub required: bool,
|
|
|
|
#[doc(hidden)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub requires: Option<Vec<&'a str>>,
|
2015-04-27 02:03:11 +00:00
|
|
|
#[doc(hidden)]
|
2016-01-11 08:59:56 +00:00
|
|
|
pub conflicts: Option<Vec<&'a str>>,
|
2015-04-27 02:03:11 +00:00
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl<'a> ArgGroup<'a> {
|
2016-01-26 19:02:10 +00:00
|
|
|
/// Creates a new instance of `ArgGroup` using a unique string name. The name will be used to
|
|
|
|
/// get values from the group or refer to the group inside of conflict and requirement rules.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
2015-04-27 02:03:11 +00:00
|
|
|
/// # use clap::{App, ArgGroup};
|
2015-11-01 14:02:37 +00:00
|
|
|
/// ArgGroup::with_name("config")
|
2016-01-26 19:02:10 +00:00
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn with_name(n: &'a str) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
ArgGroup {
|
|
|
|
name: n,
|
|
|
|
required: false,
|
2015-09-04 18:05:13 +00:00
|
|
|
args: vec![],
|
2015-04-27 02:03:11 +00:00
|
|
|
requires: None,
|
2015-10-28 14:23:59 +00:00
|
|
|
conflicts: None,
|
2015-04-27 02:03:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-01 14:02:37 +00:00
|
|
|
/// Creates a new instance of `ArgGroup` from a .yml (YAML) file.
|
2015-09-01 03:14:00 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-09-01 03:14:00 +00:00
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// # use clap::ArgGroup;
|
|
|
|
/// let yml = load_yaml!("group.yml");
|
|
|
|
/// let ag = ArgGroup::from_yaml(yml);
|
|
|
|
/// ```
|
|
|
|
#[cfg(feature = "yaml")]
|
2016-02-04 06:10:37 +00:00
|
|
|
pub fn from_yaml(y: &'a Yaml) -> ArgGroup<'a> {
|
|
|
|
ArgGroup::from(y.as_hash().unwrap())
|
2015-09-01 03:14:00 +00:00
|
|
|
}
|
|
|
|
|
2015-04-27 02:03:11 +00:00
|
|
|
/// Adds an argument to this group by name
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, ArgGroup, Arg};
|
|
|
|
/// let cfg_arg = Arg::with_name("config");
|
|
|
|
/// // ...
|
|
|
|
/// ArgGroup::with_name("files")
|
|
|
|
/// .arg("config")
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn arg(mut self, n: &'a str) -> Self {
|
2015-10-28 14:23:59 +00:00
|
|
|
assert!(self.name != n,
|
|
|
|
"ArgGroup '{}' can not have same name as arg inside it",
|
2016-01-11 08:59:56 +00:00
|
|
|
&*self.name);
|
2015-09-04 18:05:13 +00:00
|
|
|
self.args.push(n);
|
2015-04-27 02:03:11 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2015-08-30 17:22:26 +00:00
|
|
|
/// Adds multiple arguments to this group by name
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```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"])
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn args(mut self, ns: &[&'a str]) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
for n in ns {
|
2016-01-11 08:59:56 +00:00
|
|
|
self = self.arg(n);
|
2015-04-27 02:03:11 +00:00
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-01-26 19:02:10 +00:00
|
|
|
/// Sets the group as required or not. A required group will be displayed in the usage string
|
2015-04-27 02:03:11 +00:00
|
|
|
/// 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
|
|
|
|
/// conflicting with another argument).
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{Arg, ArgGroup};
|
|
|
|
/// let cfg_arg = Arg::with_name("config");
|
|
|
|
/// let in_arg = Arg::with_name("input");
|
|
|
|
/// // ...
|
|
|
|
/// ArgGroup::with_name("cfg")
|
|
|
|
/// .args(&["config", "input"])
|
|
|
|
/// .required(true)
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2015-10-28 14:23:59 +00:00
|
|
|
pub fn required(mut self, r: bool) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
self.required = r;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets the requirement rules of this group. This is not to be confused with a required group.
|
2015-04-28 02:52:50 +00:00
|
|
|
/// Requirement rules function just like argument requirement rules, you can name other
|
|
|
|
/// arguments or groups that must be present when one of the arguments from this group is used.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
|
|
|
/// **NOTE:** The name provided may be an argument, or group name
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, Arg, ArgGroup};
|
|
|
|
/// let cfg_arg = Arg::with_name("config");
|
|
|
|
/// let in_arg = Arg::with_name("input");
|
|
|
|
/// // ...
|
|
|
|
/// ArgGroup::with_name("files")
|
|
|
|
/// .args(&["config", "input"])
|
|
|
|
/// // ...
|
|
|
|
/// # ;
|
|
|
|
/// ArgGroup::with_name("other_group")
|
|
|
|
/// .requires("files")
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn requires(mut self, n: &'a str) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
if let Some(ref mut reqs) = self.requires {
|
2015-09-04 18:05:13 +00:00
|
|
|
reqs.push(n);
|
2015-04-27 02:03:11 +00:00
|
|
|
} else {
|
2015-09-04 18:05:13 +00:00
|
|
|
self.requires = Some(vec![n]);
|
2015-04-27 02:03:11 +00:00
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Sets the requirement rules of this group. This is not to be confused with a required group.
|
2015-04-28 02:52:50 +00:00
|
|
|
/// Requirement rules function just like argument requirement rules, you can name other
|
|
|
|
/// arguments or groups that must be present when one of the arguments from this group is used.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
|
|
|
/// **NOTE:** The names provided may be an argument, or group name
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, Arg, ArgGroup};
|
|
|
|
/// let cfg_arg = Arg::with_name("config");
|
|
|
|
/// let in_arg = Arg::with_name("input");
|
|
|
|
/// // ...
|
|
|
|
/// ArgGroup::with_name("files")
|
|
|
|
/// .args(&["config", "input"])
|
|
|
|
/// // ...
|
|
|
|
/// # ;
|
|
|
|
/// ArgGroup::with_name("other_group")
|
|
|
|
/// .requires_all(&["config", "input"]) // No different than saying, .requires("files")
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn requires_all(mut self, ns: &[&'a str]) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
for n in ns {
|
|
|
|
self = self.requires(n);
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-01-26 19:02:10 +00:00
|
|
|
/// Sets the exclusion rules of this group. Exclusion (aka conflict) rules function just like
|
|
|
|
/// argument exclusion rules, you can name other arguments or groups that must not be present
|
|
|
|
/// when one of the arguments from this group are used.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
|
|
|
/// **NOTE:** The name provided may be an argument, or group name
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, Arg, ArgGroup};
|
|
|
|
/// let cfg_arg = Arg::with_name("config");
|
|
|
|
/// let in_arg = Arg::with_name("input");
|
|
|
|
/// // ...
|
|
|
|
/// ArgGroup::with_name("files")
|
|
|
|
/// .args(&["config", "input"])
|
|
|
|
/// // ...
|
|
|
|
/// # ;
|
|
|
|
/// ArgGroup::with_name("other_group")
|
|
|
|
/// .conflicts_with("files")
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn conflicts_with(mut self, n: &'a str) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
if let Some(ref mut confs) = self.conflicts {
|
2015-09-04 18:05:13 +00:00
|
|
|
confs.push(n);
|
2015-04-27 02:03:11 +00:00
|
|
|
} else {
|
2015-09-04 18:05:13 +00:00
|
|
|
self.conflicts = Some(vec![n]);
|
2015-04-27 02:03:11 +00:00
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2015-04-28 02:52:50 +00:00
|
|
|
/// Sets the exclusion rules of this group. Exclusion rules function just like argument
|
|
|
|
/// exclusion rules, you can name other arguments or groups that must not be present when one
|
|
|
|
/// of the arguments from this group are used.
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
|
|
|
/// **NOTE:** The names provided may be an argument, or group name
|
|
|
|
///
|
2015-09-22 02:06:15 +00:00
|
|
|
/// # Examples
|
2015-04-27 02:03:11 +00:00
|
|
|
///
|
2016-01-26 19:02:10 +00:00
|
|
|
/// ```rust
|
|
|
|
/// # use clap::{App, Arg, ArgGroup};
|
|
|
|
/// let cfg_arg = Arg::with_name("config");
|
|
|
|
/// let in_arg = Arg::with_name("input");
|
|
|
|
/// // ...
|
|
|
|
/// ArgGroup::with_name("files")
|
|
|
|
/// .args(&["config", "input"])
|
|
|
|
/// // ...
|
|
|
|
/// # ;
|
|
|
|
/// ArgGroup::with_name("other_group")
|
|
|
|
/// .conflicts_with_all(&["files", "input"]) // same as saying, conflicts_with("files")
|
|
|
|
/// # ;
|
|
|
|
/// ```
|
2016-01-11 08:59:56 +00:00
|
|
|
pub fn conflicts_with_all(mut self, ns: &[&'a str]) -> Self {
|
2015-04-27 02:03:11 +00:00
|
|
|
for n in ns {
|
|
|
|
self = self.conflicts_with(n);
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl<'a> Debug for ArgGroup<'a> {
|
2015-10-28 14:23:59 +00:00
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result {
|
|
|
|
write!(f,
|
2016-02-04 06:10:37 +00:00
|
|
|
"{{\n\
|
|
|
|
\tname: {:?},\n\
|
|
|
|
\targs: {:?},\n\
|
|
|
|
\trequired: {:?},\n\
|
|
|
|
\trequires: {:?},\n\
|
|
|
|
\tconflicts: {:?},\n\
|
|
|
|
}}",
|
2015-10-28 14:23:59 +00:00
|
|
|
self.name,
|
|
|
|
self.args,
|
|
|
|
self.required,
|
|
|
|
self.requires,
|
|
|
|
self.conflicts)
|
2015-04-27 02:03:11 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-04 17:58:00 +00:00
|
|
|
|
2016-01-11 08:59:56 +00:00
|
|
|
impl<'a, 'z> From<&'z ArgGroup<'a>> for ArgGroup<'a> {
|
|
|
|
fn from(g: &'z ArgGroup<'a>) -> Self {
|
|
|
|
ArgGroup {
|
|
|
|
name: g.name.clone(),
|
|
|
|
required: g.required,
|
|
|
|
args: g.args.clone(),
|
|
|
|
requires: g.requires.clone(),
|
|
|
|
conflicts: g.conflicts.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-04 06:10:37 +00:00
|
|
|
#[cfg(feature = "yaml")]
|
|
|
|
impl<'a> From<&'a BTreeMap<Yaml, Yaml>> for ArgGroup<'a> {
|
|
|
|
fn from(b: &'a BTreeMap<Yaml, Yaml>) -> Self {
|
|
|
|
// We WANT this to panic on error...so expect() is good.
|
|
|
|
let mut a = ArgGroup::default();
|
|
|
|
let group_settings = if b.len() == 1 {
|
|
|
|
let name_yml = b.keys().nth(0).expect("failed to get name");
|
|
|
|
let name_str = name_yml.as_str().expect("failed to convert name to str");
|
|
|
|
a.name = name_str;
|
|
|
|
b.get(name_yml).expect("failed to get name_str").as_hash().expect("failed to convert to a hash")
|
|
|
|
} else {
|
|
|
|
b
|
|
|
|
};
|
|
|
|
|
|
|
|
for (k, v) in group_settings.iter() {
|
|
|
|
a = match k.as_str().unwrap() {
|
|
|
|
"required" => a.required(v.as_bool().unwrap()),
|
|
|
|
"args" => {
|
|
|
|
for ys in v.as_vec().unwrap() {
|
|
|
|
if let Some(s) = ys.as_str() {
|
|
|
|
a = a.arg(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a
|
|
|
|
}
|
|
|
|
"arg" => {
|
|
|
|
if let Some(ys) = v.as_str() {
|
|
|
|
a = a.arg(ys);
|
|
|
|
}
|
|
|
|
a
|
|
|
|
}
|
|
|
|
"requires" => {
|
|
|
|
for ys in v.as_vec().unwrap() {
|
|
|
|
if let Some(s) = ys.as_str() {
|
|
|
|
a = a.requires(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a
|
|
|
|
}
|
|
|
|
"conflicts_with" => {
|
|
|
|
for ys in v.as_vec().unwrap() {
|
|
|
|
if let Some(s) = ys.as_str() {
|
|
|
|
a = a.conflicts_with(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a
|
|
|
|
}
|
|
|
|
"name" => {
|
|
|
|
if let Some(ys) = v.as_str() {
|
|
|
|
a.name = ys;
|
|
|
|
}
|
|
|
|
a
|
|
|
|
}
|
|
|
|
s => panic!("Unknown ArgGroup setting '{}' in YAML file for \
|
|
|
|
ArgGroup '{}'",
|
|
|
|
s,
|
|
|
|
a.name),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
a
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-04 17:58:00 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::ArgGroup;
|
2016-02-04 06:10:37 +00:00
|
|
|
#[cfg(feature = "yaml")]
|
|
|
|
use yaml_rust::YamlLoader;
|
2015-09-04 17:58:00 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn groups() {
|
|
|
|
let g = ArgGroup::with_name("test")
|
2016-01-21 05:18:53 +00:00
|
|
|
.arg("a1")
|
|
|
|
.arg("a4")
|
|
|
|
.args(&["a2", "a3"])
|
2015-10-28 14:23:59 +00:00
|
|
|
.required(true)
|
|
|
|
.conflicts_with("c1")
|
|
|
|
.conflicts_with_all(&["c2", "c3"])
|
|
|
|
.conflicts_with("c4")
|
|
|
|
.requires("r1")
|
|
|
|
.requires_all(&["r2", "r3"])
|
|
|
|
.requires("r4");
|
2015-09-04 17:58:00 +00:00
|
|
|
|
2016-01-22 04:18:52 +00:00
|
|
|
let args = vec!["a1", "a4", "a2", "a3"];
|
2015-09-07 01:07:46 +00:00
|
|
|
let reqs = vec!["r1", "r2", "r3", "r4"];
|
2015-09-04 18:05:13 +00:00
|
|
|
let confs = vec!["c1", "c2", "c3", "c4"];
|
2015-09-04 17:58:00 +00:00
|
|
|
|
|
|
|
assert_eq!(g.args, args);
|
2016-02-04 06:13:46 +00:00
|
|
|
assert_eq!(g.requires, Some(reqs));
|
|
|
|
assert_eq!(g.conflicts, Some(confs));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_debug() {
|
|
|
|
let g = ArgGroup::with_name("test")
|
|
|
|
.arg("a1")
|
|
|
|
.arg("a4")
|
|
|
|
.args(&["a2", "a3"])
|
|
|
|
.required(true)
|
|
|
|
.conflicts_with("c1")
|
|
|
|
.conflicts_with_all(&["c2", "c3"])
|
|
|
|
.conflicts_with("c4")
|
|
|
|
.requires("r1")
|
|
|
|
.requires_all(&["r2", "r3"])
|
|
|
|
.requires("r4");
|
|
|
|
|
|
|
|
let args = vec!["a1", "a4", "a2", "a3"];
|
|
|
|
let reqs = vec!["r1", "r2", "r3", "r4"];
|
|
|
|
let confs = vec!["c1", "c2", "c3", "c4"];
|
|
|
|
|
|
|
|
let debug_str =
|
|
|
|
format!("{{\n\
|
|
|
|
\tname: \"test\",\n\
|
|
|
|
\targs: {:?},\n\
|
|
|
|
\trequired: {:?},\n\
|
|
|
|
\trequires: {:?},\n\
|
|
|
|
\tconflicts: {:?},\n\
|
|
|
|
}}", args, true, Some(reqs), Some(confs));
|
|
|
|
assert_eq!(&*format!("{:?}", g), &*debug_str);
|
|
|
|
}
|
2015-09-04 17:58:00 +00:00
|
|
|
|
2016-02-04 06:13:46 +00:00
|
|
|
#[test]
|
|
|
|
fn test_from() {
|
|
|
|
let g = ArgGroup::with_name("test")
|
|
|
|
.arg("a1")
|
|
|
|
.arg("a4")
|
|
|
|
.args(&["a2", "a3"])
|
|
|
|
.required(true)
|
|
|
|
.conflicts_with("c1")
|
|
|
|
.conflicts_with_all(&["c2", "c3"])
|
|
|
|
.conflicts_with("c4")
|
|
|
|
.requires("r1")
|
|
|
|
.requires_all(&["r2", "r3"])
|
|
|
|
.requires("r4");
|
|
|
|
|
|
|
|
let args = vec!["a1", "a4", "a2", "a3"];
|
|
|
|
let reqs = vec!["r1", "r2", "r3", "r4"];
|
|
|
|
let confs = vec!["c1", "c2", "c3", "c4"];
|
|
|
|
|
|
|
|
let g2 = ArgGroup::from(&g);
|
|
|
|
assert_eq!(g2.args, args);
|
|
|
|
assert_eq!(g2.requires, Some(reqs));
|
|
|
|
assert_eq!(g2.conflicts, Some(confs));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature="yaml")]
|
|
|
|
#[cfg_attr(feature = "yaml", test)]
|
|
|
|
fn test_yaml() {
|
|
|
|
|
|
|
|
let g_yaml =
|
|
|
|
"name: test
|
|
|
|
args:
|
|
|
|
- a1
|
|
|
|
- a4
|
|
|
|
- a2
|
|
|
|
- a3
|
|
|
|
conflicts_with:
|
|
|
|
- c1
|
|
|
|
- c2
|
|
|
|
- c3
|
|
|
|
- c4
|
|
|
|
requires:
|
|
|
|
- r1
|
|
|
|
- r2
|
|
|
|
- r3
|
|
|
|
- r4";
|
|
|
|
let yml = &YamlLoader::load_from_str(g_yaml).expect("failed to load YAML file")[0];
|
|
|
|
let g = ArgGroup::from_yaml(yml);
|
|
|
|
let args = vec!["a1", "a4", "a2", "a3"];
|
|
|
|
let reqs = vec!["r1", "r2", "r3", "r4"];
|
|
|
|
let confs = vec!["c1", "c2", "c3", "c4"];
|
|
|
|
assert_eq!(g.args, args);
|
|
|
|
assert_eq!(g.requires, Some(reqs));
|
|
|
|
assert_eq!(g.conflicts, Some(confs));
|
2015-09-04 17:58:00 +00:00
|
|
|
}
|
2015-09-07 01:07:46 +00:00
|
|
|
}
|