Merge pull request #20 from epage/macro

Deprecate YAML and Usage Parser
This commit is contained in:
Ed Page 2021-11-23 12:09:51 -06:00 committed by GitHub
commit d8b12a6bb5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 1791 additions and 1509 deletions

2
FAQ.md
View file

@ -73,14 +73,12 @@ To build an `App` there are three:
* Derive Macros
* Builder Pattern
* Yaml
To build an `Arg` there are four:
* Derive Macros
* Builder Pattern
* Usage Strings
* Yaml
### Why is there a default subcommand of help?

View file

@ -27,8 +27,7 @@ We are currently hard at work trying to release `3.0`. We have a `3.0.0-beta.5`
4. [Quick Example](#quick-example)
1. [Using Derive Macros](#using-derive-macros)
2. [Using Builder Pattern](#using-builder-pattern)
3. [Using YAML](#using-yaml)
4. [Running it](#running-it)
3. [Running it](#running-it)
5. [Try it!](#try-it)
1. [Pre-Built Test](#pre-built-test)
2. [Build Your Own Binary](#build-your-own-binary)
@ -92,7 +91,6 @@ Below are a few of the features which `clap` supports, full descriptions and usa
* **Sub-Commands** (i.e. `git add <file>` where `add` is a sub-command of `git`)
- Support their own sub-arguments, and sub-sub-commands independent of the parent
- Get their own auto-generated Help, Version, and Usage independent of parent
* **Support for building CLIs from YAML** - This keeps your Rust source nice and tidy and makes supporting localized translation very simple!
* **Requirement Rules**: Arguments can define the following types of requirement rules
- Can be required by default
- Can be required only if certain arguments are present
@ -283,93 +281,27 @@ The next example shows a far less verbose method, but sacrifices some of the adv
//
// This example demonstrates clap's "usage strings" method of creating arguments
// which is less verbose
use clap::App;
use clap::{App, arg};
fn main() {
let matches = App::new("myapp")
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'")
.arg("<INPUT> 'Sets the input file to use'")
.arg("-v... 'Sets the level of verbosity'")
.arg(arg!(-c --config <FILE> "Sets a custom config file").required(false))
.arg(arg!(<INPUT> "Sets the input file to use"))
.arg(arg!(-v --verbose ... "Sets the level of verbosity"))
.subcommand(App::new("test")
.about("controls testing features")
.version("1.3")
.author("Someone E. <someone_else@other.com>")
.arg("-d, --debug 'Print debug information'"))
.arg(arg!(-d --debug "Print debug information")))
.get_matches();
// Same as previous example...
}
```
#### Using YAML
This third method shows how you can use a YAML file to build your CLI and keep your Rust source tidy
or support multiple localized translations by having different YAML files for each localization.
First, create the `cli.yaml` file to hold your CLI options, but it could be called anything we like:
```yaml
name: myapp
version: "1.0"
author: Kevin K. <kbknapp@gmail.com>
about: Does awesome things
args:
- config:
short: c
long: config
value_name: FILE
help: Sets a custom config file
takes_value: true
- INPUT:
help: Sets the input file to use
required: true
index: 1
- verbose:
short: v
multiple_occurrences: true
help: Sets the level of verbosity
subcommands:
- test:
about: controls testing features
version: "1.3"
author: Someone E. <someone_else@other.com>
args:
- debug:
short: d
long: debug
help: Print debug information
```
Since this feature requires additional dependencies that not everyone may want, it is *not* compiled in by default and we need to enable a feature flag in Cargo.toml:
Simply add the `yaml` feature flag to your `Cargo.toml`.
```toml
[dependencies]
clap = { version = "3.0.0-beta.5", features = ["yaml"] }
```
Finally we create our `main.rs` file just like we would have with the previous two examples:
```rust,ignore
// (Full example with detailed comments in examples/17_yaml.rs)
//
// This example demonstrates clap's building from YAML style of creating arguments which is far
// more clean, but takes a very small performance hit compared to the other two methods.
use clap::{App, load_yaml};
fn main() {
// The YAML file is found relative to the current file, similar to how modules are found
let yaml = load_yaml!("cli.yaml");
let matches = App::from(yaml).get_matches();
// Same as previous examples...
}
```
#### Running it
If you were to compile any of the above programs and run them with the flag `--help` or `-h` (or `help` subcommand, since we defined `test` as a subcommand) the following would be output (except the first example where the help message sort of explains the Rust code).

View file

@ -1,4 +1,4 @@
use clap::{App, Arg};
use clap::{arg, App, Arg};
use criterion::{criterion_group, criterion_main, Criterion};
macro_rules! create_app {
@ -7,9 +7,9 @@ macro_rules! create_app {
.version("0.1")
.about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>")
.arg("-f --flag 'tests flags'")
.arg("-o --option=[opt] 'tests options'")
.arg("[positional] 'tests positional'")
.arg(arg!(-f --flag "tests flags"))
.arg(arg!(-o --option <opt> "tests options").required(false))
.arg(arg!([positional] "tests positional"))
}};
}
@ -19,14 +19,14 @@ pub fn build_simple(c: &mut Criterion) {
pub fn build_with_flag(c: &mut Criterion) {
c.bench_function("build_with_flag", |b| {
b.iter(|| App::new("claptests").arg(Arg::from("-s, --some 'something'")))
b.iter(|| App::new("claptests").arg(arg!(-s --some "something")))
});
}
pub fn build_with_flag_ref(c: &mut Criterion) {
c.bench_function("build_with_flag_ref", |b| {
b.iter(|| {
let arg = Arg::from("-s, --some 'something'");
let arg = arg!(-s --some "something");
App::new("claptests").arg(&arg)
})
});
@ -34,14 +34,14 @@ pub fn build_with_flag_ref(c: &mut Criterion) {
pub fn build_with_opt(c: &mut Criterion) {
c.bench_function("build_with_opt", |b| {
b.iter(|| App::new("claptests").arg(Arg::from("-s, --some <FILE> 'something'")))
b.iter(|| App::new("claptests").arg(arg!(-s --some <FILE> "something")))
});
}
pub fn build_with_opt_ref(c: &mut Criterion) {
c.bench_function("build_with_opt_ref", |b| {
b.iter(|| {
let arg = Arg::from("-s, --some <FILE> 'something'");
let arg = arg!(-s --some <FILE> "something");
App::new("claptests").arg(&arg)
})
});

View file

@ -1,4 +1,4 @@
use clap::{App, AppSettings, Arg, ArgSettings};
use clap::{arg, App, AppSettings, Arg, ArgSettings};
use criterion::{criterion_group, criterion_main, Criterion};
static OPT3_VALS: [&str; 2] = ["fast", "slow"];
@ -10,43 +10,41 @@ macro_rules! create_app {
.version("0.1")
.about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>")
.arg("-o --option=[opt]... 'tests options'")
.arg("[positional] 'tests positionals'")
.arg(Arg::from("-f --flag... 'tests flags'").global(true))
.arg(arg!(-o --option <opt> ... "tests options").required(false))
.arg(arg!([positional] "tests positionals"))
.arg(arg!(-f --flag ... "tests flags").global(true))
.args(&[
Arg::from("[flag2] -F 'tests flags with exclusions'")
arg!(flag2: -F "tests flags with exclusions")
.conflicts_with("flag")
.requires("option2"),
Arg::from(
"[option2] --long-option-2 [option2] 'tests long options with exclusions'",
)
.conflicts_with("option")
.requires("positional2"),
Arg::from("[positional2] 'tests positionals with exclusions'"),
Arg::from("-O --Option [option3] 'tests options with specific value sets'")
arg!(option2: --"long-option-2" <option2> "tests long options with exclusions")
.required(false)
.conflicts_with("option")
.requires("positional2"),
arg!([positional2] "tests positionals with exclusions"),
arg!(-O --Option <option3> "tests options with specific value sets")
.required(false)
.possible_values(OPT3_VALS),
Arg::from("[positional3]... 'tests positionals with specific values'")
arg!([positional3] ... "tests positionals with specific values")
.possible_values(POS3_VALS),
Arg::from("--multvals [one] [two] 'Tests multiple values, not mult occs'"),
Arg::from("--multvalsmo... [one] [two] 'Tests multiple values, not mult occs'"),
Arg::from("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
Arg::from("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3),
arg!(--multvals "Tests multiple values not mult occs").required(false).value_names(&["one", "two"]),
arg!(
--multvalsmo "Tests multiple values, not mult occs"
).multiple_values(true).required(false).value_names(&["one", "two"]),
arg!(--minvals2 <minvals> ... "Tests 2 min vals").min_values(2).multiple_values(true).required(false),
arg!(--maxvals3 <maxvals> ... "Tests 3 max vals").max_values(3).multiple_values(true).required(false),
])
.subcommand(
App::new("subcmd")
.about("tests subcommands")
.version("0.1")
.author("Kevin K. <kbknapp@gmail.com>")
.arg("-o --option [scoption]... 'tests options'")
.arg("[scpositional] 'tests positionals'"),
.arg(arg!(-o --option <scoption> ... "tests options").required(false))
.arg(arg!([scpositional] "tests positionals"))
)
}};
}
pub fn build_from_usage(c: &mut Criterion) {
c.bench_function("build_from_usage", |b| b.iter(|| create_app!()));
}
pub fn build_from_builder(c: &mut Criterion) {
c.bench_function("build_from_builder", |b| {
b.iter(|| {
@ -291,7 +289,6 @@ pub fn parse_complex_with_sc_complex(c: &mut Criterion) {
criterion_group!(
benches,
build_from_usage,
build_from_builder,
parse_complex,
parse_complex_with_flag,

View file

@ -1,5 +1,5 @@
use clap::App;
use clap::{Arg, ArgSettings};
use clap::{arg, Arg, ArgSettings};
use criterion::{criterion_group, criterion_main, Criterion};
use std::io::Cursor;
@ -15,13 +15,18 @@ fn app_example1<'c>() -> App<'c> {
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'")
.arg("<output> 'Sets an optional output file'")
.arg("-d... 'Turn debugging information on'")
.arg(
arg!(
-c --config <FILE> "Sets a custom config file"
)
.required(false),
)
.arg(arg!(<output> "Sets an optional output file"))
.arg(arg!(d: -d ... "Turn debugging information on"))
.subcommand(
App::new("test")
.about("does testing things")
.arg("-l, --list 'lists test values'"),
.arg(arg!(-l --list "lists test values")),
)
}
@ -49,9 +54,14 @@ fn app_example3<'c>() -> App<'c> {
.help("the input file to use")
.setting(ArgSettings::Required),
])
.arg("--license 'display the license file'")
.arg("[output] 'Supply an output file to use'")
.arg("-i, --int=[IFACE] 'Set an interface to use'")
.arg(arg!(--license "display the license file"))
.arg(arg!([output] "Supply an output file to use"))
.arg(
arg!(
-i --int <IFACE> "Set an interface to use"
)
.required(false),
)
}
fn app_example4<'c>() -> App<'c> {

View file

@ -1,4 +1,4 @@
use clap::App;
use clap::{arg, App};
fn main() {
// This example shows how to create an application with several arguments using usage strings, which can be
@ -33,13 +33,20 @@ fn main() {
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'")
.arg("[output] 'Sets an optional output file'")
.arg("-d..., --debug... 'Turn debugging information on'")
.arg(
arg!(
-c --config <FILE> "Sets a custom config file"
)
.required(false),
)
.arg(arg!([output] "Sets an optional output file"))
.arg(arg!(
-d --debug ... "Turn debugging information on"
))
.subcommand(
App::new("test")
.about("does testing things")
.arg("-l, --list 'lists test values'"),
.arg(arg!(-l --list "lists test values")),
)
.get_matches();

View file

@ -9,8 +9,8 @@ fn main() {
// another option, usage(), which is an exception to the rule. This should only be used when
// the default usage string automatically generated by clap doesn't suffice.
//
// You also set all the valid arguments your App should accept via the arg(), args(), arg()
// and args_from_usage() (as well as subcommands via the subcommand() and subcommands() methods) which
// You also set all the valid arguments your App should accept via the arg() and args()
// (as well as subcommands via the subcommand() and subcommands() methods) which
// will be covered later.
//
// Once all options have been set, call one of the .get_matches* family of methods in order to

View file

@ -1,4 +1,4 @@
use clap::{App, Arg};
use clap::{arg, App, Arg};
fn main() {
// Args describe a possible valid argument which may be supplied by the user at runtime. There
@ -9,9 +9,8 @@ fn main() {
// methods describing various settings for the individual arguments. Or by supplying a "usage"
// string. Both methods have their pros and cons.
//
// Arguments can be added to applications in two manners, one at a time with the arg(), and
// arg() method, or multiple arguments at once via a Vec<Arg> inside the args() method,
// or a single &str describing multiple Args (one per line) supplied to args_from_usage().
// Arguments can be added to applications in two manners, one at a time with the arg()
// method, or multiple arguments at once via a `&[Arg]` inside the args() method.
//
// There are various options which can be set for a given argument, some apply to any of the
// three types of arguments, some only apply one or two of the types. *NOTE* if you set
@ -50,10 +49,15 @@ fn main() {
//
//
// One "Flag" using a usage string
.arg("--license 'display the license file'")
// Two args, one "Positional", and one "Option" using a usage string
.arg("[output] 'Supply an output file to use'")
.arg("-i, --int=[IFACE] 'Set an interface to use'")
.arg(arg!(--license "display the license file"))
// Two args one Positional and one Option using a usage string
.arg(arg!([output] "Supply an output file to use"))
.arg(
arg!(
-i --int <IFACE> "Set an interface to use"
)
.required(false),
)
.get_matches();
// Here are some examples of using the arguments defined above. Keep in mind that this is only

View file

@ -1,4 +1,4 @@
use clap::{App, Arg};
use clap::{arg, App, Arg};
fn main() {
// Of the three argument types, flags are the most simple. Flags are simple switches which can
@ -29,8 +29,13 @@ fn main() {
// also has a conflicts_with_all(Vec<&str>)
// and an exclusive(true)
)
.arg("-c, --config=[FILE] 'sets a custom config file'")
.arg("[output] 'sets an output file'")
.arg(
arg!(
-c --config <FILE> "sets a custom config file"
)
.required(false),
)
.arg(arg!([output] "sets an output file"))
.get_matches();
// We can find out whether or not awesome was used

View file

@ -1,4 +1,4 @@
use clap::{App, Arg};
use clap::{arg, App, Arg};
fn main() {
// Option arguments are those that take an additional value, such as "-c value". In clap they
@ -33,8 +33,13 @@ fn main() {
// also has a conflicts_with_all(Vec<&str>)
// and an exclusive(true)
)
.arg("-c, --config=[FILE] 'the config file to use'")
.arg("[output] 'the output file to use'")
.arg(
arg!(
-c --config <FILE> "the config file to use"
)
.required(false),
)
.arg(arg!([output] "the output file to use"))
.get_matches();
// We can find out whether or not "input" was used

View file

@ -1,4 +1,4 @@
use clap::App;
use clap::{arg, App};
fn main() {
// You can use some convenience methods provided by clap to get typed values, so long as the
@ -22,8 +22,15 @@ fn main() {
let matches = App::new("myapp")
// Create two arguments, a required positional which accepts multiple values
// and an optional '-l value'
.arg("<seq>... 'A sequence of whole positive numbers, i.e. 20 25 30'")
.arg("-l [len] 'A length to use, defaults to 10 when omitted'")
.arg(arg!(
<seq> ... "A sequence of whole positive numbers, i.e. 20 25 30"
))
.arg(
arg!(
l: -l <len> "A length to use, defaults to 10 when omitted"
)
.required(false),
)
.get_matches();
// This code loops through all the values provided to "seq" and adds 2

View file

@ -5,7 +5,7 @@
use std::str::FromStr;
// Add clap like normal
use clap::{App, Arg};
use clap::{arg, App};
// Define your enum
enum Vals {
@ -35,7 +35,7 @@ fn main() {
let m = App::new("myapp")
// Use a single positional argument that is required
.arg(
Arg::from("<type> 'The type to use'")
arg!(<type> "The type to use")
// Define the list of possible values
.possible_values(["Foo", "Bar", "Baz", "Qux"]),
)

View file

@ -20,16 +20,16 @@
/// 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 specify that *at least one* of
/// them is used. For this, you can create a group.
use clap::{App, Arg, ArgGroup};
use clap::{arg, App, Arg, ArgGroup};
fn main() {
// Create application like normal
let matches = App::new("myapp")
// Add the version arguments
.arg("--set-ver [ver] 'set version manually'")
.arg("--major 'auto inc major'")
.arg("--minor 'auto inc minor'")
.arg("--patch 'auto inc patch'")
.arg(arg!(--"set-ver" <ver> "set version manually").required(false))
.arg(arg!(--major "auto inc major"))
.arg(arg!(--minor "auto inc minor"))
.arg(arg!(--patch "auto inc patch"))
// Create a group, make it required, and add the above arguments
.group(
ArgGroup::new("vers")
@ -38,8 +38,12 @@ fn main() {
)
// Arguments can also be added to a group individually, these two arguments
// are part of the "input" group which is not required
.arg(Arg::from("[INPUT_FILE] 'some regular input'").group("input"))
.arg(Arg::from("--spec-in [SPEC_IN] 'some special input argument'").group("input"))
.arg(arg!([INPUT_FILE] "some regular input").group("input"))
.arg(
arg!(--"spec-in" <SPEC_IN> "some special input argument")
.required(false)
.group("input"),
)
// Now let's assume we have a -c [config] argument which requires one of
// (but **not** both) the "input" arguments
.arg(

View file

@ -1,4 +1,4 @@
use clap::{App, AppSettings};
use clap::{arg, App, AppSettings};
fn main() {
// You can use AppSettings to change the application level behavior of clap. .setting() function
@ -11,7 +11,7 @@ fn main() {
let matches = App::new("myapp")
.setting(AppSettings::SubcommandsNegateReqs)
// Negates requirement of parent command.
.arg("<input> 'input file to use'")
.arg(arg!(<input> "input file to use"))
// Required positional argument called input. This
// will be only required if subcommand is not present.
.subcommand(App::new("test").about("does some testing"))

View file

@ -1,50 +0,0 @@
// In order to use YAML to define your CLI you must compile clap with the "yaml" feature because
// it's **not** included by default.
//
// In order to do this, ensure your Cargo.toml looks like one of the following:
//
// [dependencies.clap]
// features = ["yaml"]
//
// __OR__
//
// [dependencies]
// clap = { features = ["yaml"] }
// Using yaml requires calling a clap macro `load_yaml!()`.
// Note: If you're using clap as a dependency and don't have a feature for your users called
// "yaml", you'll need to remove the #[cfg(feature = "yaml")] conditional compilation attribute
#[cfg(feature = "yaml")]
fn main() {
use clap::{load_yaml, App};
// To load a yaml file containing our CLI definition such as the example '17_yaml.yaml' we can
// use the convenience macro which loads the file at compile relative to the current file
// similar to how modules are found.
//
// Then we pass that yaml object to App to build the CLI.
//
// Finally we call get_matches() to start the parsing process. We use the matches just as we
// normally would
let yaml = load_yaml!("17_yaml.yaml");
let m = App::from(yaml).get_matches();
// Because the example 17_yaml.yaml is rather large we'll just look a single arg so you can
// see that it works...
if let Some(mode) = m.value_of("mode") {
match mode {
"vi" => println!("You are using vi"),
"emacs" => println!("You are using emacs..."),
_ => unreachable!(),
}
} else {
println!("--mode <MODE> wasn't used...");
}
}
#[cfg(not(feature = "yaml"))]
fn main() {
// As stated above, if clap is not compiled with the YAML feature, it is disabled.
println!("YAML feature is disabled.");
println!("Pass --features yaml to cargo when trying this example.");
}

View file

@ -1,98 +0,0 @@
name: yaml_app
version: "1.0"
about: an example using a .yaml file to build a CLI
author: Kevin K. <kbknapp@gmail.com>
# AppSettings can be defined as a list and are **not** ascii case sensitive
settings:
- ArgRequiredElseHelp
# All Args must be defined in the 'args:' list where the name of the arg, is the
# key to a Hash object
args:
# The name of this argument, is 'opt' which will be used to access the value
# later in your Rust code
- opt:
help: example option argument from yaml
short: o
long: option
multiple_occurrences: true
takes_value: true
- pos:
help: example positional argument from yaml
index: 1
# A list of possible values can be defined as a list
possible_values:
- fast
- slow
- flag:
help: demo flag argument
short: F
multiple_occurrences: true
takes_value: true
global: true
# Conflicts, mutual overrides, and requirements can all be defined as a
# list, where the key is the name of the other argument
conflicts_with:
- opt
requires:
- pos
- mode:
long: mode
help: shows an option with specific values
# possible_values can also be defined in this list format
possible_values: [ vi, emacs ]
takes_value: true
- mvals:
long: mult-vals
help: demos an option which has two named values
# value names can be described in a list, where the help will be shown
# --mult-vals <one> <two>
value_names:
- one
- two
- minvals:
long: min-vals
multiple_values: true
help: you must supply at least two values to satisfy me
min_values: 2
- maxvals:
long: max-vals
multiple_values: true
help: you can only supply a max of 3 values for me!
max_values: 3
# All subcommands must be listed in the 'subcommand:' object, where the key to
# the list is the name of the subcommand, and all settings for that command are
# are part of a Hash object
subcommands:
# The name of this subcommand will be 'subcmd' which can be accessed in your
# Rust code later
- subcmd:
about: demos subcommands from yaml
version: "0.1"
author: Kevin K. <kbknapp@gmail.com>
# Subcommand args are exactly like App args
args:
- scopt:
short: B
multiple_occurrences: true
help: example subcommand option
takes_value: true
- scpos1:
help: example subcommand positional
index: 1
# ArgGroups are supported as well, and must be specified in the 'groups:'
# object of this file
groups:
# the name of the ArgGoup is specified here
- min-max-vals:
# All args and groups that are a part of this group are set here
args:
- minvals
- maxvals
# setting conflicts is done the same manner as setting 'args:'
#
# to make this group required, you could set 'required: true' but for
# this example we won't do that.

View file

@ -83,7 +83,7 @@ pub struct App<'help> {
pub(crate) usage_str: Option<&'help str>,
pub(crate) usage: Option<String>,
pub(crate) help_str: Option<&'help str>,
pub(crate) disp_ord: usize,
pub(crate) disp_ord: Option<usize>,
pub(crate) term_w: Option<usize>,
pub(crate) max_w: Option<usize>,
pub(crate) template: Option<&'help str>,
@ -379,7 +379,6 @@ impl<'help> App<'help> {
App {
id: Id::from(&*name),
name,
disp_ord: 999,
..Default::default()
}
.arg(
@ -398,11 +397,109 @@ impl<'help> App<'help> {
)
}
/// Deprecated, see [`App::from`]
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[deprecated(since = "3.0.0", note = "Replaced with `App::from`")]
pub fn from_yaml(yaml: &'help Yaml) -> Self {
Self::from(yaml)
#[deprecated(
since = "3.0.0",
note = "Maybe clap::Parser would fit your use case? (Issue #9)"
)]
pub fn from_yaml(y: &'help Yaml) -> Self {
#![allow(deprecated)]
let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
// We WANT this to panic on error...so expect() is good.
let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() {
(App::new(name), yaml_file_hash, "app".into())
} else {
let (name_yaml, value_yaml) = yaml_file_hash
.iter()
.next()
.expect("There must be one subcommand in the YAML file");
let name_str = name_yaml
.as_str()
.expect("Subcommand name must be a string");
(
App::new(name_str),
value_yaml.as_hash().expect("Subcommand must be a hash"),
format!("subcommand '{}'", name_str),
)
};
let mut has_metadata = false;
for (k, v) in yaml {
a = match k.as_str().expect("App fields must be strings") {
"_has_metadata" => {
has_metadata = true;
a
}
"bin_name" => yaml_to_str!(a, v, bin_name),
"version" => yaml_to_str!(a, v, version),
"long_version" => yaml_to_str!(a, v, long_version),
"author" => yaml_to_str!(a, v, author),
"about" => yaml_to_str!(a, v, about),
"before_help" => yaml_to_str!(a, v, before_help),
"before_long_help" => yaml_to_str!(a, v, before_long_help),
"after_help" => yaml_to_str!(a, v, after_help),
"after_long_help" => yaml_to_str!(a, v, after_long_help),
"help_heading" => yaml_to_str!(a, v, help_heading),
"help_template" => yaml_to_str!(a, v, help_template),
"override_help" => yaml_to_str!(a, v, override_help),
"override_usage" => yaml_to_str!(a, v, override_usage),
"alias" => yaml_to_str!(a, v, alias),
"aliases" => yaml_vec_or_str!(a, v, alias),
"visible_alias" => yaml_to_str!(a, v, visible_alias),
"visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
"display_order" => yaml_to_usize!(a, v, display_order),
"term_width" => yaml_to_usize!(a, v, term_width),
"max_term_width" => yaml_to_usize!(a, v, max_term_width),
"args" => {
if let Some(vec) = v.as_vec() {
for arg_yaml in vec {
a = a.arg(Arg::from_yaml(arg_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"subcommands" => {
if let Some(vec) = v.as_vec() {
for sc_yaml in vec {
a = a.subcommand(App::from_yaml(sc_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"groups" => {
if let Some(vec) = v.as_vec() {
for ag_yaml in vec {
a = a.group(ArgGroup::from(ag_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"setting" | "settings" => {
yaml_to_setting!(a, v, setting, AppSettings, "AppSetting", err)
}
"global_setting" | "global_settings" => {
yaml_to_setting!(a, v, global_setting, AppSettings, "AppSetting", err)
}
"name" => continue,
s => {
if !has_metadata {
panic!("Unknown setting '{}' in YAML file for {}", s, err)
}
continue;
}
}
}
a
}
/// Sets a string of author(s) that will be displayed to the user when they
@ -793,7 +890,7 @@ impl<'help> App<'help> {
self
}
/// Deprecated, see [`App::override_usage`]
/// Deprecated, replaced with [`App::override_usage`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::override_usage`")]
pub fn usage<S: Into<&'help str>>(self, usage: S) -> Self {
self.override_usage(usage)
@ -839,7 +936,7 @@ impl<'help> App<'help> {
self
}
/// Deprecated, see [`App::override_help`]
/// Deprecated, replaced with [`App::override_help`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::override_help`")]
pub fn help<S: Into<&'help str>>(self, help: S) -> Self {
self.override_help(help)
@ -893,7 +990,7 @@ impl<'help> App<'help> {
self
}
/// Deprecated, see [`App::help_template`]
/// Deprecated, replaced with [`App::help_template`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::help_template`")]
pub fn template<S: Into<&'help str>>(self, s: S) -> Self {
self.help_template(s)
@ -1061,7 +1158,7 @@ impl<'help> App<'help> {
self
}
/// Deprecated, see [`App::term_width`]
/// Deprecated, replaced with [`App::term_width`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::term_width`")]
pub fn set_term_width(self, width: usize) -> Self {
self.term_width(width)
@ -1102,7 +1199,7 @@ impl<'help> App<'help> {
/// # Examples
///
/// ```no_run
/// # use clap::{App, Arg};
/// # use clap::{App, arg, Arg};
/// App::new("myprog")
/// // Adding a single "flag" argument with a short and help text, using Arg::new()
/// .arg(
@ -1113,7 +1210,7 @@ impl<'help> App<'help> {
/// // Adding a single "option" argument with a short, a long, and help text using the less
/// // verbose Arg::from()
/// .arg(
/// Arg::from("-c --config=[CONFIG] 'Optionally sets a config file to use'")
/// arg!(-c --config <CONFIG> "Optionally sets a config file to use")
/// )
/// # ;
/// ```
@ -1150,10 +1247,10 @@ impl<'help> App<'help> {
/// # Examples
///
/// ```no_run
/// # use clap::{App, Arg};
/// # use clap::{App, arg, Arg};
/// App::new("myprog")
/// .args(&[
/// Arg::from("[debug] -d 'turns on debugging info'"),
/// arg!("[debug] -d 'turns on debugging info'"),
/// Arg::new("input").index(1).help("the input file to use")
/// ])
/// # ;
@ -1174,10 +1271,25 @@ impl<'help> App<'help> {
self
}
/// Deprecated, see [`App::arg`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::arg`")]
/// Deprecated in [Issue #8](https://github.com/epage/clapng/issues/8), see [`arg!`][crate::arg!].
#[deprecated(since = "3.0.0", note = "Replaced with `arg!`")]
pub fn arg_from_usage(self, usage: &'help str) -> Self {
self.arg(usage)
#![allow(deprecated)]
self.arg(Arg::from_usage(usage))
}
/// Deprecated in [Issue #8](https://github.com/epage/clapng/issues/8), see [`arg!`][crate::arg!].
#[deprecated(since = "3.0.0", note = "Replaced with `arg!`")]
pub fn args_from_usage(mut self, usage: &'help str) -> Self {
#![allow(deprecated)]
for line in usage.lines() {
let l = line.trim();
if l.is_empty() {
continue;
}
self = self.arg(Arg::from_usage(l));
}
self
}
/// If this `App` instance is a subcommand, this method adds an alias, which
@ -1615,12 +1727,12 @@ impl<'help> App<'help> {
/// of the arguments from the specified group is present at runtime.
///
/// ```no_run
/// # use clap::{App, ArgGroup};
/// # use clap::{App, arg, ArgGroup};
/// App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'")
/// .arg("--major 'auto increase major'")
/// .arg("--minor 'auto increase minor'")
/// .arg("--patch 'auto increase patch'")
/// .arg(arg!("--set-ver [ver] 'set the version manually'"))
/// .arg(arg!("--major 'auto increase major'"))
/// .arg(arg!("--minor 'auto increase minor'"))
/// .arg(arg!("--patch 'auto increase patch'"))
/// .group(ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor","patch"])
/// .required(true))
@ -1637,14 +1749,14 @@ impl<'help> App<'help> {
/// # Examples
///
/// ```no_run
/// # use clap::{App, ArgGroup};
/// # use clap::{App, arg, ArgGroup};
/// App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'")
/// .arg("--major 'auto increase major'")
/// .arg("--minor 'auto increase minor'")
/// .arg("--patch 'auto increase patch'")
/// .arg("-c [FILE] 'a config file'")
/// .arg("-i [IFACE] 'an interface'")
/// .arg(arg!("--set-ver [ver] 'set the version manually'"))
/// .arg(arg!("--major 'auto increase major'"))
/// .arg(arg!("--minor 'auto increase minor'"))
/// .arg(arg!("--patch 'auto increase patch'"))
/// .arg(arg!("-c [FILE] 'a config file'"))
/// .arg(arg!("-i [IFACE] 'an interface'"))
/// .groups(&[
/// ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor","patch"])
@ -1673,11 +1785,11 @@ impl<'help> App<'help> {
/// # Examples
///
/// ```no_run
/// # use clap::{App, Arg, };
/// # use clap::{App, arg};
/// App::new("myprog")
/// .subcommand(App::new("config")
/// .about("Controls configuration features")
/// .arg("<config> 'Required configuration file to use'"))
/// .arg(arg!("<config> 'Required configuration file to use'")))
/// # ;
/// ```
#[inline]
@ -1760,7 +1872,7 @@ impl<'help> App<'help> {
/// ```
#[inline]
pub fn display_order(mut self, ord: usize) -> Self {
self.disp_ord = ord;
self.disp_ord = Some(ord);
self
}
@ -2066,7 +2178,7 @@ impl<'help> App<'help> {
self.try_get_matches_from(&mut env::args_os())
}
/// Deprecated, see [`App::try_get_matches`]
/// Deprecated, replaced with [`App::try_get_matches`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches`")]
pub fn get_matches_safe(self) -> ClapResult<ArgMatches> {
self.try_get_matches()
@ -2142,7 +2254,7 @@ impl<'help> App<'help> {
self.try_get_matches_from_mut(itr)
}
/// Deprecated, see [`App::try_get_matches_from`]
/// Deprecated, replaced with [`App::try_get_matches_from`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches_from`")]
pub fn get_matches_from_safe<I, T>(self, itr: I) -> ClapResult<ArgMatches>
where
@ -2251,7 +2363,7 @@ impl<'help> App<'help> {
self._do_parse(&mut it)
}
/// Deprecated, see [`App::try_get_matches_from_mut`]
/// Deprecated, replaced with [`App::try_get_matches_from_mut`]
#[deprecated(
since = "3.0.0",
note = "Replaced with `App::try_get_matches_from_mut`"
@ -2654,19 +2766,19 @@ impl<'help> App<'help> {
.args
.args_mut()
.filter(|a| !a.is_positional())
.filter(|a| a.disp_ord == 999)
.filter(|a| a.get_display_order() == 999)
.filter(|a| a.provider != ArgProvider::Generated)
.enumerate()
{
a.disp_ord = i;
a.disp_ord = Some(i);
}
for (i, mut sc) in &mut self
.subcommands
.iter_mut()
.enumerate()
.filter(|&(_, ref sc)| sc.disp_ord == 999)
.filter(|&(_, ref sc)| sc.get_display_order() == 999)
{
sc.disp_ord = i;
sc.disp_ord = Some(i);
}
}
for sc in &mut self.subcommands {
@ -2955,6 +3067,10 @@ impl<'help> App<'help> {
.find(|sc| sc.long_flag_aliases_to(long))
.map(|sc| sc.get_name())
}
pub(crate) fn get_display_order(&self) -> usize {
self.disp_ord.unwrap_or(999)
}
}
impl<'help> Index<&'_ Id> for App<'help> {
@ -2965,108 +3081,6 @@ impl<'help> Index<&'_ Id> for App<'help> {
}
}
#[cfg(feature = "yaml")]
impl<'help> From<&'help Yaml> for App<'help> {
#[allow(clippy::cognitive_complexity)]
fn from(y: &'help Yaml) -> Self {
let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
// We WANT this to panic on error...so expect() is good.
let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() {
(App::new(name), yaml_file_hash, "app".into())
} else {
let (name_yaml, value_yaml) = yaml_file_hash
.iter()
.next()
.expect("There must be one subcommand in the YAML file");
let name_str = name_yaml
.as_str()
.expect("Subcommand name must be a string");
(
App::new(name_str),
value_yaml.as_hash().expect("Subcommand must be a hash"),
format!("subcommand '{}'", name_str),
)
};
let mut has_metadata = false;
for (k, v) in yaml {
a = match k.as_str().expect("App fields must be strings") {
"_has_metadata" => {
has_metadata = true;
a
}
"bin_name" => yaml_to_str!(a, v, bin_name),
"version" => yaml_to_str!(a, v, version),
"long_version" => yaml_to_str!(a, v, long_version),
"author" => yaml_to_str!(a, v, author),
"about" => yaml_to_str!(a, v, about),
"before_help" => yaml_to_str!(a, v, before_help),
"before_long_help" => yaml_to_str!(a, v, before_long_help),
"after_help" => yaml_to_str!(a, v, after_help),
"after_long_help" => yaml_to_str!(a, v, after_long_help),
"help_heading" => yaml_to_str!(a, v, help_heading),
"help_template" => yaml_to_str!(a, v, help_template),
"override_help" => yaml_to_str!(a, v, override_help),
"override_usage" => yaml_to_str!(a, v, override_usage),
"alias" => yaml_to_str!(a, v, alias),
"aliases" => yaml_vec_or_str!(a, v, alias),
"visible_alias" => yaml_to_str!(a, v, visible_alias),
"visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
"display_order" => yaml_to_usize!(a, v, display_order),
"term_width" => yaml_to_usize!(a, v, term_width),
"max_term_width" => yaml_to_usize!(a, v, max_term_width),
"args" => {
if let Some(vec) = v.as_vec() {
for arg_yaml in vec {
a = a.arg(Arg::from(arg_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"subcommands" => {
if let Some(vec) = v.as_vec() {
for sc_yaml in vec {
a = a.subcommand(App::from(sc_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"groups" => {
if let Some(vec) = v.as_vec() {
for ag_yaml in vec {
a = a.group(ArgGroup::from(ag_yaml));
}
} else {
panic!("Failed to convert YAML value {:?} to a vec", v);
}
a
}
"setting" | "settings" => {
yaml_to_setting!(a, v, setting, AppSettings, "AppSetting", err)
}
"global_setting" | "global_settings" => {
yaml_to_setting!(a, v, global_setting, AppSettings, "AppSetting", err)
}
"name" => continue,
s => {
if !has_metadata {
panic!("Unknown setting '{}' in YAML file for {}", s, err)
}
continue;
}
}
}
a
}
}
impl fmt::Display for App<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)

View file

@ -519,11 +519,11 @@ pub enum AppSettings {
#[deprecated(since = "3.0.0", note = "Replaced with `App::color`")]
ColorAuto,
/// Deprecated, see [`App::color`][crate::App::color]
/// Deprecated, replaced with [`App::color`][crate::App::color]
#[deprecated(since = "3.0.0", note = "Replaced with `App::color`")]
ColorAlways,
/// Deprecated, see [`App::color`][crate::App::color]
/// Deprecated, replaced with [`App::color`][crate::App::color]
#[deprecated(since = "3.0.0", note = "Replaced with `App::color`")]
ColorNever,
@ -574,7 +574,7 @@ pub enum AppSettings {
/// ```
DisableHelpFlag,
/// Deprecated, see [`AppSettings::DisableHelpFlag`]
/// Deprecated, replaced with [`AppSettings::DisableHelpFlag`]
#[deprecated(since = "3.0.0", note = "Replaced with `AppSettings::DisableHelpFlag`")]
DisableHelpFlags,
@ -615,7 +615,7 @@ pub enum AppSettings {
/// ```
DisableVersionFlag,
/// Deprecated, see [`AppSettings::DisableVersionFlag`]
/// Deprecated, replaced with [`AppSettings::DisableVersionFlag`]
#[deprecated(
since = "3.0.0",
note = "Replaced with `AppSettings::DisableVersionFlag`"
@ -743,7 +743,7 @@ pub enum AppSettings {
/// [`subcommands`]: crate::App::subcommand()
PropagateVersion,
/// Deprecated, see [`AppSettings::PropagateVersion`]
/// Deprecated, replaced with [`AppSettings::PropagateVersion`]
#[deprecated(
since = "3.0.0",
note = "Replaced with `AppSettings::PropagateVersion`"
@ -819,12 +819,12 @@ pub enum AppSettings {
/// avoided in many cases.
///
/// ```rust
/// # use clap::{App, AppSettings};
/// # use clap::{App, arg, AppSettings};
/// let app = App::new("app")
/// .setting(AppSettings::IgnoreErrors)
/// .arg("-c, --config=[FILE] 'Sets a custom config file'")
/// .arg("-x, --stuff=[FILE] 'Sets a custom stuff file'")
/// .arg("-f 'Flag'");
/// .arg(arg!(-c --config <FILE> "Sets a custom config file").required(false))
/// .arg(arg!(-x --stuff <FILE> "Sets a custom stuff file").required(false))
/// .arg(arg!(f: -f "Flag"));
///
/// let r = app.try_get_matches_from(vec!["app", "-c", "file", "-f", "-x"]);
///
@ -883,10 +883,10 @@ pub enum AppSettings {
/// # Examples
///
/// ```rust
/// # use clap::{App, Arg, AppSettings};
/// # use clap::{App, arg, AppSettings};
/// let m = App::new("myprog")
/// .setting(AppSettings::NoBinaryName)
/// .arg(Arg::from("<cmd>... 'commands to run'"))
/// .arg(arg!(<cmd> ... "commands to run"))
/// .get_matches_from(vec!["command", "set"]);
///
/// let cmds: Vec<&str> = m.values_of("cmd").unwrap().collect();
@ -1028,10 +1028,10 @@ pub enum AppSettings {
/// # Examples
///
/// ```rust
/// # use clap::{App, Arg, AppSettings};
/// # use clap::{App, arg, AppSettings};
/// let m = App::new("myprog")
/// .setting(AppSettings::TrailingVarArg)
/// .arg(Arg::from("<cmd>... 'commands to run'"))
/// .arg(arg!(<cmd> ... "commands to run"))
/// .get_matches_from(vec!["myprog", "arg1", "-r", "val1"]);
///
/// let trail: Vec<&str> = m.values_of("cmd").unwrap().collect();

View file

@ -69,7 +69,7 @@ impl Default for ArgProvider {
/// # Examples
///
/// ```rust
/// # use clap::Arg;
/// # use clap::{Arg, arg};
/// // Using the traditional builder pattern and setting each option manually
/// let cfg = Arg::new("config")
/// .short('c')
@ -78,7 +78,7 @@ impl Default for ArgProvider {
/// .value_name("FILE")
/// .help("Provides a config file to myprog");
/// // Using a usage string (setting a similar argument to the one above)
/// let input = Arg::from("-i, --input=[FILE] 'Provides an input file to the program'");
/// let input = arg!(-i --input <FILE> "Provides an input file to the program");
/// ```
#[allow(missing_debug_implementations)]
#[derive(Default, Clone)]
@ -101,7 +101,7 @@ pub struct Arg<'help> {
pub(crate) long: Option<&'help str>,
pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible)
pub(crate) short_aliases: Vec<(char, bool)>, // (name, visible)
pub(crate) disp_ord: usize,
pub(crate) disp_ord: Option<usize>,
pub(crate) possible_vals: Vec<PossibleValue<'help>>,
pub(crate) val_names: Vec<&'help str>,
pub(crate) num_vals: Option<usize>,
@ -338,28 +338,154 @@ impl<'help> Arg<'help> {
Arg {
id: Id::from(&*name),
name,
disp_ord: 999,
..Default::default()
}
}
/// Deprecated, see [`Arg::new`]
/// Deprecated, replaced with [`Arg::new`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::new`")]
pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
Self::new(n)
}
/// Deprecated, see [`Arg::from`]
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::from`")]
#[deprecated(
since = "3.0.0",
note = "Maybe clap::Parser would fit your use case? (Issue #9)"
)]
pub fn from_yaml(y: &'help Yaml) -> Self {
Self::from(y)
let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
// We WANT this to panic on error...so expect() is good.
let (name_yaml, yaml) = yaml_file_hash
.iter()
.next()
.expect("There must be one arg in the YAML file");
let name_str = name_yaml.as_str().expect("Arg name must be a string");
let mut a = Arg::new(name_str);
let mut has_metadata = false;
for (k, v) in yaml.as_hash().expect("Arg must be a hash") {
a = match k.as_str().expect("Arg fields must be strings") {
"_has_metadata" => {
has_metadata = true;
a
}
"short" => yaml_to_char!(a, v, short),
"long" => yaml_to_str!(a, v, long),
"alias" => yaml_to_str!(a, v, alias),
"aliases" => yaml_vec_or_str!(a, v, alias),
"short_alias" => yaml_to_str!(a, v, alias),
"short_aliases" => yaml_to_chars!(a, v, short_aliases),
"help" => yaml_to_str!(a, v, help),
"long_help" => yaml_to_str!(a, v, long_help),
"required" => yaml_to_bool!(a, v, required),
"required_if_eq" => yaml_tuple2!(a, v, required_if_eq),
"required_if_eq_any" => yaml_array_tuple2!(a, v, required_if_eq_any),
"required_if_eq_all" => yaml_array_tuple2!(a, v, required_if_eq_all),
"takes_value" => yaml_to_bool!(a, v, takes_value),
"index" => yaml_to_usize!(a, v, index),
"global" => yaml_to_bool!(a, v, global),
"multiple_occurrences" => yaml_to_bool!(a, v, multiple_occurrences),
"multiple_values" => yaml_to_bool!(a, v, multiple_values),
"hidden" => yaml_to_bool!(a, v, hidden),
"hidden_long_help" => yaml_to_bool!(a, v, hidden_long_help),
"hidden_short_help" => yaml_to_bool!(a, v, hidden_short_help),
"next_line_help" => yaml_to_bool!(a, v, next_line_help),
"group" => yaml_to_str!(a, v, group),
"number_of_values" => yaml_to_usize!(a, v, number_of_values),
"max_values" => yaml_to_usize!(a, v, max_values),
"min_values" => yaml_to_usize!(a, v, min_values),
"value_name" => yaml_to_str!(a, v, value_name),
"use_delimiter" => yaml_to_bool!(a, v, use_delimiter),
"allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values),
"raw" => yaml_to_bool!(a, v, raw),
"require_equals" => yaml_to_bool!(a, v, require_equals),
"require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
"value_terminator" => yaml_to_str!(a, v, value_terminator),
"value_delimiter" => yaml_to_char!(a, v, value_delimiter),
"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),
#[cfg(feature = "env")]
"env" => yaml_to_str!(a, v, env),
"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!(a, v, conflicts_with),
"exclusive" => yaml_to_bool!(a, v, exclusive),
"last" => yaml_to_bool!(a, v, last),
"help_heading" => yaml_to_str!(a, v, help_heading),
"value_hint" => yaml_str_parse!(a, v, value_hint),
"hide_default_value" => yaml_to_bool!(a, v, hide_default_value),
#[cfg(feature = "env")]
"hide_env" => yaml_to_bool!(a, v, hide_env),
#[cfg(feature = "env")]
"hide_env_values" => yaml_to_bool!(a, v, hide_env_values),
"hide_possible_values" => yaml_to_bool!(a, v, hide_possible_values),
"overrides_with" => yaml_to_str!(a, v, overrides_with),
"overrides_with_all" => yaml_vec_or_str!(a, v, overrides_with),
"possible_value" => yaml_to_str!(a, v, possible_value),
"possible_values" => yaml_vec_or_str!(a, v, possible_value),
"case_insensitive" => yaml_to_bool!(a, v, case_insensitive),
"required_unless_present_any" => yaml_vec!(a, v, required_unless_present_any),
"required_unless_present_all" => yaml_vec!(a, v, required_unless_present_all),
"visible_alias" => yaml_to_str!(a, v, visible_alias),
"visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
"visible_short_alias" => yaml_to_char!(a, v, visible_short_alias),
"visible_short_aliases" => yaml_to_chars!(a, v, visible_short_aliases),
#[cfg(feature = "regex")]
"validator_regex" => {
if let Some(vec) = v.as_vec() {
debug_assert_eq!(2, vec.len());
let regex = yaml_str!(vec[0]);
match Regex::new(regex) {
Err(e) => panic!(
"Failed to convert \"{}\" into regular expression: {}",
regex, e
),
Ok(regex) => a.validator_regex(regex, yaml_str!(vec[1])),
}
} else {
panic!("Failed to convert YAML value to vector")
}
}
"setting" | "settings" => {
yaml_to_setting!(
a,
v,
setting,
ArgSettings,
"ArgSetting",
format!("arg '{}'", name_str)
)
}
s => {
if !has_metadata {
panic!(
"Unknown setting '{}' in YAML file for arg '{}'",
s, name_str
)
}
continue;
}
}
}
a
}
/// Deprecated, see [`Arg::from`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::from`")]
/// Deprecated in [Issue #8](https://github.com/epage/clapng/issues/8), see [`arg!`][crate::arg!].
#[deprecated(since = "3.0.0", note = "Replaced with `arg!`")]
pub fn from_usage(u: &'help str) -> Self {
Self::from(u)
UsageParser::from_usage(u).parse()
}
pub(crate) fn generated(mut self) -> Self {
@ -367,6 +493,17 @@ impl<'help> Arg<'help> {
self
}
/// Set the identifier used for referencing this argument in the clap API.
///
/// **NOTE:** This will shown to the user in usage/help if no [`value_name`][Arg::value_name]
/// is provided.
pub fn name<S: Into<&'help str>>(mut self, n: S) -> Self {
let name = n.into();
self.id = Id::from(&*name);
self.name = name;
self
}
/// Sets the short version of the argument without the preceding `-`.
///
/// By default `clap` automatically assigns `V` and `h` to the auto-generated `version` and
@ -834,7 +971,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::required_unless_present`]
/// Deprecated, replaced with [`Arg::required_unless_present`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::required_unless_present`")]
pub fn required_unless<T: Key>(self, arg_id: T) -> Self {
self.required_unless_present(arg_id)
@ -914,7 +1051,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::required_unless_present_all`]
/// Deprecated, replaced with [`Arg::required_unless_present_all`]
#[deprecated(
since = "3.0.0",
note = "Replaced with `Arg::required_unless_present_all`"
@ -1003,7 +1140,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::required_unless_present_any`]
/// Deprecated, replaced with [`Arg::required_unless_present_any`]
#[deprecated(
since = "3.0.0",
note = "Replaced with `Arg::required_unless_present_any`"
@ -1180,12 +1317,12 @@ impl<'help> Arg<'help> {
/// # Examples
///
/// ```rust # use clap::{App, Arg};
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// let m = App::new("prog")
/// .arg(Arg::from("-f, --flag 'some flag'")
/// .arg(arg!(-f --flag "some flag")
/// .conflicts_with("debug"))
/// .arg(Arg::from("-d, --debug 'other flag'"))
/// .arg(Arg::from("-c, --color 'third flag'")
/// .arg(arg!(-d --debug "other flag"))
/// .arg(arg!(-c --color "third flag")
/// .overrides_with("flag"))
/// .get_matches_from(vec![
/// "prog", "-f", "-d", "-c"]);
@ -1205,9 +1342,9 @@ impl<'help> Arg<'help> {
/// preventing a "Unexpected multiple usage" error):
///
/// ```rust
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// let m = App::new("posix")
/// .arg(Arg::from("--flag 'some flag'").overrides_with("flag"))
/// .arg(arg!(--flag "some flag").overrides_with("flag"))
/// .get_matches_from(vec!["posix", "--flag", "--flag"]);
/// assert!(m.is_present("flag"));
/// assert_eq!(m.occurrences_of("flag"), 1);
@ -1218,9 +1355,9 @@ impl<'help> Arg<'help> {
/// if it's a flag and it already accepts multiple occurrences.
///
/// ```
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// let m = App::new("posix")
/// .arg(Arg::from("--flag... 'some flag'").overrides_with("flag"))
/// .arg(arg!(--flag ... "some flag").overrides_with("flag"))
/// .get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
/// assert!(m.is_present("flag"));
/// assert_eq!(m.occurrences_of("flag"), 4);
@ -1231,9 +1368,9 @@ impl<'help> Arg<'help> {
/// occurrence happened.
///
/// ```
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// let m = App::new("posix")
/// .arg(Arg::from("--opt [val] 'some option'").overrides_with("opt"))
/// .arg(arg!(--opt <val> "some option").overrides_with("opt"))
/// .get_matches_from(vec!["", "--opt=some", "--opt=other"]);
/// assert!(m.is_present("opt"));
/// assert_eq!(m.occurrences_of("opt"), 1);
@ -1262,9 +1399,10 @@ impl<'help> Arg<'help> {
/// will ignore the "override self" setting.
///
/// ```
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// let m = App::new("posix")
/// .arg(Arg::from("[opt]... --opt [val]... 'some option'")
/// .arg(arg!(--opt <val> ... "some option")
/// .multiple_values(true)
/// .overrides_with("opt"))
/// .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]);
/// assert!(m.is_present("opt"));
@ -1286,12 +1424,12 @@ impl<'help> Arg<'help> {
/// # Examples
///
/// ```rust
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// let m = App::new("prog")
/// .arg(Arg::from("-f, --flag 'some flag'")
/// .arg(arg!(-f --flag "some flag")
/// .conflicts_with("color"))
/// .arg(Arg::from("-d, --debug 'other flag'"))
/// .arg(Arg::from("-c, --color 'third flag'")
/// .arg(arg!(-d --debug "other flag"))
/// .arg(arg!(-c --color "third flag")
/// .overrides_with_all(&["flag", "debug"]))
/// .get_matches_from(vec![
/// "prog", "-f", "-d", "-c"]);
@ -1583,7 +1721,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::required_if_eq`]
/// Deprecated, replaced with [`Arg::required_if_eq`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq`")]
pub fn required_if<T: Key>(self, arg_id: T, val: &'help str) -> Self {
self.required_if_eq(arg_id, val)
@ -1675,7 +1813,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::required_if_eq_any`]
/// Deprecated, replaced with [`Arg::required_if_eq_any`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq_any`")]
pub fn required_ifs<T: Key>(self, ifs: &[(T, &'help str)]) -> Self {
self.required_if_eq_any(ifs)
@ -3382,7 +3520,7 @@ impl<'help> Arg<'help> {
/// [index]: Arg::index()
#[inline]
pub fn display_order(mut self, ord: usize) -> Self {
self.disp_ord = ord;
self.disp_ord = Some(ord);
self
}
@ -4269,7 +4407,7 @@ impl<'help> Arg<'help> {
}
}
/// Deprecated, see [`Arg::forbid_empty_values`]
/// Deprecated, replaced with [`Arg::forbid_empty_values`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::forbid_empty_values`")]
pub fn empty_values(self, empty: bool) -> Self {
self.forbid_empty_values(!empty)
@ -4514,7 +4652,7 @@ impl<'help> Arg<'help> {
}
}
/// Deprecated, see [`Arg::multiple_occurrences`] (most likely what you want) and
/// Deprecated, replaced with [`Arg::multiple_occurrences`] (most likely what you want) and
/// [`Arg::multiple_values`]
#[deprecated(
since = "3.0.0",
@ -4745,7 +4883,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::setting`]
/// Deprecated, replaced with [`Arg::setting`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::setting`")]
pub fn set(self, s: ArgSettings) -> Self {
self.setting(s)
@ -4780,7 +4918,7 @@ impl<'help> Arg<'help> {
self
}
/// Deprecated, see [`Arg::unset_setting`]
/// Deprecated, replaced with [`Arg::unset_setting`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::unset_setting`")]
pub fn unset(self, s: ArgSettings) -> Self {
self.unset_setting(s)
@ -4903,146 +5041,9 @@ impl<'help> Arg<'help> {
pub(crate) fn is_multiple(&self) -> bool {
self.is_set(ArgSettings::MultipleValues) | self.is_set(ArgSettings::MultipleOccurrences)
}
}
#[cfg(feature = "yaml")]
impl<'help> From<&'help Yaml> for Arg<'help> {
/// Creates a new instance of [`Arg`] from a .yaml (YAML) file.
///
/// # Examples
///
/// ```ignore
/// use clap::{Arg, load_yaml};
/// let yaml = load_yaml!("arg.yaml");
/// let arg = Arg::from(yaml);
/// ```
#[allow(clippy::cognitive_complexity)]
fn from(y: &'help Yaml) -> Self {
let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
// We WANT this to panic on error...so expect() is good.
let (name_yaml, yaml) = yaml_file_hash
.iter()
.next()
.expect("There must be one arg in the YAML file");
let name_str = name_yaml.as_str().expect("Arg name must be a string");
let mut a = Arg::new(name_str);
let mut has_metadata = false;
for (k, v) in yaml.as_hash().expect("Arg must be a hash") {
a = match k.as_str().expect("Arg fields must be strings") {
"_has_metadata" => {
has_metadata = true;
a
}
"short" => yaml_to_char!(a, v, short),
"long" => yaml_to_str!(a, v, long),
"alias" => yaml_to_str!(a, v, alias),
"aliases" => yaml_vec_or_str!(a, v, alias),
"short_alias" => yaml_to_str!(a, v, alias),
"short_aliases" => yaml_to_chars!(a, v, short_aliases),
"help" => yaml_to_str!(a, v, help),
"long_help" => yaml_to_str!(a, v, long_help),
"required" => yaml_to_bool!(a, v, required),
"required_if_eq" => yaml_tuple2!(a, v, required_if_eq),
"required_if_eq_any" => yaml_array_tuple2!(a, v, required_if_eq_any),
"required_if_eq_all" => yaml_array_tuple2!(a, v, required_if_eq_all),
"takes_value" => yaml_to_bool!(a, v, takes_value),
"index" => yaml_to_usize!(a, v, index),
"global" => yaml_to_bool!(a, v, global),
"multiple_occurrences" => yaml_to_bool!(a, v, multiple_occurrences),
"multiple_values" => yaml_to_bool!(a, v, multiple_values),
"hidden" => yaml_to_bool!(a, v, hidden),
"hidden_long_help" => yaml_to_bool!(a, v, hidden_long_help),
"hidden_short_help" => yaml_to_bool!(a, v, hidden_short_help),
"next_line_help" => yaml_to_bool!(a, v, next_line_help),
"group" => yaml_to_str!(a, v, group),
"number_of_values" => yaml_to_usize!(a, v, number_of_values),
"max_values" => yaml_to_usize!(a, v, max_values),
"min_values" => yaml_to_usize!(a, v, min_values),
"value_name" => yaml_to_str!(a, v, value_name),
"use_delimiter" => yaml_to_bool!(a, v, use_delimiter),
"allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values),
"raw" => yaml_to_bool!(a, v, raw),
"require_equals" => yaml_to_bool!(a, v, require_equals),
"require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
"value_terminator" => yaml_to_str!(a, v, value_terminator),
"value_delimiter" => yaml_to_char!(a, v, value_delimiter),
"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),
#[cfg(feature = "env")]
"env" => yaml_to_str!(a, v, env),
"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!(a, v, conflicts_with),
"exclusive" => yaml_to_bool!(a, v, exclusive),
"last" => yaml_to_bool!(a, v, last),
"help_heading" => yaml_to_str!(a, v, help_heading),
"value_hint" => yaml_str_parse!(a, v, value_hint),
"hide_default_value" => yaml_to_bool!(a, v, hide_default_value),
#[cfg(feature = "env")]
"hide_env" => yaml_to_bool!(a, v, hide_env),
#[cfg(feature = "env")]
"hide_env_values" => yaml_to_bool!(a, v, hide_env_values),
"hide_possible_values" => yaml_to_bool!(a, v, hide_possible_values),
"overrides_with" => yaml_to_str!(a, v, overrides_with),
"overrides_with_all" => yaml_vec_or_str!(a, v, overrides_with),
"possible_value" => yaml_to_str!(a, v, possible_value),
"possible_values" => yaml_vec_or_str!(a, v, possible_value),
"case_insensitive" => yaml_to_bool!(a, v, case_insensitive),
"required_unless_present_any" => yaml_vec!(a, v, required_unless_present_any),
"required_unless_present_all" => yaml_vec!(a, v, required_unless_present_all),
"visible_alias" => yaml_to_str!(a, v, visible_alias),
"visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
"visible_short_alias" => yaml_to_char!(a, v, visible_short_alias),
"visible_short_aliases" => yaml_to_chars!(a, v, visible_short_aliases),
#[cfg(feature = "regex")]
"validator_regex" => {
if let Some(vec) = v.as_vec() {
debug_assert_eq!(2, vec.len());
let regex = yaml_str!(vec[0]);
match Regex::new(regex) {
Err(e) => panic!(
"Failed to convert \"{}\" into regular expression: {}",
regex, e
),
Ok(regex) => a.validator_regex(regex, yaml_str!(vec[1])),
}
} else {
panic!("Failed to convert YAML value to vector")
}
}
"setting" | "settings" => {
yaml_to_setting!(
a,
v,
setting,
ArgSettings,
"ArgSetting",
format!("arg '{}'", name_str)
)
}
s => {
if !has_metadata {
panic!(
"Unknown setting '{}' in YAML file for arg '{}'",
s, name_str
)
}
continue;
}
}
}
a
pub(crate) fn get_display_order(&self) -> usize {
self.disp_ord.unwrap_or(999)
}
}
@ -5052,12 +5053,6 @@ impl<'help> From<&'_ Arg<'help>> for Arg<'help> {
}
}
impl<'help> From<&'help str> for Arg<'help> {
fn from(s: &'help str) -> Self {
UsageParser::from_usage(s).parse()
}
}
impl<'help> PartialEq for Arg<'help> {
fn eq(&self, other: &Arg<'help>) -> bool {
self.name == other.name

View file

@ -130,7 +130,7 @@ pub enum ArgSettings {
HideDefaultValue,
/// Possible values become case insensitive
IgnoreCase,
/// Deprecated, see [`ArgSettings::IgnoreCase`]
/// Deprecated, replaced with [`ArgSettings::IgnoreCase`]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgSettings::IgnoreCase`")]
CaseInsensitive,
/// Hides environment variable arguments from the help message

View file

@ -1,28 +1,4 @@
use super::{settings::ArgSettings, Arg};
#[test]
fn short_flag_misspell() {
let a = Arg::from("-f1, --flag 'some flag'");
assert_eq!(a.name, "flag");
assert_eq!(a.short.unwrap(), 'f');
assert_eq!(a.long.unwrap(), "flag");
assert_eq!(a.help.unwrap(), "some flag");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
}
#[test]
fn short_flag_name_missing() {
let a = Arg::from("-f 'some flag'");
assert_eq!(a.name, "f");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some flag");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
assert!(a.num_vals.is_none());
}
use crate::Arg;
// This test will *fail to compile* if Arg is not Send + Sync
#[test]

View file

@ -36,12 +36,12 @@ use yaml_rust::Yaml;
/// the arguments from the specified group is present at runtime.
///
/// ```rust
/// # use clap::{App, ArgGroup, ErrorKind};
/// # use clap::{App, arg, ArgGroup, ErrorKind};
/// let result = App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'")
/// .arg("--major 'auto increase major'")
/// .arg("--minor 'auto increase minor'")
/// .arg("--patch 'auto increase patch'")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor", "patch"])
/// .required(true))
@ -54,12 +54,12 @@ use yaml_rust::Yaml;
/// This next example shows a passing parse of the same scenario
///
/// ```rust
/// # use clap::{App, ArgGroup};
/// # use clap::{App, arg, ArgGroup};
/// let result = App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'")
/// .arg("--major 'auto increase major'")
/// .arg("--minor 'auto increase minor'")
/// .arg("--patch 'auto increase patch'")
/// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg(arg!(--major "auto increase major"))
/// .arg(arg!(--minor "auto increase minor"))
/// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor","patch"])
/// .required(true))
@ -108,15 +108,18 @@ impl<'help> ArgGroup<'help> {
ArgGroup::default().name(n)
}
/// Deprecated, see [`ArgGroup::new`]
/// Deprecated, replaced with [`ArgGroup::new`]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgGroup::new`")]
pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
Self::new(n)
}
/// Deprecated, see [`ArgGroup::from`]
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgGroup::from`")]
#[deprecated(
since = "3.0.0",
note = "Maybe clap::Parser would fit your use case? (Issue #9)"
)]
pub fn from_yaml(yaml: &'help Yaml) -> Self {
Self::from(yaml)
}
@ -436,17 +439,10 @@ impl<'help> From<&'_ ArgGroup<'help>> for ArgGroup<'help> {
}
}
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
impl<'help> From<&'help Yaml> for ArgGroup<'help> {
/// Creates a new instance of `ArgGroup` from a .yaml (YAML) file.
///
/// # Examples
///
/// ```ignore
/// # use clap::{ArgGroup, load_yaml};
/// let yaml = load_yaml!("group.yaml");
/// let ag = ArgGroup::from(yaml);
/// ```
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
fn from(y: &'help Yaml) -> Self {
let b = y.as_hash().expect("ArgGroup::from::<Yaml> expects a table");
// We WANT this to panic on error...so expect() is good.

View file

@ -44,10 +44,7 @@ impl<'help> UsageParser<'help> {
pub(crate) fn parse(mut self) -> Arg<'help> {
debug!("UsageParser::parse");
let mut arg = Arg {
disp_ord: 999,
..Default::default()
};
let mut arg = Arg::default();
loop {
debug!("UsageParser::parse:iter: pos={}", self.pos);
self.stop_at(token);
@ -173,12 +170,11 @@ impl<'help> UsageParser<'help> {
self.pos += 1;
if dot_counter == 3 {
debug!("UsageParser::multiple: setting multiple");
arg.settings.set(ArgSettings::MultipleOccurrences);
if arg.is_set(ArgSettings::TakesValue) {
// This is after `--name=value`, so requesting multiple value
arg.settings.set(ArgSettings::MultipleValues);
} else {
// This is after `[name]` (or a flag), so requesting multiple occurrences
arg.settings.set(ArgSettings::MultipleOccurrences);
arg.settings.set(ArgSettings::UseValueDelimiter);
arg.val_delim.get_or_insert(',');
}
self.prev = UsageToken::Multiple;
self.pos += 1;
@ -245,12 +241,14 @@ fn default_value_end(b: u8) -> bool {
#[cfg(test)]
mod test {
#![allow(deprecated)]
use crate::build::{Arg, ArgSettings};
#[allow(clippy::cognitive_complexity)]
#[test]
fn create_flag_usage() {
let a = Arg::from("[flag] -f 'some help info'");
let a = Arg::from_usage("[flag] -f 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none());
@ -258,7 +256,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("[flag] --flag 'some help info'");
let a = Arg::from_usage("[flag] --flag 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.long.unwrap(), "flag");
assert!(a.short.is_none());
@ -266,7 +264,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("--flag 'some help info'");
let a = Arg::from_usage("--flag 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.long.unwrap(), "flag");
assert!(a.short.is_none());
@ -274,7 +272,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("[flag] -f --flag 'some help info'");
let a = Arg::from_usage("[flag] -f --flag 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.short.unwrap(), 'f');
assert_eq!(a.long.unwrap(), "flag");
@ -282,7 +280,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("[flag] -f... 'some help info'");
let a = Arg::from_usage("[flag] -f... 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none());
@ -290,7 +288,7 @@ mod test {
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("[flag] -f --flag... 'some help info'");
let a = Arg::from_usage("[flag] -f --flag... 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.long.unwrap(), "flag");
assert_eq!(a.short.unwrap(), 'f');
@ -298,7 +296,7 @@ mod test {
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("-f --flag... 'some help info'");
let a = Arg::from_usage("-f --flag... 'some help info'");
assert_eq!(a.name, "flag");
assert_eq!(a.long.unwrap(), "flag");
assert_eq!(a.short.unwrap(), 'f');
@ -306,29 +304,29 @@ mod test {
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("--flags");
let a = Arg::from_usage("--flags");
assert_eq!(a.name, "flags");
assert_eq!(a.long.unwrap(), "flags");
assert!(a.val_names.is_empty());
let a = Arg::from("--flags...");
let a = Arg::from_usage("--flags...");
assert_eq!(a.name, "flags");
assert_eq!(a.long.unwrap(), "flags");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("[flags] -f");
let a = Arg::from_usage("[flags] -f");
assert_eq!(a.name, "flags");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.val_names.is_empty());
let a = Arg::from("[flags] -f...");
let a = Arg::from_usage("[flags] -f...");
assert_eq!(a.name, "flags");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("-f 'some help info'");
let a = Arg::from_usage("-f 'some help info'");
assert_eq!(a.name, "f");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none());
@ -336,12 +334,12 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty());
let a = Arg::from("-f");
let a = Arg::from_usage("-f");
assert_eq!(a.name, "f");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.val_names.is_empty());
let a = Arg::from("-f...");
let a = Arg::from_usage("-f...");
assert_eq!(a.name, "f");
assert_eq!(a.short.unwrap(), 'f');
assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -351,7 +349,7 @@ mod test {
#[test]
fn create_option_usage0() {
// Short only
let a = Arg::from("[option] -o [opt] 'some help info'");
let a = Arg::from_usage("[option] -o [opt] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
@ -365,7 +363,7 @@ mod test {
#[test]
fn create_option_usage1() {
let a = Arg::from("-o [opt] 'some help info'");
let a = Arg::from_usage("-o [opt] 'some help info'");
assert_eq!(a.name, "o");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
@ -379,7 +377,7 @@ mod test {
#[test]
fn create_option_usage2() {
let a = Arg::from("<option> -o <opt> 'some help info'");
let a = Arg::from_usage("<option> -o <opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
@ -393,7 +391,7 @@ mod test {
#[test]
fn create_option_usage3() {
let a = Arg::from("-o <opt> 'some help info'");
let a = Arg::from_usage("-o <opt> 'some help info'");
assert_eq!(a.name, "o");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
@ -407,12 +405,12 @@ mod test {
#[test]
fn create_option_usage4() {
let a = Arg::from("[option] -o [opt]... 'some help info'");
let a = Arg::from_usage("[option] -o [opt]... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -421,7 +419,7 @@ mod test {
#[test]
fn create_option_usage5() {
let a = Arg::from("[option]... -o [opt] 'some help info'");
let a = Arg::from_usage("[option]... -o [opt] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
@ -435,12 +433,12 @@ mod test {
#[test]
fn create_option_usage6() {
let a = Arg::from("-o [opt]... 'some help info'");
let a = Arg::from_usage("-o [opt]... 'some help info'");
assert_eq!(a.name, "o");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -449,12 +447,12 @@ mod test {
#[test]
fn create_option_usage7() {
let a = Arg::from("<option> -o <opt>... 'some help info'");
let a = Arg::from_usage("<option> -o <opt>... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -463,7 +461,7 @@ mod test {
#[test]
fn create_option_usage8() {
let a = Arg::from("<option>... -o <opt> 'some help info'");
let a = Arg::from_usage("<option>... -o <opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
@ -477,35 +475,21 @@ mod test {
#[test]
fn create_option_usage9() {
let a = Arg::from("-o <opt>... 'some help info'");
let a = Arg::from_usage("-o <opt>... 'some help info'");
assert_eq!(a.name, "o");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
assert_eq!(a.val_names.iter().collect::<Vec<_>>(), [&"opt"]);
}
#[test]
fn create_option_usage10() {
let a = Arg::from("[option]... -o [opt]... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
assert_eq!(a.val_names.iter().collect::<Vec<_>>(), [&"opt"]);
}
#[test]
fn create_option_usage_long1() {
let a = Arg::from("[option] --opt [opt] 'some help info'");
let a = Arg::from_usage("[option] --opt [opt] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -519,7 +503,7 @@ mod test {
#[test]
fn create_option_usage_long2() {
let a = Arg::from("--opt [option] 'some help info'");
let a = Arg::from_usage("--opt [option] 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -533,7 +517,7 @@ mod test {
#[test]
fn create_option_usage_long3() {
let a = Arg::from("<option> --opt <opt> 'some help info'");
let a = Arg::from_usage("<option> --opt <opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -547,7 +531,7 @@ mod test {
#[test]
fn create_option_usage_long4() {
let a = Arg::from("--opt <option> 'some help info'");
let a = Arg::from_usage("--opt <option> 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -561,12 +545,12 @@ mod test {
#[test]
fn create_option_usage_long5() {
let a = Arg::from("[option] --opt [opt]... 'some help info'");
let a = Arg::from_usage("[option] --opt [opt]... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -575,7 +559,7 @@ mod test {
#[test]
fn create_option_usage_long6() {
let a = Arg::from("[option]... --opt [opt] 'some help info'");
let a = Arg::from_usage("[option]... --opt [opt] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -589,12 +573,12 @@ mod test {
#[test]
fn create_option_usage_long7() {
let a = Arg::from("--opt [option]... 'some help info'");
let a = Arg::from_usage("--opt [option]... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -603,12 +587,12 @@ mod test {
#[test]
fn create_option_usage_long8() {
let a = Arg::from("<option> --opt <opt>... 'some help info'");
let a = Arg::from_usage("<option> --opt <opt>... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -617,7 +601,7 @@ mod test {
#[test]
fn create_option_usage_long9() {
let a = Arg::from("<option>... --opt <opt> 'some help info'");
let a = Arg::from_usage("<option>... --opt <opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -631,12 +615,12 @@ mod test {
#[test]
fn create_option_usage_long10() {
let a = Arg::from("--opt <option>... 'some help info'");
let a = Arg::from_usage("--opt <option>... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -645,7 +629,7 @@ mod test {
#[test]
fn create_option_usage_long_equals1() {
let a = Arg::from("[option] --opt=[opt] 'some help info'");
let a = Arg::from_usage("[option] --opt=[opt] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -659,7 +643,7 @@ mod test {
#[test]
fn create_option_usage_long_equals2() {
let a = Arg::from("--opt=[option] 'some help info'");
let a = Arg::from_usage("--opt=[option] 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -673,7 +657,7 @@ mod test {
#[test]
fn create_option_usage_long_equals3() {
let a = Arg::from("<option> --opt=<opt> 'some help info'");
let a = Arg::from_usage("<option> --opt=<opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -687,7 +671,7 @@ mod test {
#[test]
fn create_option_usage_long_equals4() {
let a = Arg::from("--opt=<option> 'some help info'");
let a = Arg::from_usage("--opt=<option> 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -701,12 +685,12 @@ mod test {
#[test]
fn create_option_usage_long_equals5() {
let a = Arg::from("[option] --opt=[opt]... 'some help info'");
let a = Arg::from_usage("[option] --opt=[opt]... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -715,7 +699,7 @@ mod test {
#[test]
fn create_option_usage_long_equals6() {
let a = Arg::from("[option]... --opt=[opt] 'some help info'");
let a = Arg::from_usage("[option]... --opt=[opt] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -729,12 +713,12 @@ mod test {
#[test]
fn create_option_usage_long_equals7() {
let a = Arg::from("--opt=[option]... 'some help info'");
let a = Arg::from_usage("--opt=[option]... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -743,12 +727,12 @@ mod test {
#[test]
fn create_option_usage_long_equals8() {
let a = Arg::from("<option> --opt=<opt>... 'some help info'");
let a = Arg::from_usage("<option> --opt=<opt>... 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -757,7 +741,7 @@ mod test {
#[test]
fn create_option_usage_long_equals9() {
let a = Arg::from("<option>... --opt=<opt> 'some help info'");
let a = Arg::from_usage("<option>... --opt=<opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
@ -771,12 +755,12 @@ mod test {
#[test]
fn create_option_usage_long_equals10() {
let a = Arg::from("--opt=<option>... 'some help info'");
let a = Arg::from_usage("--opt=<option>... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -785,7 +769,7 @@ mod test {
#[test]
fn create_option_usage_both1() {
let a = Arg::from("[option] -o --opt [option] 'some help info'");
let a = Arg::from_usage("[option] -o --opt [option] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -799,7 +783,7 @@ mod test {
#[test]
fn create_option_usage_both2() {
let a = Arg::from("-o --opt [option] 'some help info'");
let a = Arg::from_usage("-o --opt [option] 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -813,7 +797,7 @@ mod test {
#[test]
fn create_option_usage_both3() {
let a = Arg::from("<option> -o --opt <opt> 'some help info'");
let a = Arg::from_usage("<option> -o --opt <opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -827,7 +811,7 @@ mod test {
#[test]
fn create_option_usage_both4() {
let a = Arg::from("-o --opt <option> 'some help info'");
let a = Arg::from_usage("-o --opt <option> 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -841,7 +825,7 @@ mod test {
#[test]
fn create_option_usage_both5() {
let a = Arg::from("[option]... -o --opt [option] 'some help info'");
let a = Arg::from_usage("[option]... -o --opt [option] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -855,12 +839,12 @@ mod test {
#[test]
fn create_option_usage_both6() {
let a = Arg::from("-o --opt [option]... 'some help info'");
let a = Arg::from_usage("-o --opt [option]... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -869,7 +853,7 @@ mod test {
#[test]
fn create_option_usage_both7() {
let a = Arg::from("<option>... -o --opt <opt> 'some help info'");
let a = Arg::from_usage("<option>... -o --opt <opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -883,12 +867,12 @@ mod test {
#[test]
fn create_option_usage_both8() {
let a = Arg::from("-o --opt <option>... 'some help info'");
let a = Arg::from_usage("-o --opt <option>... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -897,7 +881,7 @@ mod test {
#[test]
fn create_option_usage_both_equals1() {
let a = Arg::from("[option] -o --opt=[option] 'some help info'");
let a = Arg::from_usage("[option] -o --opt=[option] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -911,7 +895,7 @@ mod test {
#[test]
fn create_option_usage_both_equals2() {
let a = Arg::from("-o --opt=[option] 'some help info'");
let a = Arg::from_usage("-o --opt=[option] 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -925,7 +909,7 @@ mod test {
#[test]
fn create_option_usage_both_equals3() {
let a = Arg::from("<option> -o --opt=<opt> 'some help info'");
let a = Arg::from_usage("<option> -o --opt=<opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -939,7 +923,7 @@ mod test {
#[test]
fn create_option_usage_both_equals4() {
let a = Arg::from("-o --opt=<option> 'some help info'");
let a = Arg::from_usage("-o --opt=<option> 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -953,7 +937,7 @@ mod test {
#[test]
fn create_option_usage_both_equals5() {
let a = Arg::from("[option]... -o --opt=[option] 'some help info'");
let a = Arg::from_usage("[option]... -o --opt=[option] 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -967,12 +951,12 @@ mod test {
#[test]
fn create_option_usage_both_equals6() {
let a = Arg::from("-o --opt=[option]... 'some help info'");
let a = Arg::from_usage("-o --opt=[option]... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required));
@ -981,7 +965,7 @@ mod test {
#[test]
fn create_option_usage_both_equals7() {
let a = Arg::from("<option>... -o --opt=<opt> 'some help info'");
let a = Arg::from_usage("<option>... -o --opt=<opt> 'some help info'");
assert_eq!(a.name, "option");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
@ -995,12 +979,12 @@ mod test {
#[test]
fn create_option_usage_both_equals8() {
let a = Arg::from("-o --opt=<option>... 'some help info'");
let a = Arg::from_usage("-o --opt=<option>... 'some help info'");
assert_eq!(a.name, "opt");
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -1009,7 +993,7 @@ mod test {
#[test]
fn create_option_with_vals1() {
let a = Arg::from("-o <file> <mode> 'some help info'");
let a = Arg::from_usage("-o <file> <mode> 'some help info'");
assert_eq!(a.name, "o");
assert!(a.long.is_none());
assert_eq!(a.short.unwrap(), 'o');
@ -1023,12 +1007,12 @@ mod test {
#[test]
fn create_option_with_vals2() {
let a = Arg::from("-o <file> <mode>... 'some help info'");
let a = Arg::from_usage("-o <file> <mode>... 'some help info'");
assert_eq!(a.name, "o");
assert!(a.long.is_none());
assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -1037,12 +1021,12 @@ mod test {
#[test]
fn create_option_with_vals3() {
let a = Arg::from("--opt <file> <mode>... 'some help info'");
let a = Arg::from_usage("--opt <file> <mode>... 'some help info'");
assert_eq!(a.name, "opt");
assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.is_set(ArgSettings::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required));
@ -1051,7 +1035,7 @@ mod test {
#[test]
fn create_option_with_vals4() {
let a = Arg::from("[myopt] --opt <file> <mode> 'some help info'");
let a = Arg::from_usage("[myopt] --opt <file> <mode> 'some help info'");
assert_eq!(a.name, "myopt");
assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt");
@ -1065,7 +1049,7 @@ mod test {
#[test]
fn create_option_with_vals5() {
let a = Arg::from("--opt <file> <mode> 'some help info'");
let a = Arg::from_usage("--opt <file> <mode> 'some help info'");
assert_eq!(a.name, "opt");
assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt");
@ -1078,7 +1062,7 @@ mod test {
#[test]
fn create_positional_usage() {
let a = Arg::from("[pos] 'some help info'");
let a = Arg::from_usage("[pos] 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
@ -1089,7 +1073,7 @@ mod test {
#[test]
fn create_positional_usage0() {
let a = Arg::from("<pos> 'some help info'");
let a = Arg::from_usage("<pos> 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
@ -1100,7 +1084,7 @@ mod test {
#[test]
fn pos_mult_help() {
let a = Arg::from("[pos]... 'some help info'");
let a = Arg::from_usage("[pos]... 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1111,7 +1095,7 @@ mod test {
#[test]
fn pos_help_lit_single_quote() {
let a = Arg::from("[pos]... 'some help\' info'");
let a = Arg::from_usage("[pos]... 'some help\' info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some help' info");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1122,7 +1106,7 @@ mod test {
#[test]
fn pos_help_double_lit_single_quote() {
let a = Arg::from("[pos]... 'some \'help\' info'");
let a = Arg::from_usage("[pos]... 'some \'help\' info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some 'help' info");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1133,7 +1117,7 @@ mod test {
#[test]
fn pos_help_newline() {
let a = Arg::from(
let a = Arg::from_usage(
"[pos]... 'some help\n\
info'",
);
@ -1147,7 +1131,7 @@ mod test {
#[test]
fn pos_help_newline_lit_sq() {
let a = Arg::from(
let a = Arg::from_usage(
"[pos]... 'some help\' stuff\n\
info'",
);
@ -1161,7 +1145,7 @@ mod test {
#[test]
fn pos_req_mult_help() {
let a = Arg::from("<pos>... 'some help info'");
let a = Arg::from_usage("<pos>... 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1172,7 +1156,7 @@ mod test {
#[test]
fn pos_req() {
let a = Arg::from("<pos>");
let a = Arg::from_usage("<pos>");
assert_eq!(a.name, "pos");
assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(!a.is_set(ArgSettings::MultipleValues));
@ -1182,7 +1166,7 @@ mod test {
#[test]
fn pos_mult() {
let a = Arg::from("[pos]...");
let a = Arg::from_usage("[pos]...");
assert_eq!(a.name, "pos");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(!a.is_set(ArgSettings::MultipleValues));
@ -1192,7 +1176,7 @@ mod test {
#[test]
fn pos_req_mult_def_help() {
let a = Arg::from("<pos>... @a 'some help info'");
let a = Arg::from_usage("<pos>... @a 'some help info'");
assert_eq!(a.name, "pos");
assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1204,7 +1188,7 @@ mod test {
#[test]
fn create_option_with_vals1_def() {
let a = Arg::from("-o <file> <mode> @a 'some help info'");
let a = Arg::from_usage("-o <file> <mode> @a 'some help info'");
assert_eq!(a.name, "o");
assert!(a.long.is_none());
assert_eq!(a.short.unwrap(), 'o');
@ -1219,7 +1203,7 @@ mod test {
#[test]
fn create_option_with_vals4_def() {
let a = Arg::from("[myopt] --opt <file> <mode> @a 'some help info'");
let a = Arg::from_usage("[myopt] --opt <file> <mode> @a 'some help info'");
assert_eq!(a.name, "myopt");
assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt");
@ -1234,27 +1218,59 @@ mod test {
#[test]
fn nonascii() {
let a = Arg::from("<ASCII> 'üñíčöĐ€'");
let a = Arg::from_usage("<ASCII> 'üñíčöĐ€'");
assert_eq!(a.name, "ASCII");
assert_eq!(a.help, Some("üñíčöĐ€"));
let a = Arg::from("<üñíčöĐ€> 'ASCII'");
let a = Arg::from_usage("<üñíčöĐ€> 'ASCII'");
assert_eq!(a.name, "üñíčöĐ€");
assert_eq!(a.help, Some("ASCII"));
let a = Arg::from("<üñíčöĐ€> 'üñíčöĐ€'");
let a = Arg::from_usage("<üñíčöĐ€> 'üñíčöĐ€'");
assert_eq!(a.name, "üñíčöĐ€");
assert_eq!(a.help, Some("üñíčöĐ€"));
let a = Arg::from("-ø 'ø'");
let a = Arg::from_usage("-ø 'ø'");
assert_eq!(a.name, "ø");
assert_eq!(a.short, Some('ø'));
assert_eq!(a.help, Some("ø"));
let a = Arg::from("--üñíčöĐ€ 'Nōṫ ASCII'");
let a = Arg::from_usage("--üñíčöĐ€ 'Nōṫ ASCII'");
assert_eq!(a.name, "üñíčöĐ€");
assert_eq!(a.long, Some("üñíčöĐ€"));
assert_eq!(a.help, Some("Nōṫ ASCII"));
let a = Arg::from("[ñämê] --ôpt=[üñíčöĐ€] 'hælp'");
let a = Arg::from_usage("[ñämê] --ôpt=[üñíčöĐ€] 'hælp'");
assert_eq!(a.name, "ñämê");
assert_eq!(a.long, Some("ôpt"));
assert_eq!(a.val_names.iter().collect::<Vec<_>>(), [&"üñíčöĐ€"]);
assert_eq!(a.help, Some("hælp"));
}
#[test]
fn value_names_building_num_vals_from_usage() {
use crate::App;
let m = App::new("test")
.arg(Arg::from_usage("--pos <who> <what> <why>"))
.try_get_matches_from(vec!["myprog", "--pos", "val1", "val2", "val3"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
assert_eq!(
m.values_of("pos").unwrap().collect::<Vec<_>>(),
["val1", "val2", "val3"]
);
}
#[test]
fn issue_665() {
use crate::{App, ErrorKind};
// Verify fix for "arg_from_usage(): required values not being enforced when followed by another option"
let res = App::new("tester")
.arg(Arg::from_usage("-v, --reroll-count=[N] 'Mark the patch series as PATCH vN'"))
.arg(
Arg::from_usage("--subject-prefix [Subject-Prefix] 'Use [Subject-Prefix] instead of the standard [PATCH] prefix'")
.setting(ArgSettings::ForbidEmptyValues)
)
.try_get_matches_from(vec!["test", "--subject-prefix", "-v", "2"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
}
}

View file

@ -37,6 +37,10 @@ pub use crate::derive::{ArgEnum, Args, FromArgMatches, IntoApp, Parser, Subcomma
#[cfg(feature = "yaml")]
#[doc(hidden)]
#[deprecated(
since = "3.0.0",
note = "Deprecated in Issue #9, maybe clap::Parser would fit your use case?"
)]
pub use yaml_rust::YamlLoader;
#[cfg(feature = "derive")]
@ -66,21 +70,27 @@ const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a
report at https://github.com/clap-rs/clap/issues";
const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point";
/// Deprecated, see [`App`]
/// Deprecated, replaced with [`App`]
#[deprecated(since = "3.0.0", note = "Replaced with `App`")]
#[derive(Debug, Copy, Clone)]
pub struct SubCommand {}
#[allow(deprecated)]
impl SubCommand {
/// Deprecated, see [`App::new`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::new`)")]
/// Deprecated, replaced with [`App::new`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::new`")]
pub fn with_name<'help>(name: &str) -> App<'help> {
App::new(name)
}
/// Deprecated, see [`App::from`]
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[deprecated(since = "3.0.0", note = "Replaced with `App::from`)")]
#[deprecated(
since = "3.0.0",
note = "Deprecated in Issue #9, maybe clap::Parser would fit your use case?"
)]
pub fn from_yaml(yaml: &yaml_rust::Yaml) -> App {
App::from(yaml)
#![allow(deprecated)]
App::from_yaml(yaml)
}
}

View file

@ -1,29 +1,9 @@
/// A convenience macro for loading the YAML file at compile time (relative to the current file,
/// like modules work). That YAML object can then be passed to this function.
///
/// # Panics
///
/// The YAML file must be properly formatted or this function will panic!(). A good way to
/// ensure this doesn't happen is to run your program with the `--help` switch. If this passes
/// without error, you needn't worry because the YAML is properly formatted.
///
/// # Examples
///
/// The following example shows how to load a properly formatted YAML file to build an instance
/// of an `App` struct.
///
/// ```ignore
/// # #[macro_use]
/// # extern crate clap;
/// # use clap::App;
/// # fn main() {
/// let yaml = load_yaml!("app.yaml");
/// let app = App::from(yaml);
///
/// // continued logic goes here, such as `app.get_matches()` etc.
/// # }
/// ```
/// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
#[cfg(feature = "yaml")]
#[deprecated(
since = "3.0.0",
note = "Deprecated in Issue #9, maybe clap::Parser would fit your use case?"
)]
#[macro_export]
macro_rules! load_yaml {
($yaml:expr) => {
@ -175,96 +155,304 @@ macro_rules! app_from_crate {
};
}
/// Build `App`, `Arg` and `Group` with Usage-string like input
/// but without the associated parsing runtime cost.
#[doc(hidden)]
#[macro_export]
macro_rules! arg_impl {
( @string $val:ident ) => {
stringify!($val)
};
( @string $val:literal ) => {{
let ident_or_string_literal: &str = $val;
ident_or_string_literal
}};
( @string $val:tt ) => {
::std::compile_error!("Only identifiers or string literals supported");
};
( @string ) => {
None
};
( @char $val:ident ) => {{
let ident_or_char_literal = stringify!($val);
debug_assert_eq!(
ident_or_char_literal.len(),
1,
"Single-letter identifier expected, got {}",
ident_or_char_literal
);
ident_or_char_literal.chars().next().unwrap()
}};
( @char $val:literal ) => {{
let ident_or_char_literal: char = $val;
ident_or_char_literal
}};
( @char ) => {{
None
}};
(
@arg
($arg:expr)
--$long:ident
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
debug_assert!(!$arg.is_set($crate::ArgSettings::MultipleOccurrences), "Flags should precede `...`");
let mut arg = $arg;
let long = $crate::arg_impl! { @string $long };
if arg.get_name().is_empty() {
arg = arg.name(long);
}
arg.long(long)
})
$($tail)*
}
};
(
@arg
($arg:expr)
--$long:literal
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
debug_assert!(!$arg.is_set($crate::ArgSettings::MultipleOccurrences), "Flags should precede `...`");
let mut arg = $arg;
let long = $crate::arg_impl! { @string $long };
if arg.get_name().is_empty() {
arg = arg.name(long);
}
arg.long(long)
})
$($tail)*
}
};
(
@arg
($arg:expr)
-$short:ident
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
debug_assert!(!$arg.is_set($crate::ArgSettings::MultipleOccurrences), "Flags should precede `...`");
$arg.short($crate::arg_impl! { @char $short })
})
$($tail)*
}
};
(
@arg
($arg:expr)
-$short:literal
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
debug_assert!(!$arg.is_set($crate::ArgSettings::MultipleOccurrences), "Flags should precede `...`");
$arg.short($crate::arg_impl! { @char $short })
})
$($tail)*
}
};
(
@arg
($arg:expr)
<$value_name:ident>
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert!(!$arg.is_set($crate::ArgSettings::MultipleOccurrences), "Values should precede `...`");
debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
let mut arg = $arg;
arg = arg.required(true);
arg = arg.takes_value(true);
let value_name = $crate::arg_impl! { @string $value_name };
if arg.get_name().is_empty() {
arg = arg.name(value_name);
}
arg.value_name(value_name)
})
$($tail)*
}
};
(
@arg
($arg:expr)
[$value_name:ident]
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
debug_assert!(!$arg.is_set($crate::ArgSettings::MultipleOccurrences), "Values should precede `...`");
debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
let mut arg = $arg;
if arg.get_long().is_none() && arg.get_short().is_none() {
arg = arg.required(false);
} else {
arg = arg.min_values(0).max_values(1);
}
arg = arg.takes_value(true);
let value_name = $crate::arg_impl! { @string $value_name };
if arg.get_name().is_empty() {
arg = arg.name(value_name);
}
arg.value_name(value_name)
})
$($tail)*
}
};
(
@arg
($arg:expr)
...
$($tail:tt)*
) => {
$crate::arg_impl! {
@arg
({
$arg.multiple_occurrences(true)
})
$($tail)*
}
};
(
@arg
($arg:expr)
$help:literal
) => {
$arg.help($help)
};
(
@arg
($arg:expr)
) => {
$arg
};
}
/// Create an [`Arg`] from a usage string.
///
/// `clap_app!` also supports several shorthand syntaxes.
/// Allows creation of basic settings for the [`Arg`].
///
/// **NOTE**: Not all settings may be set using the usage string method. Some properties are
/// only available via the builder pattern.
///
/// # Syntax
///
/// Usage strings typically following the form:
///
/// ```notrust
/// [explicit name] [short] [long] [value names] [...] [help string]
/// ```
///
/// ### Explicit Name
///
/// The name may be either a bare-word or a string, followed by a `:`, like `name:` or
/// `"name":`.
///
/// *Note:* This is an optional field, if it's omitted the argument will use one of the additional
/// fields as the name using the following priority order:
///
/// 1. Explicit Name
/// 2. Long
/// 3. Value Name
///
/// See [`Arg::name`][crate::Arg::name].
///
/// ### Short
///
/// A short flag is a `-` followed by either a bare-character or quoted character, like `-f` or
/// `-'f'`.
///
/// See [`Arg::short`][crate::Arg::short].
///
/// ### Long
///
/// A long flag is a `--` followed by either a bare-word or a string, like `--foo` or
/// `--"foo"`.
///
/// See [`Arg::long`][crate::Arg::long].
///
/// ### Values (Value Notation)
///
/// This is set by placing bare-word between:
/// - `[]` like `[FOO]`
/// - Positional argument: optional
/// - Named argument: optional value
/// - `<>` like `<FOO>`: required
///
/// See [`Arg::value_name`][crate::Arg::value_name].
///
/// ### `...`
///
/// `...` (three consecutive dots/periods) specifies that this argument may occur multiple
/// times (not to be confused with multiple values per occurrence).
///
/// See [`Arg::multiple_occurrences`][crate::Arg::multiple_occurrences].
///
/// ### Help String
///
/// The help string is denoted between a pair of single quotes `''` and may contain any
/// characters.
///
/// # Examples
///
/// ```no_run
/// # #[macro_use]
/// # extern crate clap;
/// # fn main() {
/// let matches = clap_app!(myapp =>
/// (version: "1.0")
/// (author: "Kevin K. <kbknapp@gmail.com>")
/// (about: "Does awesome things")
/// (@arg CONFIG: -c --config +takes_value "Sets a custom config file")
/// (@arg INPUT: +required "Sets the input file to use")
/// (@arg debug: -d ... "Sets the level of debugging information")
/// (@group difficulty: +required !multiple
/// (@arg hard: -h --hard "Sets hard mode")
/// (@arg normal: -n --normal "Sets normal mode")
/// (@arg easy: -e --easy "Sets easy mode")
/// )
/// (@subcommand test =>
/// (about: "controls testing features")
/// (version: "1.3")
/// (author: "Someone E. <someone_else@other.com>")
/// (@arg verbose: -v --verbose "Print test information verbosely")
/// )
/// )
/// .get_matches();
/// # }
/// ```rust
/// # use clap::{App, Arg, arg};
/// App::new("prog")
/// .args(&[
/// arg!(--config <FILE> "a required file for the configuration and no short"),
/// arg!(-d --debug ... "turns on debugging information and allows multiples"),
/// arg!([input] "an optional input file to use")
/// ])
/// # ;
/// ```
///
/// # Shorthand Syntax for Args
///
/// * A single hyphen followed by a character (such as `-c`) sets the [`Arg::short`]
/// * A double hyphen followed by a character or word (such as `--config`) sets [`Arg::long`]
/// * Three dots (`...`) sets [`Arg::multiple_values(true)`]
/// * Three dots (`...`) sets [`Arg::multiple_occurrences(true)`]
/// * Angled brackets after either a short or long will set [`Arg::value_name`] and
/// `Arg::required(true)` such as `--config <FILE>` = `Arg::value_name("FILE")` and
/// `Arg::required(true)`
/// * Square brackets after either a short or long will set [`Arg::value_name`] and
/// `Arg::required(false)` such as `--config [FILE]` = `Arg::value_name("FILE")` and
/// `Arg::required(false)`
/// * There are short hand syntaxes for Arg methods that accept booleans
/// * A plus sign will set that method to `true` such as `+required` = `Arg::required(true)`
/// * An exclamation will set that method to `false` such as `!required` = `Arg::required(false)`
/// * A `#{min, max}` will set [`Arg::min_values(min)`] and [`Arg::max_values(max)`]
/// * An asterisk (`*`) will set `Arg::required(true)`
/// * Curly brackets around a `fn` will set [`Arg::validator`] as in `{fn}` = `Arg::validator(fn)`
/// * An Arg method that accepts a string followed by square brackets will set that method such as
/// `conflicts_with[FOO]` will set `Arg::conflicts_with("FOO")` (note the lack of quotes around
/// `FOO` in the macro)
/// * An Arg method that takes a string and can be set multiple times (such as
/// [`Arg::conflicts_with`]) followed by square brackets and a list of values separated by spaces
/// will set that method such as `conflicts_with[FOO BAR BAZ]` will set
/// `Arg::conflicts_with("FOO")`, `Arg::conflicts_with("BAR")`, and `Arg::conflicts_with("BAZ")`
/// (note the lack of quotes around the values in the macro)
///
/// # Shorthand Syntax for Groups
/// * Some shorthand syntaxes for `Arg` are also available for `ArgGroup`:
/// * For methods accepting a boolean: `+required` and `!multiple`, etc.
/// * For methods accepting strings: `conflicts_with[FOO]` and `conflicts_with[FOO BAR BAZ]`, etc.
/// * `*` for `ArgGroup::required`
/// * `...` for `ArgGroup::multiple`
///
/// # Alternative form for non-ident values
///
/// Certain places that normally accept an `ident` also optionally accept an alternative of `("expr enclosed by parens")`
/// * `(@arg something: --something)` could also be `(@arg ("something-else"): --("something-else"))`
/// * `(@subcommand something => ...)` could also be `(@subcommand ("something-else") => ...)`
///
/// Or it can be even simpler by using the literal directly
/// * `(@arg "something-else": --"something-else")`
/// * `(@subcommand "something-else" => ...)`
///
/// [`Arg::short`]: crate::Arg::short()
/// [`Arg::long`]: crate::Arg::long()
/// [`Arg::multiple_values(true)`]: crate::Arg::multiple_values()
/// [`Arg::multiple_occurrences(true)`]: crate::Arg::multiple_occurrences()
/// [`Arg::value_name`]: crate::Arg::value_name()
/// [`Arg::min_values(min)`]: crate::Arg::min_values()
/// [`Arg::max_values(max)`]: crate::Arg::max_values()
/// [`Arg::validator`]: crate::Arg::validator()
/// [`Arg::conflicts_with`]: crate::Arg::conflicts_with()
/// [`Arg`]: ./struct.Arg.html
#[macro_export]
macro_rules! arg {
( $name:ident: $($tail:tt)+ ) => {
$crate::arg_impl! {
@arg ($crate::Arg::new($crate::arg_impl! { @string $name })) $($tail)+
}
};
( $($tail:tt)+ ) => {{
let arg = $crate::arg_impl! {
@arg ($crate::Arg::default()) $($tail)+
};
debug_assert!(!arg.get_name().is_empty(), "Without a value or long flag, the `name:` prefix is required");
arg
}};
}
/// Deprecated, replaced with [`clap::Parser`][crate::Parser] and [`clap::arg!`][crate::arg] (Issue clap-rs/clap#2835)
#[deprecated(
since = "3.0.0",
note = "Replaced with `App` builder API (with `From::from` for parsing usage) or `Parser` derive API (Issue #2835)"
note = "Replaced with `clap::Parser` for a declarative API (Issue clap-rs/clap#2835)"
)]
#[macro_export]
macro_rules! clap_app {
@ -627,7 +815,7 @@ macro_rules! debug {
($($arg:tt)*) => {};
}
/// Deprecated, see [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t]
/// Deprecated, replaced with [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t]
#[macro_export]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::value_of_t`")]
macro_rules! value_t {
@ -639,7 +827,7 @@ macro_rules! value_t {
};
}
/// Deprecated, see [`ArgMatches::value_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit]
/// Deprecated, replaced with [`ArgMatches::value_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit]
#[macro_export]
#[deprecated(
since = "3.0.0",
@ -654,7 +842,7 @@ macro_rules! value_t_or_exit {
};
}
/// Deprecated, see [`ArgMatches::values_of_t`][crate::ArgMatches::value_of_t]
/// Deprecated, replaced with [`ArgMatches::values_of_t`][crate::ArgMatches::value_of_t]
#[macro_export]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::values_of_t`")]
macro_rules! values_t {
@ -666,7 +854,7 @@ macro_rules! values_t {
};
}
/// Deprecated, see [`ArgMatches::values_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit]
/// Deprecated, replaced with [`ArgMatches::values_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit]
#[macro_export]
#[deprecated(
since = "3.0.0",

View file

@ -210,7 +210,9 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
longest = longest.max(display_width(arg.to_string().as_str()));
debug!("Help::write_args: New Longest...{}", longest);
}
let btm = ord_m.entry(arg.disp_ord).or_insert_with(BTreeMap::new);
let btm = ord_m
.entry(arg.get_display_order())
.or_insert_with(BTreeMap::new);
// Formatting key like this to ensure that:
// 1. Argument has long flags are printed just after short flags.
@ -844,7 +846,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
.filter(|subcommand| should_show_subcommand(subcommand))
{
let btm = ord_m
.entry(subcommand.disp_ord)
.entry(subcommand.get_display_order())
.or_insert_with(BTreeMap::new);
let mut sc_str = String::new();
sc_str.push_str(

View file

@ -47,9 +47,9 @@ pub enum ErrorKind {
/// # Examples
///
/// ```rust
/// # use clap::{App, Arg, ErrorKind};
/// # use clap::{App, arg, ErrorKind};
/// let result = App::new("prog")
/// .arg(Arg::from("--flag 'some flag'"))
/// .arg(arg!(--flag "some flag"))
/// .try_get_matches_from(vec!["prog", "--other"]);
/// assert!(result.is_err());
/// assert_eq!(result.unwrap_err().kind, ErrorKind::UnknownArgument);
@ -1106,7 +1106,7 @@ impl Error {
Self::new(c, ErrorKind::ArgumentNotFound, false).set_info(vec![arg])
}
/// Deprecated, see [`App::error`]
/// Deprecated, replaced with [`App::error`]
///
/// [`App::error`]: crate::App::error
#[deprecated(since = "3.0.0", note = "Replaced with `App::error`")]

View file

@ -178,12 +178,12 @@ impl ArgMatches {
///
#[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
///
/// let m = App::new("utf8")
/// .arg(Arg::from("<arg> 'some arg'")
/// .arg(arg!(<arg> "some arg")
/// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi {0xe9}!"
@ -221,12 +221,12 @@ impl ArgMatches {
///
#[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
///
/// let m = App::new("utf8")
/// .arg(Arg::from("<arg> 'some arg'")
/// .arg(arg!(<arg> "some arg")
/// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi {0xe9}!"
@ -306,12 +306,12 @@ impl ArgMatches {
///
#[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::OsStringExt;
///
/// let m = App::new("utf8")
/// .arg(Arg::from("<arg>... 'some arg'")
/// .arg(arg!(<arg> ... "some arg")
/// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi"
@ -343,12 +343,12 @@ impl ArgMatches {
///
#[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// use std::ffi::{OsStr,OsString};
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
///
/// let m = App::new("utf8")
/// .arg(Arg::from("<arg>... 'some arg'")
/// .arg(arg!(<arg> ... "some arg")
/// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi"
@ -392,10 +392,9 @@ impl ArgMatches {
/// # Examples
///
/// ```
/// # extern crate clap;
/// # use clap::App;
/// # use clap::{App, arg};
/// let matches = App::new("myapp")
/// .arg("[length] 'Set the length to use as a pos whole num, i.e. 20'")
/// .arg(arg!([length] "Set the length to use as a pos whole num i.e. 20"))
/// .get_matches_from(&["test", "12"]);
///
/// // Specify the type explicitly (or use turbofish)
@ -443,10 +442,9 @@ impl ArgMatches {
/// # Examples
///
/// ```
/// # extern crate clap;
/// # use clap::App;
/// # use clap::{App, arg};
/// let matches = App::new("myapp")
/// .arg("[length] 'Set the length to use as a pos whole num, i.e. 20'")
/// .arg(arg!([length] "Set the length to use as a pos whole num i.e. 20"))
/// .get_matches_from(&["test", "12"]);
///
/// // Specify the type explicitly (or use turbofish)
@ -481,10 +479,9 @@ impl ArgMatches {
/// # Examples
///
/// ```
/// # extern crate clap;
/// # use clap::App;
/// # use clap::{App, arg};
/// let matches = App::new("myapp")
/// .arg("[length]... 'A sequence of integers because integers are neat!'")
/// .arg(arg!([length] ... "A sequence of integers because integers are neat!"))
/// .get_matches_from(&["test", "12", "77", "40"]);
///
/// // Specify the type explicitly (or use turbofish)
@ -534,10 +531,9 @@ impl ArgMatches {
/// # Examples
///
/// ```
/// # extern crate clap;
/// # use clap::App;
/// # use clap::{App, arg};
/// let matches = App::new("myapp")
/// .arg("[length]... 'A sequence of integers because integers are neat!'")
/// .arg(arg!([length] ... "A sequence of integers because integers are neat!"))
/// .get_matches_from(&["test", "12", "77", "40"]);
///
/// // Specify the type explicitly (or use turbofish)
@ -1103,12 +1099,12 @@ impl<'a> Default for GroupedValues<'a> {
///
#[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// # use clap::{App, arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
///
/// let m = App::new("utf8")
/// .arg(Arg::from("<arg> 'some arg'")
/// .arg(arg!(<arg> "some arg")
/// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi {0xe9}!"

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, AppSettings, Arg, ErrorKind};
use clap::{arg, App, AppSettings, Arg, ErrorKind};
static ALLOW_EXT_SC: &str = "clap-test v1.4.8
@ -430,8 +430,10 @@ fn skip_possible_values() {
.version("1.3")
.setting(AppSettings::HidePossibleValuesInHelp)
.args(&[
Arg::from("-o, --opt [opt] 'some option'").possible_values(["one", "two"]),
Arg::from("[arg1] 'some pos arg'").possible_values(["three", "four"]),
arg!(-o --opt <opt> "some option")
.required(false)
.possible_values(["one", "two"]),
arg!([arg1] "some pos arg").possible_values(["three", "four"]),
]);
assert!(utils::compare_output(
@ -447,8 +449,8 @@ fn stop_delim_values_only_pos_follows() {
let r = App::new("onlypos")
.setting(AppSettings::DontDelimitTrailingValues)
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg]... 'some arg'"),
arg!(f: -f <flag> "some opt").required(false),
arg!([arg] ... "some arg"),
])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok());
@ -466,7 +468,7 @@ fn dont_delim_values_trailingvararg() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.setting(AppSettings::DontDelimitTrailingValues)
.arg(Arg::from("[opt]... 'some pos'"))
.arg(arg!([opt] ... "some pos"))
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
assert!(m.is_present("opt"));
assert_eq!(
@ -478,10 +480,7 @@ fn dont_delim_values_trailingvararg() {
#[test]
fn delim_values_only_pos_follows() {
let r = App::new("onlypos")
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg]... 'some arg'"),
])
.args(&[arg!(f: -f [flag] "some opt"), arg!([arg] ... "some arg")])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -497,7 +496,7 @@ fn delim_values_only_pos_follows() {
fn delim_values_trailingvararg() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.arg(Arg::from("[opt]... 'some pos'"))
.arg(arg!([opt] ... "some pos"))
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
assert!(m.is_present("opt"));
assert_eq!(
@ -510,8 +509,8 @@ fn delim_values_trailingvararg() {
fn delim_values_only_pos_follows_with_delim() {
let r = App::new("onlypos")
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg]... 'some arg'").use_delimiter(true),
arg!(f: -f [flag] "some opt"),
arg!([arg] ... "some arg").use_delimiter(true),
])
.try_get_matches_from(vec!["", "--", "-f", "-g,x"]);
assert!(r.is_ok());
@ -528,7 +527,7 @@ fn delim_values_only_pos_follows_with_delim() {
fn delim_values_trailingvararg_with_delim() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.arg(Arg::from("[opt]... 'some pos'").use_delimiter(true))
.arg(arg!([opt] ... "some pos").use_delimiter(true))
.get_matches_from(vec!["", "test", "--foo", "-Wl,-bar"]);
assert!(m.is_present("opt"));
assert_eq!(
@ -608,7 +607,7 @@ fn leading_double_hyphen_trailingvararg() {
let m = App::new("positional")
.setting(AppSettings::TrailingVarArg)
.setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("[opt]... 'some pos'"))
.arg(arg!([opt] ... "some pos"))
.get_matches_from(vec!["", "--foo", "-Wl", "bar"]);
assert!(m.is_present("opt"));
assert_eq!(
@ -670,8 +669,8 @@ fn args_negate_subcommands_one_level() {
let res = App::new("disablehelp")
.setting(AppSettings::ArgsNegateSubcommands)
.setting(AppSettings::SubcommandsNegateReqs)
.arg("<arg1> 'some arg'")
.arg("<arg2> 'some arg'")
.arg(arg!(<arg1> "some arg"))
.arg(arg!(<arg2> "some arg"))
.subcommand(App::new("sub1").subcommand(App::new("sub2").subcommand(App::new("sub3"))))
.try_get_matches_from(vec!["", "pickles", "sub1"]);
assert!(res.is_ok(), "error: {:?}", res.unwrap_err().kind);
@ -684,12 +683,12 @@ fn args_negate_subcommands_two_levels() {
let res = App::new("disablehelp")
.global_setting(AppSettings::ArgsNegateSubcommands)
.global_setting(AppSettings::SubcommandsNegateReqs)
.arg("<arg1> 'some arg'")
.arg("<arg2> 'some arg'")
.arg(arg!(<arg1> "some arg"))
.arg(arg!(<arg2> "some arg"))
.subcommand(
App::new("sub1")
.arg("<arg> 'some'")
.arg("<arg2> 'some'")
.arg(arg!(<arg> "some"))
.arg(arg!(<arg2> "some"))
.subcommand(App::new("sub2").subcommand(App::new("sub3"))),
)
.try_get_matches_from(vec!["", "sub1", "arg", "sub2"]);
@ -704,7 +703,7 @@ fn args_negate_subcommands_two_levels() {
#[test]
fn propagate_vals_down() {
let m = App::new("myprog")
.arg(Arg::from("[cmd] 'command to run'").global(true))
.arg(arg!([cmd] "command to run").global(true))
.subcommand(App::new("foo"))
.try_get_matches_from(vec!["myprog", "set", "foo"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
@ -718,8 +717,8 @@ fn propagate_vals_down() {
fn allow_missing_positional() {
let m = App::new("test")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[src] 'some file'").default_value("src"))
.arg("<dest> 'some file'")
.arg(arg!([src] "some file").default_value("src"))
.arg(arg!(<dest> "some file"))
.try_get_matches_from(vec!["test", "file"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
@ -731,8 +730,8 @@ fn allow_missing_positional() {
fn allow_missing_positional_no_default() {
let m = App::new("test")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[src] 'some file'"))
.arg("<dest> 'some file'")
.arg(arg!([src] "some file"))
.arg(arg!(<dest> "some file"))
.try_get_matches_from(vec!["test", "file"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
@ -744,8 +743,8 @@ fn allow_missing_positional_no_default() {
fn missing_positional_no_hyphen() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH] 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.arg(arg!([BENCH] "some bench"))
.arg(arg!([ARGS] ... "some args"))
.try_get_matches_from(vec!["bench", "foo", "arg1", "arg2", "arg3"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
@ -765,8 +764,8 @@ fn missing_positional_no_hyphen() {
fn missing_positional_hyphen() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH] 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.arg(arg!([BENCH] "some bench"))
.arg(arg!([ARGS] ... "some args"))
.try_get_matches_from(vec!["bench", "--", "arg1", "arg2", "arg3"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
@ -786,10 +785,10 @@ fn missing_positional_hyphen() {
fn missing_positional_hyphen_far_back() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH1] 'some bench'"))
.arg(Arg::from("[BENCH2] 'some bench'"))
.arg(Arg::from("[BENCH3] 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.arg(arg!([BENCH1] "some bench"))
.arg(arg!([BENCH2] "some bench"))
.arg(arg!([BENCH3] "some bench"))
.arg(arg!([ARGS] ... "some args"))
.try_get_matches_from(vec!["bench", "foo", "--", "arg1", "arg2", "arg3"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
@ -813,9 +812,9 @@ fn missing_positional_hyphen_far_back() {
fn missing_positional_hyphen_req_error() {
let r = App::new("bench")
.setting(AppSettings::AllowMissingPositional)
.arg(Arg::from("[BENCH1] 'some bench'"))
.arg(Arg::from("<BENCH2> 'some bench'"))
.arg(Arg::from("[ARGS]... 'some args'"))
.arg(arg!([BENCH1] "some bench"))
.arg(arg!(<BENCH2> "some bench"))
.arg(arg!([ARGS] ... "some args"))
.try_get_matches_from(vec!["bench", "foo", "--", "arg1", "arg2", "arg3"]);
assert!(r.is_err());
assert_eq!(r.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
@ -825,7 +824,7 @@ fn missing_positional_hyphen_req_error() {
fn issue_1066_allow_leading_hyphen_and_unknown_args() {
let res = App::new("prog")
.global_setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("--some-argument"))
.arg(arg!(--"some-argument"))
.try_get_matches_from(vec!["prog", "hello"]);
assert!(res.is_err());
@ -836,7 +835,7 @@ fn issue_1066_allow_leading_hyphen_and_unknown_args() {
fn issue_1066_allow_leading_hyphen_and_unknown_args_no_vals() {
let res = App::new("prog")
.global_setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("--some-argument"))
.arg(arg!(--"some-argument"))
.try_get_matches_from(vec!["prog", "--hello"]);
assert!(res.is_err());
@ -847,7 +846,7 @@ fn issue_1066_allow_leading_hyphen_and_unknown_args_no_vals() {
fn issue_1066_allow_leading_hyphen_and_unknown_args_option() {
let res = App::new("prog")
.global_setting(AppSettings::AllowLeadingHyphen)
.arg(Arg::from("--some-argument=[val]"))
.arg(arg!(--"some-argument" <val>))
.try_get_matches_from(vec!["prog", "-hello"]);
assert!(res.is_err());
@ -922,7 +921,7 @@ fn aaos_flags() {
// flags
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--flag 'some flag'"))
.arg(arg!(--flag "some flag"))
.try_get_matches_from(vec!["", "--flag", "--flag"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -935,7 +934,7 @@ fn aaos_flags_mult() {
// flags with multiple
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--flag... 'some flag'"))
.arg(arg!(--flag ... "some flag"))
.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -948,7 +947,7 @@ fn aaos_opts() {
// opts
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'"))
.arg(arg!(--opt <val> "some option"))
.try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -962,8 +961,12 @@ fn aaos_opts_w_other_overrides() {
// opts with other overrides
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'"))
.arg(Arg::from("--other [val] 'some other option'").overrides_with("opt"))
.arg(arg!(--opt <val> "some option").required(false))
.arg(
arg!(--other <val> "some other option")
.required(false)
.overrides_with("opt"),
)
.try_get_matches_from(vec!["", "--opt=some", "--other=test", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -978,8 +981,12 @@ fn aaos_opts_w_other_overrides_rev() {
// opts with other overrides, rev
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'"))
.arg(Arg::from("--other [val] 'some other option'").overrides_with("opt"))
.arg(arg!(--opt <val> "some option").required(true))
.arg(
arg!(--other <val> "some other option")
.required(true)
.overrides_with("opt"),
)
.try_get_matches_from(vec!["", "--opt=some", "--opt=other", "--other=val"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -993,8 +1000,12 @@ fn aaos_opts_w_other_overrides_2() {
// opts with other overrides
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'").overrides_with("other"))
.arg(Arg::from("--other [val] 'some other option'"))
.arg(
arg!(--opt <val> "some option")
.required(false)
.overrides_with("other"),
)
.arg(arg!(--other <val> "some other option").required(false))
.try_get_matches_from(vec!["", "--opt=some", "--other=test", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -1009,8 +1020,12 @@ fn aaos_opts_w_other_overrides_rev_2() {
// opts with other overrides, rev
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'").overrides_with("other"))
.arg(Arg::from("--other [val] 'some other option'"))
.arg(
arg!(--opt <val> "some option")
.required(true)
.overrides_with("other"),
)
.arg(arg!(--other <val> "some other option").required(true))
.try_get_matches_from(vec!["", "--opt=some", "--opt=other", "--other=val"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -1025,7 +1040,7 @@ fn aaos_opts_mult() {
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(
Arg::from("[opt]... --opt [val]... 'some option'")
arg!(--opt <val> ... "some option")
.number_of_values(1)
.takes_value(true)
.use_delimiter(true)
@ -1047,7 +1062,7 @@ fn aaos_opts_mult_req_delims() {
// opts with multiple and require delims
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("[opt]... --opt [val]... 'some option'"))
.arg(arg!(--opt <val> ... "some option").multiple_values(true))
.try_get_matches_from(vec![
"",
"--opt",
@ -1073,7 +1088,7 @@ fn aaos_pos_mult() {
// opts with multiple
let res = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("[val]... 'some pos'"))
.arg(arg!([val] ... "some pos"))
.try_get_matches_from(vec!["", "some", "other", "value"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -1089,7 +1104,7 @@ fn aaos_pos_mult() {
fn aaos_option_use_delim_false() {
let m = App::new("posix")
.setting(AppSettings::AllArgsOverrideSelf)
.arg(Arg::from("--opt [val] 'some option'").use_delimiter(false))
.arg(arg!(--opt <val> "some option").use_delimiter(false))
.get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]);
assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 1);

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, Arg};
use clap::{arg, App, Arg};
static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2
@ -167,7 +167,7 @@ fn invisible_arg_aliases_help_output() {
.takes_value(true)
.aliases(&["invisible", "als1", "more"]),
)
.arg(Arg::from("-f, --flag").aliases(&["unseeable", "flg1", "anyway"])),
.arg(arg!(-f - -flag).aliases(&["unseeable", "flg1", "anyway"])),
);
assert!(utils::compare_output(
app,

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, Arg};
use clap::{arg, App, Arg};
static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2
@ -163,7 +163,7 @@ fn invisible_short_arg_aliases_help_output() {
.takes_value(true)
.short_aliases(&['a', 'b', 'c']),
)
.arg(Arg::from("-f, --flag").short_aliases(&['x', 'y', 'z'])),
.arg(arg!(-f - -flag).short_aliases(&['x', 'y', 'z'])),
);
assert!(utils::compare_output(
app,

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, Arg, ArgGroup, ErrorKind};
use clap::{arg, App, Arg, ArgGroup, ErrorKind};
static CONFLICT_ERR: &str = "error: The argument '-F' cannot be used with '--flag'
@ -29,8 +29,8 @@ For more information try --help
#[test]
fn flag_conflict() {
let result = App::new("flag_conflict")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("other"))
.arg(Arg::from("-o, --other 'some flag'"))
.arg(arg!(-f --flag "some flag").conflicts_with("other"))
.arg(arg!(-o --other "some flag"))
.try_get_matches_from(vec!["myprog", "-f", "-o"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -40,8 +40,8 @@ fn flag_conflict() {
#[test]
fn flag_conflict_2() {
let result = App::new("flag_conflict")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("other"))
.arg(Arg::from("-o, --other 'some flag'"))
.arg(arg!(-f --flag "some flag").conflicts_with("other"))
.arg(arg!(-o --other "some flag"))
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -51,8 +51,8 @@ fn flag_conflict_2() {
#[test]
fn flag_conflict_with_all() {
let result = App::new("flag_conflict")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with_all(&["other"]))
.arg(Arg::from("-o, --other 'some flag'"))
.arg(arg!(-f --flag "some flag").conflicts_with_all(&["other"]))
.arg(arg!(-o --other "some flag"))
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -62,8 +62,8 @@ fn flag_conflict_with_all() {
#[test]
fn flag_conflict_with_everything() {
let result = App::new("flag_conflict")
.arg(Arg::from("-f, --flag 'some flag'").exclusive(true))
.arg(Arg::from("-o, --other 'some flag'"))
.arg(arg!(-f --flag "some flag").exclusive(true))
.arg(arg!(-o --other "some flag"))
.try_get_matches_from(vec!["myprog", "-o", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -73,10 +73,10 @@ fn flag_conflict_with_everything() {
#[test]
fn group_conflict() {
let result = App::new("group_conflict")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("gr"))
.arg(arg!(-f --flag "some flag").conflicts_with("gr"))
.group(ArgGroup::new("gr").required(true).arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.try_get_matches_from(vec!["myprog", "--other", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -86,10 +86,10 @@ fn group_conflict() {
#[test]
fn group_conflict_2() {
let result = App::new("group_conflict")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("gr"))
.arg(arg!(-f --flag "some flag").conflicts_with("gr"))
.group(ArgGroup::new("gr").required(true).arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.try_get_matches_from(vec!["myprog", "-f", "--some"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -238,8 +238,12 @@ fn conflicts_with_invalid_arg() {
#[test]
fn conflict_with_unused_default() {
let result = App::new("conflict")
.arg(Arg::from("-o, --opt=[opt] 'some opt'").default_value("default"))
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("opt"))
.arg(
arg!(-o --opt <opt> "some opt")
.required(false)
.default_value("default"),
)
.arg(arg!(-f --flag "some flag").conflicts_with("opt"))
.try_get_matches_from(vec!["myprog", "-f"]);
assert!(result.is_ok());
@ -253,11 +257,12 @@ fn conflict_with_unused_default() {
fn conflicts_with_alongside_default() {
let result = App::new("conflict")
.arg(
Arg::from("-o, --opt=[opt] 'some opt'")
arg!(-o --opt <opt> "some opt")
.default_value("default")
.required(false)
.conflicts_with("flag"),
)
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(arg!(-f --flag "some flag"))
.try_get_matches_from(vec!["myprog", "-f"]);
assert!(

View file

@ -1,4 +1,4 @@
use clap::{App, Arg, ArgMatches};
use clap::{arg, App, Arg, ArgMatches};
#[test]
fn opt_missing() {
@ -82,7 +82,7 @@ fn opt_default() {
// assert no change to usual argument handling when adding default_missing_value()
let r = App::new("app")
.arg(
Arg::from("-o [opt] 'some opt'")
arg!(o: -o [opt] "some opt")
.default_value("default")
.default_missing_value("default_missing"),
)
@ -98,7 +98,7 @@ fn opt_default_user_override() {
// assert no change to usual argument handling when adding default_missing_value()
let r = App::new("app")
.arg(
Arg::from("-o [opt] 'some opt'")
arg!(o: -o [opt] "some opt")
.default_value("default")
.default_missing_value("default_missing"),
)

View file

@ -1,10 +1,14 @@
mod utils;
use clap::{App, Arg, ErrorKind};
use clap::{arg, App, Arg, ErrorKind};
#[test]
fn opts() {
let r = App::new("df")
.arg(Arg::from("-o [opt] 'some opt'").default_value("default"))
.arg(
arg!(o: -o <opt> "some opt")
.required(false)
.default_value("default"),
)
.try_get_matches_from(vec![""]);
assert!(r.is_ok());
let m = r.unwrap();
@ -16,7 +20,8 @@ fn opts() {
fn opt_without_value_fail() {
let r = App::new("df")
.arg(
Arg::from("-o [opt] 'some opt'")
arg!(o: -o <opt> "some opt")
.required(false)
.default_value("default")
.forbid_empty_values(true),
)
@ -32,7 +37,11 @@ fn opt_without_value_fail() {
#[test]
fn opt_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'").default_value("default"))
.arg(
arg!(--opt <FILE> "some arg")
.required(false)
.default_value("default"),
)
.try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -43,7 +52,7 @@ fn opt_user_override() {
#[test]
fn positionals() {
let r = App::new("df")
.arg(Arg::from("[arg] 'some opt'").default_value("default"))
.arg(arg!([arg] "some opt").default_value("default"))
.try_get_matches_from(vec![""]);
assert!(r.is_ok());
let m = r.unwrap();
@ -54,7 +63,7 @@ fn positionals() {
#[test]
fn positional_user_override() {
let r = App::new("df")
.arg(Arg::from("[arg] 'some arg'").default_value("default"))
.arg(arg!([arg] "some arg").default_value("default"))
.try_get_matches_from(vec!["", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -70,7 +79,11 @@ fn osstr_opts() {
let expected = OsStr::new("default");
let r = App::new("df")
.arg(Arg::from("-o [opt] 'some opt'").default_value_os(expected))
.arg(
arg!(o: -o <opt> "some opt")
.required(false)
.default_value_os(expected),
)
.try_get_matches_from(vec![""]);
assert!(r.is_ok());
let m = r.unwrap();
@ -84,7 +97,11 @@ fn osstr_opt_user_override() {
let default = OsStr::new("default");
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'").default_value_os(default))
.arg(
arg!(--opt <FILE> "some arg")
.required(false)
.default_value_os(default),
)
.try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -98,7 +115,7 @@ fn osstr_positionals() {
let expected = OsStr::new("default");
let r = App::new("df")
.arg(Arg::from("[arg] 'some opt'").default_value_os(expected))
.arg(arg!([arg] "some opt").default_value_os(expected))
.try_get_matches_from(vec![""]);
assert!(r.is_ok());
let m = r.unwrap();
@ -112,7 +129,7 @@ fn osstr_positional_user_override() {
let default = OsStr::new("default");
let r = App::new("df")
.arg(Arg::from("[arg] 'some arg'").default_value_os(default))
.arg(arg!([arg] "some arg").default_value_os(default))
.try_get_matches_from(vec!["", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -125,8 +142,8 @@ fn osstr_positional_user_override() {
#[test]
fn default_if_arg_present_no_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("[arg] 'some arg'").default_value_if("opt", None, Some("default")))
.arg(arg!(--opt <FILE> "some arg").required(true))
.arg(arg!([arg] "some arg").default_value_if("opt", None, Some("default")))
.try_get_matches_from(vec!["", "--opt", "some"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -137,8 +154,8 @@ fn default_if_arg_present_no_default() {
#[test]
fn default_if_arg_present_no_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("[arg] 'some arg'").default_value_if("opt", None, Some("default")))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!([arg] "some arg").default_value_if("opt", None, Some("default")))
.try_get_matches_from(vec!["", "--opt", "some", "other"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -149,9 +166,9 @@ fn default_if_arg_present_no_default_user_override() {
#[test]
fn default_if_arg_present_no_arg_with_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", None, Some("default")),
)
@ -165,9 +182,9 @@ fn default_if_arg_present_no_arg_with_default() {
#[test]
fn default_if_arg_present_with_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", None, Some("default")),
)
@ -181,9 +198,9 @@ fn default_if_arg_present_with_default() {
#[test]
fn default_if_arg_present_with_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", None, Some("default")),
)
@ -197,9 +214,9 @@ fn default_if_arg_present_with_default_user_override() {
#[test]
fn default_if_arg_present_no_arg_with_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", None, Some("default")),
)
@ -215,8 +232,8 @@ fn default_if_arg_present_no_arg_with_default_user_override() {
#[test]
fn default_if_arg_present_with_value_no_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("[arg] 'some arg'").default_value_if("opt", Some("value"), Some("default")))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!([arg] "some arg").default_value_if("opt", Some("value"), Some("default")))
.try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -227,8 +244,8 @@ fn default_if_arg_present_with_value_no_default() {
#[test]
fn default_if_arg_present_with_value_no_default_fail() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("[arg] 'some arg'").default_value_if("opt", Some("value"), Some("default")))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!([arg] "some arg").default_value_if("opt", Some("value"), Some("default")))
.try_get_matches_from(vec!["", "--opt", "other"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -239,8 +256,8 @@ fn default_if_arg_present_with_value_no_default_fail() {
#[test]
fn default_if_arg_present_with_value_no_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("[arg] 'some arg'").default_value_if("opt", Some("some"), Some("default")))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!([arg] "some arg").default_value_if("opt", Some("some"), Some("default")))
.try_get_matches_from(vec!["", "--opt", "some", "other"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -251,9 +268,9 @@ fn default_if_arg_present_with_value_no_default_user_override() {
#[test]
fn default_if_arg_present_with_value_no_arg_with_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", Some("some"), Some("default")),
)
@ -267,9 +284,9 @@ fn default_if_arg_present_with_value_no_arg_with_default() {
#[test]
fn default_if_arg_present_with_value_no_arg_with_default_fail() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", Some("some"), Some("default")),
)
@ -283,9 +300,9 @@ fn default_if_arg_present_with_value_no_arg_with_default_fail() {
#[test]
fn default_if_arg_present_with_value_with_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", Some("some"), Some("default")),
)
@ -299,9 +316,9 @@ fn default_if_arg_present_with_value_with_default() {
#[test]
fn default_if_arg_present_with_value_with_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", Some("some"), Some("default")),
)
@ -315,9 +332,9 @@ fn default_if_arg_present_with_value_with_default_user_override() {
#[test]
fn default_if_arg_present_no_arg_with_value_with_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", Some("some"), Some("default")),
)
@ -331,9 +348,9 @@ fn default_if_arg_present_no_arg_with_value_with_default_user_override() {
#[test]
fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_if("opt", Some("some"), Some("default")),
)
@ -349,8 +366,8 @@ fn default_if_arg_present_no_arg_with_value_with_default_user_override_fail() {
#[test]
fn no_default_if_arg_present_with_value_no_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("[arg] 'some arg'").default_value_if("opt", Some("value"), None))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!([arg] "some arg").default_value_if("opt", Some("value"), None))
.try_get_matches_from(vec!["", "--opt", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -360,9 +377,9 @@ fn no_default_if_arg_present_with_value_no_default() {
#[test]
fn no_default_if_arg_present_with_value_with_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("default")
.default_value_if("opt", Some("value"), None),
)
@ -376,9 +393,9 @@ fn no_default_if_arg_present_with_value_with_default() {
#[test]
fn no_default_if_arg_present_with_value_with_default_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("default")
.default_value_if("opt", Some("value"), None),
)
@ -392,9 +409,9 @@ fn no_default_if_arg_present_with_value_with_default_user_override() {
#[test]
fn no_default_if_arg_present_no_arg_with_value_with_default() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("default")
.default_value_if("opt", Some("value"), None),
)
@ -410,10 +427,10 @@ fn no_default_if_arg_present_no_arg_with_value_with_default() {
#[test]
fn default_ifs_arg_present() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("--flag 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!(--flag "some arg"))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_ifs(&[
("opt", Some("some"), Some("default")),
@ -430,10 +447,10 @@ fn default_ifs_arg_present() {
#[test]
fn no_default_ifs_arg_present() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("--flag 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!(--flag "some arg"))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_ifs(&[("opt", Some("some"), Some("default")), ("flag", None, None)]),
)
@ -447,10 +464,10 @@ fn no_default_ifs_arg_present() {
#[test]
fn default_ifs_arg_present_user_override() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("--flag 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!(--flag "some arg"))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_ifs(&[
("opt", Some("some"), Some("default")),
@ -467,10 +484,10 @@ fn default_ifs_arg_present_user_override() {
#[test]
fn default_ifs_arg_present_order() {
let r = App::new("df")
.arg(Arg::from("--opt [FILE] 'some arg'"))
.arg(Arg::from("--flag 'some arg'"))
.arg(arg!(--opt <FILE> "some arg").required(false))
.arg(arg!(--flag "some arg"))
.arg(
Arg::from("[arg] 'some arg'")
arg!([arg] "some arg")
.default_value("first")
.default_value_ifs(&[
("opt", Some("some"), Some("default")),

View file

@ -3,18 +3,14 @@
use std::env;
use std::ffi::OsStr;
use clap::{App, Arg};
use clap::{arg, App, Arg};
#[test]
fn env() {
env::set_var("CLP_TEST_ENV", "env");
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
.env("CLP_TEST_ENV")
.takes_value(true),
)
.arg(arg!([arg] "some opt").env("CLP_TEST_ENV").takes_value(true))
.try_get_matches_from(vec![""]);
assert!(r.is_ok());
@ -50,7 +46,7 @@ fn env_os() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env_os(OsStr::new("CLP_TEST_ENV_OS"))
.takes_value(true),
)
@ -71,7 +67,7 @@ fn no_env() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_NONE")
.takes_value(true),
)
@ -91,7 +87,7 @@ fn no_env_no_takes_value() {
env::remove_var("CLP_TEST_ENV_NONE");
let r = App::new("df")
.arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV_NONE"))
.arg(arg!([arg] "some opt").env("CLP_TEST_ENV_NONE"))
.try_get_matches_from(vec![""]);
assert!(r.is_ok());
@ -107,7 +103,7 @@ fn with_default() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_WD")
.takes_value(true)
.default_value("default"),
@ -127,7 +123,7 @@ fn opt_user_override() {
let r = App::new("df")
.arg(
Arg::from("--arg [FILE] 'some arg'")
arg!(--arg [FILE] "some arg")
.env("CLP_TEST_ENV_OR")
.takes_value(true),
)
@ -150,7 +146,7 @@ fn positionals() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_P")
.takes_value(true),
)
@ -169,7 +165,7 @@ fn positionals_user_override() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_POR")
.takes_value(true),
)
@ -192,7 +188,7 @@ fn multiple_one() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_MO")
.takes_value(true)
.use_delimiter(true)
@ -213,7 +209,7 @@ fn multiple_three() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_MULTI1")
.takes_value(true)
.use_delimiter(true)
@ -237,7 +233,7 @@ fn multiple_no_delimiter() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_MULTI2")
.takes_value(true)
.multiple_values(true),
@ -260,7 +256,7 @@ fn possible_value() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_PV")
.takes_value(true)
.possible_value("env"),
@ -280,7 +276,7 @@ fn not_possible_value() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_NPV")
.takes_value(true)
.possible_value("never"),
@ -296,7 +292,7 @@ fn validator() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_VDOR")
.takes_value(true)
.validator(|s| {
@ -322,7 +318,7 @@ fn validator_output() {
let m = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_VO")
.takes_value(true)
.validator(|s| s.parse::<i32>()),
@ -338,7 +334,7 @@ fn validator_invalid() {
let r = App::new("df")
.arg(
Arg::from("[arg] 'some opt'")
arg!([arg] "some opt")
.env("CLP_TEST_ENV_IV")
.takes_value(true)
.validator(|s| {

View file

@ -5,14 +5,7 @@ use std::fs;
use std::process::{Command, Output};
fn run_example<S: AsRef<str>>(name: S, args: &[&str]) -> Output {
let mut all_args = vec![
"run",
"--example",
name.as_ref(),
"--features",
"yaml",
"--",
];
let mut all_args = vec!["run", "--example", name.as_ref(), "--"];
all_args.extend_from_slice(args);
Command::new(env!("CARGO"))

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, AppSettings, Arg, ErrorKind};
use clap::{arg, App, AppSettings, Arg, ErrorKind};
#[test]
fn flag_subcommand_normal() {
@ -274,14 +274,14 @@ fn flag_subcommand_multiple() {
App::new("some")
.short_flag('S')
.long_flag("some")
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(Arg::from("-p, --print 'print something'"))
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-p --print "print something"))
.subcommand(
App::new("result")
.short_flag('R')
.long_flag("result")
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(Arg::from("-p, --print 'print something'")),
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-p --print "print something")),
),
)
.get_matches_from(vec!["myprog", "-SfpRfp"]);

View file

@ -1,5 +1,5 @@
mod utils;
use clap::{App, Arg};
use clap::{arg, App, Arg};
const USE_FLAG_AS_ARGUMENT: &str =
"error: Found argument '--another-flag' which wasn't expected, or isn't valid in this context
@ -16,8 +16,8 @@ For more information try --help
fn flag_using_short() {
let m = App::new("flag")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::from("-c, --color 'some other flag'"),
arg!(-f --flag "some flag"),
arg!(-c --color "some other flag"),
])
.get_matches_from(vec!["", "-f", "-c"]);
assert!(m.is_present("flag"));
@ -27,7 +27,7 @@ fn flag_using_short() {
#[test]
fn lots_o_flags_sep() {
let r = App::new("opts")
.arg(Arg::from("-o... 'some flag'"))
.arg(arg!(o: -o ... "some flag"))
.try_get_matches_from(vec![
"", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
"-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o", "-o",
@ -61,7 +61,7 @@ fn lots_o_flags_sep() {
#[test]
fn lots_o_flags_combined() {
let r = App::new("opts")
.arg(Arg::from("-o... 'some flag'"))
.arg(arg!(o: -o ... "some flag"))
.try_get_matches_from(vec![
"",
"-oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo",
@ -79,10 +79,7 @@ fn lots_o_flags_combined() {
#[test]
fn flag_using_long() {
let m = App::new("flag")
.args(&[
Arg::from("--flag 'some flag'"),
Arg::from("--color 'some other flag'"),
])
.args(&[arg!(--flag "some flag"), arg!(--color "some other flag")])
.get_matches_from(vec!["", "--flag", "--color"]);
assert!(m.is_present("flag"));
assert!(m.is_present("color"));
@ -103,8 +100,8 @@ fn flag_using_long_with_literals() {
fn flag_using_mixed() {
let m = App::new("flag")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::from("-c, --color 'some other flag'"),
arg!(-f --flag "some flag"),
arg!(-c --color "some other flag"),
])
.get_matches_from(vec!["", "-f", "--color"]);
assert!(m.is_present("flag"));
@ -112,8 +109,8 @@ fn flag_using_mixed() {
let m = App::new("flag")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::from("-c, --color 'some other flag'"),
arg!(-f --flag "some flag"),
arg!(-c --color "some other flag"),
])
.get_matches_from(vec!["", "--flag", "-c"]);
assert!(m.is_present("flag"));
@ -124,9 +121,9 @@ fn flag_using_mixed() {
fn multiple_flags_in_single() {
let m = App::new("multe_flags")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::from("-c, --color 'some other flag'"),
Arg::from("-d, --debug 'another other flag'"),
arg!(-f --flag "some flag"),
arg!(-c --color "some other flag"),
arg!(-d --debug "another other flag"),
])
.get_matches_from(vec!["", "-fcd"]);
assert!(m.is_present("flag"));

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, Arg};
use clap::{arg, App, Arg};
#[test]
fn issue_1076() {
@ -49,20 +49,12 @@ fn propagate_global_arg_in_subcommand_to_subsubcommand_1385() {
#[test]
fn propagate_global_arg_to_subcommand_in_subsubcommand_2053() {
let m = App::new("opts")
.arg(Arg::from("--global-flag").global(true))
.arg(
Arg::from("--global-str <global-str>")
.required(false)
.global(true),
)
.arg(arg!(--"global-flag").global(true))
.arg(arg!(--"global-str" <str>).required(false).global(true))
.subcommand(
App::new("test")
.arg(Arg::from("--sub-flag").global(true))
.arg(
Arg::from("--sub-str <sub-str>")
.required(false)
.global(true),
)
.arg(arg!(--"sub-flag").global(true))
.arg(arg!(--"sub-str" <str>).required(false).global(true))
.subcommand(App::new("test")),
)
.get_matches_from(&[

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, Arg, ArgGroup, ErrorKind};
use clap::{arg, App, Arg, ArgGroup, ErrorKind};
static REQ_GROUP_USAGE: &str = "error: The following required arguments were not provided:
<base|--delete>
@ -32,8 +32,8 @@ For more information try --help
#[test]
fn required_group_missing_arg() {
let result = App::new("group")
.arg("-f, --flag 'some flag'")
.arg(" -c, --color 'some other flag'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!( -c --color "some other flag"))
.group(ArgGroup::new("req").args(&["flag", "color"]).required(true))
.try_get_matches_from(vec![""]);
assert!(result.is_err());
@ -46,8 +46,8 @@ fn required_group_missing_arg() {
#[should_panic = "Argument group 'req' contains non-existent argument"]
fn non_existing_arg() {
let _ = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color 'some other flag'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color "some other flag"))
.group(ArgGroup::new("req").args(&["flg", "color"]).required(true))
.try_get_matches_from(vec![""]);
}
@ -57,8 +57,8 @@ fn non_existing_arg() {
#[should_panic = "Argument group name must be unique\n\n\t'req' is already in use"]
fn unique_group_name() {
let _ = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color 'some other flag'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color "some other flag"))
.group(ArgGroup::new("req").args(&["flag"]).required(true))
.group(ArgGroup::new("req").args(&["color"]).required(true))
.try_get_matches_from(vec![""]);
@ -86,8 +86,8 @@ fn arg_group_new_of_arg_name() {
#[test]
fn group_single_value() {
let res = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color [color] 'some option'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color [color] "some option"))
.group(ArgGroup::new("grp").args(&["flag", "color"]))
.try_get_matches_from(vec!["", "-c", "blue"]);
assert!(res.is_ok());
@ -100,8 +100,8 @@ fn group_single_value() {
#[test]
fn group_single_flag() {
let res = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color [color] 'some option'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color [color] "some option"))
.group(ArgGroup::new("grp").args(&["flag", "color"]))
.try_get_matches_from(vec!["", "-f"]);
assert!(res.is_ok());
@ -114,8 +114,8 @@ fn group_single_flag() {
#[test]
fn group_empty() {
let res = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color [color] 'some option'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color [color] "some option"))
.group(ArgGroup::new("grp").args(&["flag", "color"]))
.try_get_matches_from(vec![""]);
assert!(res.is_ok());
@ -128,8 +128,8 @@ fn group_empty() {
#[test]
fn group_reqired_flags_empty() {
let result = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color 'some option'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color "some option"))
.group(ArgGroup::new("grp").required(true).args(&["flag", "color"]))
.try_get_matches_from(vec![""]);
assert!(result.is_err());
@ -140,8 +140,8 @@ fn group_reqired_flags_empty() {
#[test]
fn group_multi_value_single_arg() {
let res = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color [color]... 'some option'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color <color> "some option").multiple_values(true))
.group(ArgGroup::new("grp").args(&["flag", "color"]))
.try_get_matches_from(vec!["", "-c", "blue", "red", "green"]);
assert!(res.is_ok(), "{:?}", res.unwrap_err().kind);
@ -157,7 +157,7 @@ fn group_multi_value_single_arg() {
#[test]
fn empty_group() {
let r = App::new("empty_group")
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(arg!(-f --flag "some flag"))
.group(ArgGroup::new("vers").required(true))
.try_get_matches_from(vec!["empty_prog"]);
assert!(r.is_err());
@ -168,8 +168,10 @@ fn empty_group() {
#[test]
fn req_group_usage_string() {
let app = App::new("req_group")
.arg("[base] 'Base commit'")
.arg("-d, --delete 'Remove the base commit information'")
.arg(arg!([base] "Base commit"))
.arg(arg!(
-d --delete "Remove the base commit information"
))
.group(
ArgGroup::new("base_or_delete")
.args(&["base", "delete"])
@ -187,9 +189,9 @@ fn req_group_usage_string() {
#[test]
fn req_group_with_conflict_usage_string() {
let app = App::new("req_group")
.arg(Arg::from("[base] 'Base commit'").conflicts_with("delete"))
.arg(Arg::from(
"-d, --delete 'Remove the base commit information'",
.arg(arg!([base] "Base commit").conflicts_with("delete"))
.arg(arg!(
-d --delete "Remove the base commit information"
))
.group(
ArgGroup::new("base_or_delete")
@ -208,9 +210,9 @@ fn req_group_with_conflict_usage_string() {
#[test]
fn req_group_with_conflict_usage_string_only_options() {
let app = App::new("req_group")
.arg(Arg::from("<all> -a --all 'All'").conflicts_with("delete"))
.arg(Arg::from(
"<delete> -d, --delete 'Remove the base commit information'",
.arg(arg!(-a --all "All").conflicts_with("delete"))
.arg(arg!(
-d --delete "Remove the base commit information"
))
.group(
ArgGroup::new("all_or_delete")
@ -228,8 +230,8 @@ fn req_group_with_conflict_usage_string_only_options() {
#[test]
fn required_group_multiple_args() {
let result = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color 'some other flag'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color "some other flag"))
.group(
ArgGroup::new("req")
.args(&["flag", "color"])
@ -246,8 +248,8 @@ fn required_group_multiple_args() {
#[test]
fn group_multiple_args_error() {
let result = App::new("group")
.arg("-f, --flag 'some flag'")
.arg("-c, --color 'some other flag'")
.arg(arg!(-f --flag "some flag"))
.arg(arg!(-c --color "some other flag"))
.group(ArgGroup::new("req").args(&["flag", "color"]))
.try_get_matches_from(vec!["group", "-f", "-c"]);
assert!(result.is_err());

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, AppSettings, Arg, ArgGroup, ArgSettings, ErrorKind, PossibleValue};
use clap::{arg, App, AppSettings, Arg, ArgGroup, ArgSettings, ErrorKind, PossibleValue};
static REQUIRE_DELIM_HELP: &str = "test 1.3
@ -666,7 +666,7 @@ fn help_subcommand() {
.subcommand(
App::new("test")
.about("tests things")
.arg("-v --verbose 'with verbosity'"),
.arg(arg!(-v --verbose "with verbosity")),
)
.try_get_matches_from(vec!["myprog", "help"]);
@ -832,8 +832,17 @@ fn multi_level_sc_help() {
.about("tests subcommands")
.author("Kevin K. <kbknapp@gmail.com>")
.version("0.1")
.arg("-f, --flag 'tests flags'")
.arg("-o, --option [scoption]... 'tests options'"),
.arg(arg!(
-f --flag "tests flags"
))
.arg(
arg!(
-o --option <scoption> "tests options"
)
.required(false)
.multiple_values(true)
.multiple_occurrences(true),
),
),
);
assert!(utils::compare_output(
@ -1361,7 +1370,7 @@ fn sc_negates_reqs() {
let app = App::new("prog")
.version("1.0")
.setting(AppSettings::SubcommandsNegateReqs)
.arg("-o, --opt <FILE> 'tests options'")
.arg(arg!(-o --opt <FILE> "tests options"))
.arg(Arg::new("PATH").help("help"))
.subcommand(App::new("test"));
assert!(utils::compare_output(
@ -1376,8 +1385,8 @@ fn sc_negates_reqs() {
fn hidden_args() {
let app = App::new("prog")
.version("1.0")
.arg("-f, --flag 'testing flags'")
.arg("-o, --opt [FILE] 'tests options'")
.arg(arg!(-f --flag "testing flags"))
.arg(arg!(-o --opt <FILE> "tests options").required(false))
.arg(Arg::new("pos").hidden(true));
assert!(utils::compare_output(
app,
@ -1392,8 +1401,8 @@ fn args_negate_sc() {
let app = App::new("prog")
.version("1.0")
.setting(AppSettings::ArgsNegateSubcommands)
.arg("-f, --flag 'testing flags'")
.arg("-o, --opt [FILE] 'tests options'")
.arg(arg!(-f --flag "testing flags"))
.arg(arg!(-o --opt <FILE> "tests options").required(false))
.arg(Arg::new("PATH").help("help"))
.subcommand(App::new("test"));
assert!(utils::compare_output(
@ -1408,8 +1417,8 @@ fn args_negate_sc() {
fn issue_1046_hidden_scs() {
let app = App::new("prog")
.version("1.0")
.arg("-f, --flag 'testing flags'")
.arg("-o, --opt [FILE] 'tests options'")
.arg(arg!(-f --flag "testing flags"))
.arg(arg!(-o --opt <FILE> "tests options").required(false))
.arg(Arg::new("PATH").help("some"))
.subcommand(App::new("test").setting(AppSettings::Hidden));
assert!(utils::compare_output(
@ -1730,7 +1739,9 @@ fn issue_1052_require_delim_help() {
.about("tests stuff")
.version("1.3")
.arg(
Arg::from("-f, --fake <some> <val> 'some help'")
arg!(-f --fake "some help")
.required(true)
.value_names(&["some", "val"])
.takes_value(true)
.use_delimiter(true)
.require_delimiter(true)
@ -1752,7 +1763,9 @@ fn custom_headers_headers() {
.about("does stuff")
.version("1.4")
.arg(
Arg::from("-f, --fake <some> <val> 'some help'")
arg!(-f --fake "some help")
.required(true)
.value_names(&["some", "val"])
.takes_value(true)
.use_delimiter(true)
.require_delimiter(true)
@ -1809,7 +1822,9 @@ fn multiple_custom_help_headers() {
.about("does stuff")
.version("1.4")
.arg(
Arg::from("-f, --fake <some> <val> 'some help'")
arg!(-f --fake "some help")
.required(true)
.value_names(&["some", "val"])
.takes_value(true)
.use_delimiter(true)
.require_delimiter(true)
@ -1824,16 +1839,16 @@ fn multiple_custom_help_headers() {
)
.help_heading(Some("SPECIAL"))
.arg(
Arg::from("-b, --birthday-song <song> 'Change which song is played for birthdays'")
arg!(-b --"birthday-song" <song> "Change which song is played for birthdays")
.help_heading(Some("OVERRIDE SPECIAL")),
)
.arg(
Arg::from("--style <style> 'Choose musical style to play the song'")
arg!(--style <style> "Choose musical style to play the song")
.required(false)
.help_heading(None),
)
.arg(Arg::from(
"-v --birthday-song-volume <volume> 'Change the volume of the birthday song'",
.arg(arg!(
-v --"birthday-song-volume" <volume> "Change the volume of the birthday song"
))
.help_heading(None)
.arg(
@ -1897,11 +1912,11 @@ fn custom_help_headers_hidden_args() {
)
.help_heading(Some("SPECIAL"))
.arg(
Arg::from("-b, --song <song> 'Change which song is played for birthdays'")
arg!(-b --song <song> "Change which song is played for birthdays")
.help_heading(Some("OVERRIDE SPECIAL")),
)
.arg(Arg::from(
"-v --song-volume <volume> 'Change the volume of the birthday song'",
.arg(arg!(
-v --"song-volume" <volume> "Change the volume of the birthday song"
))
.help_heading(None)
.arg(
@ -2390,7 +2405,7 @@ fn only_custom_heading_opts_no_args() {
.setting(AppSettings::DisableVersionFlag)
.mut_arg("help", |a| a.hidden(true))
.help_heading(Some("NETWORKING"))
.arg(Arg::from("-s, --speed [SPEED] 'How fast'"));
.arg(arg!(-s --speed <SPEED> "How fast").required(false));
assert!(utils::compare_output(
app,

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, AppSettings, Arg};
use clap::{arg, App, AppSettings, Arg};
static HIDDEN_ARGS: &str = "test 1.4
@ -25,9 +25,9 @@ fn hidden_args() {
.about("tests stuff")
.version("1.4")
.args(&[
Arg::from("-f, --flag 'some flag'").hidden(true),
Arg::from("-F, --flag2 'some other flag'"),
Arg::from("--option [opt] 'some option'"),
arg!(-f --flag "some flag").hidden(true),
arg!(-F --flag2 "some other flag"),
arg!(--option <opt> "some option").required(false),
Arg::new("DUMMY").hidden(true),
]);
assert!(utils::compare_output(
@ -285,7 +285,11 @@ fn hidden_opt_args_only() {
.after_help("After help")
.mut_arg("help", |a| a.hidden(true))
.mut_arg("version", |a| a.hidden(true))
.args(&[Arg::from("--option [opt] 'some option'").hidden(true)]);
.arg(
arg!(--option <opt> "some option")
.required(false)
.hidden(true),
);
assert!(utils::compare_output(
app,

View file

@ -1,10 +1,10 @@
use clap::{App, AppSettings, Arg};
use clap::{arg, App, AppSettings, Arg};
#[test]
fn single_short_arg_without_value() {
let app = App::new("app")
.setting(AppSettings::IgnoreErrors)
.arg("-c, --config=[FILE] 'Sets a custom config file'");
let app = App::new("app").setting(AppSettings::IgnoreErrors).arg(arg!(
-c --config [FILE] "Sets a custom config file"
));
let r = app.try_get_matches_from(vec!["app", "-c" /* missing: , "config file" */]);
@ -15,9 +15,9 @@ fn single_short_arg_without_value() {
#[test]
fn single_long_arg_without_value() {
let app = App::new("app")
.setting(AppSettings::IgnoreErrors)
.arg("-c, --config=[FILE] 'Sets a custom config file'");
let app = App::new("app").setting(AppSettings::IgnoreErrors).arg(arg!(
-c --config [FILE] "Sets a custom config file"
));
let r = app.try_get_matches_from(vec!["app", "--config" /* missing: , "config file" */]);
@ -30,9 +30,13 @@ fn single_long_arg_without_value() {
fn multiple_args_and_final_arg_without_value() {
let app = App::new("app")
.setting(AppSettings::IgnoreErrors)
.arg("-c, --config=[FILE] 'Sets a custom config file'")
.arg("-x, --stuff=[FILE] 'Sets a custom stuff file'")
.arg("-f 'Flag'");
.arg(arg!(
-c --config [FILE] "Sets a custom config file"
))
.arg(arg!(
-x --stuff [FILE] "Sets a custom stuff file"
))
.arg(arg!(f: -f "Flag"));
let r = app.try_get_matches_from(vec![
"app", "-c", "file", "-f", "-x", /* missing: , "some stuff" */
@ -49,9 +53,13 @@ fn multiple_args_and_final_arg_without_value() {
fn multiple_args_and_intermittent_arg_without_value() {
let app = App::new("app")
.setting(AppSettings::IgnoreErrors)
.arg("-c, --config=[FILE] 'Sets a custom config file'")
.arg("-x, --stuff=[FILE] 'Sets a custom stuff file'")
.arg("-f 'Flag'");
.arg(arg!(
-c --config[FILE] "Sets a custom config file"
))
.arg(arg!(
-x --stuff[FILE] "Sets a custom stuff file"
))
.arg(arg!(f: -f "Flag"));
let r = app.try_get_matches_from(vec![
"app", "-x", /* missing: ,"some stuff" */

View file

@ -517,3 +517,185 @@ fn validator() {
assert_eq!(matches.value_of_t::<u16>("func1").ok(), Some(34));
assert_eq!(matches.value_of_t::<u16>("func2").ok(), Some(56));
}
mod arg {
#[test]
fn name_explicit() {
let arg = clap::arg!(foo: --bar <NUM>);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_long(), Some("bar"));
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(arg.is_set(clap::ArgSettings::Required));
}
#[test]
fn name_from_long() {
let arg = clap::arg!(--bar <NUM>);
assert_eq!(arg.get_name(), "bar");
assert_eq!(arg.get_long(), Some("bar"));
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(arg.is_set(clap::ArgSettings::Required));
}
#[test]
fn name_from_value() {
let arg = clap::arg!(<NUM>);
assert_eq!(arg.get_name(), "NUM");
assert_eq!(arg.get_long(), None);
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(arg.is_set(clap::ArgSettings::Required));
}
#[test]
#[should_panic]
fn name_none_fails() {
clap::arg!("Help");
}
#[test]
#[should_panic]
fn short_only_fails() {
clap::arg!(-b);
}
#[test]
fn short() {
let arg = clap::arg!(foo: -b);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_short(), Some('b'));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: -'b');
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_short(), Some('b'));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: -b ...);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_short(), Some('b'));
assert!(arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: -b "How to use it");
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_short(), Some('b'));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), Some("How to use it"));
}
#[test]
fn short_and_long() {
let arg = clap::arg!(foo: -b --hello);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_long(), Some("hello"));
assert_eq!(arg.get_short(), Some('b'));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: -'b' --hello);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_long(), Some("hello"));
assert_eq!(arg.get_short(), Some('b'));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: -b --hello ...);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_long(), Some("hello"));
assert_eq!(arg.get_short(), Some('b'));
assert!(arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: -b --hello "How to use it");
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_long(), Some("hello"));
assert_eq!(arg.get_short(), Some('b'));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), Some("How to use it"));
}
#[test]
fn positional() {
let arg = clap::arg!(<NUM>);
assert_eq!(arg.get_name(), "NUM");
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!([NUM]);
assert_eq!(arg.get_name(), "NUM");
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(!arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(<NUM>);
assert_eq!(arg.get_name(), "NUM");
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(foo: <NUM>);
assert_eq!(arg.get_name(), "foo");
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(<NUM> ...);
assert_eq!(arg.get_name(), "NUM");
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), None);
let arg = clap::arg!(<NUM> "How to use it");
assert_eq!(arg.get_name(), "NUM");
assert_eq!(arg.get_value_names(), Some(vec!["NUM"].as_slice()));
assert!(!arg.is_set(clap::ArgSettings::MultipleOccurrences));
assert!(arg.is_set(clap::ArgSettings::Required));
assert_eq!(arg.get_help(), Some("How to use it"));
}
}
mod arg_impl {
#[test]
fn string_ident() {
let expected = "one";
let actual = clap::arg_impl! { @string one };
assert_eq!(actual, expected);
}
#[test]
fn string_literal() {
let expected = "one";
let actual = clap::arg_impl! { @string "one" };
assert_eq!(actual, expected);
}
#[test]
fn char_ident() {
let expected = 'o';
let actual = clap::arg_impl! { @char o };
assert_eq!(actual, expected);
}
#[test]
fn char_literal() {
let expected = 'o';
let actual = clap::arg_impl! { @char 'o' };
assert_eq!(actual, expected);
}
}

View file

@ -1,13 +1,10 @@
use clap::{App, Arg, ArgSettings, ErrorKind};
use clap::{arg, App, Arg, ArgSettings, ErrorKind};
#[test]
fn multiple_occurrences_of_flags_long() {
let m = App::new("mo_flags_long")
.arg(
Arg::from("--multflag 'allowed multiple flag'")
.setting(ArgSettings::MultipleOccurrences),
)
.arg(Arg::from("--flag 'disallowed multiple flag'"))
.arg(arg!(--multflag "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
.arg(arg!(--flag "disallowed multiple flag"))
.get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]);
assert!(m.is_present("multflag"));
assert_eq!(m.occurrences_of("multflag"), 2);
@ -18,11 +15,8 @@ fn multiple_occurrences_of_flags_long() {
#[test]
fn multiple_occurrences_of_flags_short() {
let m = App::new("mo_flags_short")
.arg(
Arg::from("-m --multflag 'allowed multiple flag'")
.setting(ArgSettings::MultipleOccurrences),
)
.arg(Arg::from("-f --flag 'disallowed multiple flag'"))
.arg(arg!(-m --multflag "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
.arg(arg!(-f --flag "disallowed multiple flag"))
.get_matches_from(vec!["", "-m", "-f", "-m"]);
assert!(m.is_present("multflag"));
assert_eq!(m.occurrences_of("multflag"), 2);
@ -33,15 +27,12 @@ fn multiple_occurrences_of_flags_short() {
#[test]
fn multiple_occurrences_of_flags_mixed() {
let m = App::new("mo_flags_mixed")
.arg(arg!(-m --multflag1 "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
.arg(
Arg::from("-m, --multflag1 'allowed multiple flag'")
arg!(-n --multflag2 "another allowed multiple flag")
.setting(ArgSettings::MultipleOccurrences),
)
.arg(
Arg::from("-n, --multflag2 'another allowed multiple flag'")
.setting(ArgSettings::MultipleOccurrences),
)
.arg(Arg::from("-f, --flag 'disallowed multiple flag'"))
.arg(arg!(-f --flag "disallowed multiple flag"))
.get_matches_from(vec![
"",
"-m",
@ -98,10 +89,7 @@ fn multiple_occurrences_of_flags_large_quantity() {
.chain(vec!["-m"; 1024].into_iter())
.collect();
let m = App::new("mo_flags_large_qty")
.arg(
Arg::from("-m --multflag 'allowed multiple flag'")
.setting(ArgSettings::MultipleOccurrences),
)
.arg(arg!(-m --multflag "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
.get_matches_from(args);
assert!(m.is_present("multflag"));
assert_eq!(m.occurrences_of("multflag"), 1024);

View file

@ -1270,21 +1270,6 @@ fn value_names_building_num_vals() {
);
}
#[test]
fn value_names_building_num_vals_from_usage() {
let m = App::new("test")
.arg(Arg::from("--pos <who> <what> <why>"))
.try_get_matches_from(vec!["myprog", "--pos", "val1", "val2", "val3"]);
assert!(m.is_ok(), "{:?}", m.unwrap_err().kind);
let m = m.unwrap();
assert_eq!(
m.values_of("pos").unwrap().collect::<Vec<_>>(),
["val1", "val2", "val3"]
);
}
#[test]
fn value_names_building_num_vals_for_positional() {
let m = App::new("test")

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, ErrorKind};
use clap::{arg, App, AppSettings, Arg, ArgMatches, ArgSettings, ErrorKind};
#[cfg(feature = "suggestions")]
static DYM: &str =
@ -146,7 +146,7 @@ fn require_equals_pass() {
#[test]
fn stdin_char() {
let r = App::new("opts")
.arg(Arg::from("-f [flag] 'some flag'"))
.arg(arg!(f: -f [flag] "some flag"))
.try_get_matches_from(vec!["", "-f", "-"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -158,8 +158,8 @@ fn stdin_char() {
fn opts_using_short() {
let r = App::new("opts")
.args(&[
Arg::from("-f [flag] 'some flag'"),
Arg::from("-c [color] 'some other flag'"),
arg!(f: -f [flag] "some flag"),
arg!(c: -c [color] "some other flag"),
])
.try_get_matches_from(vec!["", "-f", "some", "-c", "other"]);
assert!(r.is_ok());
@ -173,7 +173,7 @@ fn opts_using_short() {
#[test]
fn lots_o_vals() {
let r = App::new("opts")
.arg(Arg::from("-o [opt]... 'some opt'"))
.arg(arg!(o: -o <opt> "some opt").multiple_values(true))
.try_get_matches_from(vec![
"", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
@ -214,8 +214,8 @@ fn lots_o_vals() {
fn opts_using_long_space() {
let r = App::new("opts")
.args(&[
Arg::from("--flag [flag] 'some flag'"),
Arg::from("--color [color] 'some other flag'"),
arg!(--flag [flag] "some flag"),
arg!(--color [color] "some other flag"),
])
.try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
assert!(r.is_ok());
@ -230,8 +230,8 @@ fn opts_using_long_space() {
fn opts_using_long_equals() {
let r = App::new("opts")
.args(&[
Arg::from("--flag [flag] 'some flag'"),
Arg::from("--color [color] 'some other flag'"),
arg!(--flag [flag] "some flag"),
arg!(--color [color] "some other flag"),
])
.try_get_matches_from(vec!["", "--flag=some", "--color=other"]);
assert!(r.is_ok());
@ -246,8 +246,8 @@ fn opts_using_long_equals() {
fn opts_using_mixed() {
let r = App::new("opts")
.args(&[
Arg::from("-f, --flag [flag] 'some flag'"),
Arg::from("-c, --color [color] 'some other flag'"),
arg!(-f --flag [flag] "some flag"),
arg!(-c --color [color] "some other flag"),
])
.try_get_matches_from(vec!["", "-f", "some", "--color", "other"]);
assert!(r.is_ok());
@ -262,8 +262,8 @@ fn opts_using_mixed() {
fn opts_using_mixed2() {
let r = App::new("opts")
.args(&[
Arg::from("-f, --flag [flag] 'some flag'"),
Arg::from("-c, --color [color] 'some other flag'"),
arg!(-f --flag [flag] "some flag"),
arg!(-c --color [color] "some other flag"),
])
.try_get_matches_from(vec!["", "--flag=some", "-c", "other"]);
assert!(r.is_ok());
@ -277,7 +277,7 @@ fn opts_using_mixed2() {
#[test]
fn default_values_user_value() {
let r = App::new("df")
.arg(Arg::from("-o [opt] 'some opt'").default_value("default"))
.arg(arg!(o: -o [opt] "some opt").default_value("default"))
.try_get_matches_from(vec!["", "-o", "value"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -288,8 +288,8 @@ fn default_values_user_value() {
#[test]
fn multiple_vals_pos_arg_equals() {
let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'"))
.arg(Arg::from("[file] 'some file'"))
.arg(arg!(o: -o [opt] ... "some opt"))
.arg(arg!([file] "some file"))
.try_get_matches_from(vec!["", "-o=1", "some"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -302,8 +302,12 @@ fn multiple_vals_pos_arg_equals() {
#[test]
fn multiple_vals_pos_arg_delim() {
let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::UseValueDelimiter))
.arg(Arg::from("[file] 'some file'"))
.arg(
arg!(o: -o <opt> "some opt")
.multiple_values(true)
.setting(ArgSettings::UseValueDelimiter),
)
.arg(arg!([file] "some file"))
.try_get_matches_from(vec!["", "-o", "1,2", "some"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -317,11 +321,11 @@ fn multiple_vals_pos_arg_delim() {
fn require_delims_no_delim() {
let r = App::new("mvae")
.arg(
Arg::from("-o [opt]... 'some opt'")
arg!(o: -o [opt] ... "some opt")
.setting(ArgSettings::UseValueDelimiter)
.setting(ArgSettings::RequireDelimiter),
)
.arg(Arg::from("[file] 'some file'"))
.arg(arg!([file] "some file"))
.try_get_matches_from(vec!["mvae", "-o", "1", "2", "some"]);
assert!(r.is_err());
let err = r.unwrap_err();
@ -332,11 +336,12 @@ fn require_delims_no_delim() {
fn require_delims() {
let r = App::new("mvae")
.arg(
Arg::from("-o [opt]... 'some opt'")
arg!(o: -o <opt> "some opt")
.multiple_values(true)
.setting(ArgSettings::UseValueDelimiter)
.setting(ArgSettings::RequireDelimiter),
)
.arg(Arg::from("[file] 'some file'"))
.arg(arg!([file] "some file"))
.try_get_matches_from(vec!["", "-o", "1,2", "some"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -349,7 +354,11 @@ fn require_delims() {
#[test]
fn leading_hyphen_pass() {
let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues))
.arg(
arg!(o: -o <opt> "some opt")
.multiple_values(true)
.setting(ArgSettings::AllowHyphenValues),
)
.try_get_matches_from(vec!["", "-o", "-2", "3"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -360,7 +369,7 @@ fn leading_hyphen_pass() {
#[test]
fn leading_hyphen_fail() {
let r = App::new("mvae")
.arg(Arg::from("-o [opt] 'some opt'"))
.arg(arg!(o: -o <opt> "some opt"))
.try_get_matches_from(vec!["", "-o", "-2"]);
assert!(r.is_err());
let m = r.unwrap_err();
@ -370,8 +379,12 @@ fn leading_hyphen_fail() {
#[test]
fn leading_hyphen_with_flag_after() {
let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues))
.arg("-f 'some flag'")
.arg(
arg!(o: -o <opt> "some opt")
.multiple_values(true)
.setting(ArgSettings::AllowHyphenValues),
)
.arg(arg!(f: -f "some flag"))
.try_get_matches_from(vec!["", "-o", "-2", "-f"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -383,8 +396,8 @@ fn leading_hyphen_with_flag_after() {
#[test]
fn leading_hyphen_with_flag_before() {
let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues))
.arg("-f 'some flag'")
.arg(arg!(o: -o [opt] ... "some opt").setting(ArgSettings::AllowHyphenValues))
.arg(arg!(f: -f "some flag"))
.try_get_matches_from(vec!["", "-f", "-o", "-2"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -397,12 +410,12 @@ fn leading_hyphen_with_flag_before() {
fn leading_hyphen_with_only_pos_follows() {
let r = App::new("mvae")
.arg(
Arg::from("-o [opt]... 'some opt'")
arg!(o: -o [opt] ... "some opt")
.number_of_values(1)
.setting(ArgSettings::TakesValue)
.setting(ArgSettings::AllowHyphenValues),
)
.arg("[arg] 'some arg'")
.arg(arg!([arg] "some arg"))
.try_get_matches_from(vec!["", "-o", "-2", "--", "val"]);
assert!(r.is_ok(), "{:?}", r);
let m = r.unwrap();
@ -422,20 +435,6 @@ fn did_you_mean() {
));
}
#[test]
fn issue_665() {
let res = App::new("tester")
.arg("-v, --reroll-count=[N] 'Mark the patch series as PATCH vN'")
.arg(
Arg::from("--subject-prefix [Subject-Prefix] 'Use [Subject-Prefix] instead of the standard [PATCH] prefix'")
.setting(ArgSettings::ForbidEmptyValues)
)
.try_get_matches_from(vec!["test", "--subject-prefix", "-v", "2"]);
assert!(res.is_err());
assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
}
#[test]
fn issue_1047_min_zero_vals_default_val() {
let m = App::new("foo")
@ -455,8 +454,8 @@ fn issue_1047_min_zero_vals_default_val() {
fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error> {
App::new("opts")
.arg(Arg::from("-o, --option [opt] 'some option'"))
.arg(Arg::from("--flag 'some flag'"))
.arg(arg!(-o --option <opt> "some option"))
.arg(arg!(--flag "some flag"))
.try_get_matches_from(argv)
}
@ -531,7 +530,7 @@ fn issue_1073_suboptimal_flag_suggestion() {
#[test]
fn short_non_ascii_no_space() {
let matches = App::new("app")
.arg("<opt> -磨 <opt>")
.arg(arg!(opt: -'磨' <opt>))
.get_matches_from(&["test", "-磨VALUE"]);
assert_eq!("VALUE", matches.value_of("opt").unwrap());
@ -540,7 +539,7 @@ fn short_non_ascii_no_space() {
#[test]
fn short_eq_val_starts_with_eq() {
let matches = App::new("app")
.arg("<opt> -f <opt>")
.arg(arg!(opt: -f <opt>))
.get_matches_from(&["test", "-f==value"]);
assert_eq!("=value", matches.value_of("opt").unwrap());
@ -549,7 +548,7 @@ fn short_eq_val_starts_with_eq() {
#[test]
fn long_eq_val_starts_with_eq() {
let matches = App::new("app")
.arg("<opt> --foo <opt>")
.arg(arg!(opt: --foo <opt>))
.get_matches_from(&["test", "--foo==value"]);
assert_eq!("=value", matches.value_of("opt").unwrap());

View file

@ -1,12 +1,9 @@
use clap::{App, Arg, ErrorKind};
use clap::{arg, App, Arg, ErrorKind};
#[test]
fn only_pos_follow() {
let r = App::new("onlypos")
.args(&[
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg] 'some arg'"),
])
.args(&[arg!(f: -f [flag] "some opt"), arg!([arg] "some arg")])
.try_get_matches_from(vec!["", "--", "-f"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -19,7 +16,7 @@ fn only_pos_follow() {
fn issue_946() {
let r = App::new("compiletest")
.setting(clap::AppSettings::AllowLeadingHyphen)
.arg("--exact 'filters match exactly'")
.arg(arg!(--exact "filters match exactly"))
.arg(
clap::Arg::new("filter")
.index(1)
@ -37,10 +34,7 @@ fn issue_946() {
#[test]
fn positional() {
let r = App::new("positional")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::new("positional").index(1),
])
.args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
.try_get_matches_from(vec!["", "-f", "test"]);
assert!(r.is_ok(), "{:#?}", r);
let m = r.unwrap();
@ -49,10 +43,7 @@ fn positional() {
assert_eq!(m.value_of("positional").unwrap(), "test");
let m = App::new("positional")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::new("positional").index(1),
])
.args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
.get_matches_from(vec!["", "test", "--flag"]);
assert!(m.is_present("positional"));
assert!(m.is_present("flag"));
@ -62,7 +53,7 @@ fn positional() {
#[test]
fn lots_o_vals() {
let r = App::new("opts")
.arg(Arg::from("[opt]... 'some pos'"))
.arg(arg!(<opt>... "some pos"))
.try_get_matches_from(vec![
"", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
"some", "some", "some", "some", "some", "some", "some", "some", "some", "some", "some",
@ -103,7 +94,7 @@ fn lots_o_vals() {
fn positional_multiple() {
let r = App::new("positional_multiple")
.args(&[
Arg::from("-f, --flag 'some flag'"),
arg!(-f --flag "some flag"),
Arg::new("positional")
.index(1)
.takes_value(true)
@ -124,7 +115,7 @@ fn positional_multiple() {
fn positional_multiple_3() {
let r = App::new("positional_multiple")
.args(&[
Arg::from("-f, --flag 'some flag'"),
arg!(-f --flag "some flag"),
Arg::new("positional")
.index(1)
.takes_value(true)
@ -144,10 +135,7 @@ fn positional_multiple_3() {
#[test]
fn positional_multiple_2() {
let result = App::new("positional_multiple")
.args(&[
Arg::from("-f, --flag 'some flag'"),
Arg::new("positional").index(1),
])
.args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
.try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -158,7 +146,7 @@ fn positional_multiple_2() {
fn positional_possible_values() {
let r = App::new("positional_possible_values")
.args(&[
Arg::from("-f, --flag 'some flag'"),
arg!(-f --flag "some flag"),
Arg::new("positional").index(1).possible_value("test123"),
])
.try_get_matches_from(vec!["", "-f", "test123"]);
@ -188,35 +176,35 @@ fn positional_hyphen_does_not_panic() {
#[test]
fn single_positional_usage_string() {
let mut app = App::new("test").arg("[FILE] 'some file'");
let mut app = App::new("test").arg(arg!([FILE] "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test [FILE]");
}
#[test]
fn single_positional_multiple_usage_string() {
let mut app = App::new("test").arg("[FILE]... 'some file'");
let mut app = App::new("test").arg(arg!([FILE]... "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test [FILE]...");
}
#[test]
fn multiple_positional_usage_string() {
let mut app = App::new("test")
.arg("[FILE] 'some file'")
.arg("[FILES]... 'some file'");
.arg(arg!([FILE] "some file"))
.arg(arg!([FILES]... "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test [ARGS]");
}
#[test]
fn multiple_positional_one_required_usage_string() {
let mut app = App::new("test")
.arg("<FILE> 'some file'")
.arg("[FILES]... 'some file'");
.arg(arg!(<FILE> "some file"))
.arg(arg!([FILES]... "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test <FILE> [FILES]...");
}
#[test]
fn single_positional_required_usage_string() {
let mut app = App::new("test").arg("<FILE> 'some file'");
let mut app = App::new("test").arg(arg!(<FILE> "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test <FILE>");
}
@ -227,16 +215,16 @@ fn single_positional_required_usage_string() {
with a lower index than a required positional argument"]
fn missing_required() {
let _ = App::new("test")
.arg("[FILE1] 'some file'")
.arg("<FILE2> 'some file'")
.arg(arg!([FILE1] "some file"))
.arg(arg!(<FILE2> "some file"))
.try_get_matches_from(vec![""]);
}
#[test]
fn missing_required_2() {
let r = App::new("test")
.arg("<FILE1> 'some file'")
.arg("<FILE2> 'some file'")
.arg(arg!(<FILE1> "some file"))
.arg(arg!(<FILE2> "some file"))
.try_get_matches_from(vec!["test", "file"]);
assert!(r.is_err());
assert_eq!(r.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
@ -245,9 +233,9 @@ fn missing_required_2() {
#[test]
fn last_positional() {
let r = App::new("test")
.arg("<TARGET> 'some target'")
.arg("[CORPUS] 'some corpus'")
.arg(Arg::from("[ARGS]... 'some file'").last(true))
.arg(arg!(<TARGET> "some target"))
.arg(arg!([CORPUS] "some corpus"))
.arg(arg!([ARGS]... "some file").last(true))
.try_get_matches_from(vec!["test", "tgt", "--", "arg"]);
assert!(r.is_ok());
let m = r.unwrap();
@ -257,9 +245,9 @@ fn last_positional() {
#[test]
fn last_positional_no_double_dash() {
let r = App::new("test")
.arg("<TARGET> 'some target'")
.arg("[CORPUS] 'some corpus'")
.arg(Arg::from("[ARGS]... 'some file'").last(true))
.arg(arg!(<TARGET> "some target"))
.arg(arg!([CORPUS] "some corpus"))
.arg(arg!([ARGS]... "some file").last(true))
.try_get_matches_from(vec!["test", "tgt", "crp", "arg"]);
assert!(r.is_err());
assert_eq!(r.unwrap_err().kind, ErrorKind::UnknownArgument);
@ -268,9 +256,9 @@ fn last_positional_no_double_dash() {
#[test]
fn last_positional_second_to_last_mult() {
let r = App::new("test")
.arg("<TARGET> 'some target'")
.arg("[CORPUS]... 'some corpus'")
.arg(Arg::from("[ARGS]... 'some file'").last(true))
.arg(arg!(<TARGET> "some target"))
.arg(arg!([CORPUS]... "some corpus"))
.arg(arg!([ARGS]... "some file").last(true))
.try_get_matches_from(vec!["test", "tgt", "crp1", "crp2", "--", "arg"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind);
}

View file

@ -1,9 +1,13 @@
use clap::{App, Arg, ErrorKind};
use clap::{arg, App, Arg, ErrorKind};
#[test]
fn flag_overrides_itself() {
let res = App::new("posix")
.arg(Arg::from("--flag 'some flag'").overrides_with("flag"))
.arg(
arg!(--flag "some flag"
)
.overrides_with("flag"),
)
.try_get_matches_from(vec!["", "--flag", "--flag"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -14,7 +18,7 @@ fn flag_overrides_itself() {
#[test]
fn mult_flag_overrides_itself() {
let res = App::new("posix")
.arg(Arg::from("--flag... 'some flag'").overrides_with("flag"))
.arg(arg!(--flag ... "some flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -25,7 +29,11 @@ fn mult_flag_overrides_itself() {
#[test]
fn option_overrides_itself() {
let res = App::new("posix")
.arg(Arg::from("--opt [val] 'some option'").overrides_with("opt"))
.arg(
arg!(--opt <val> "some option")
.required(false)
.overrides_with("opt"),
)
.try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -38,7 +46,8 @@ fn option_overrides_itself() {
fn mult_option_require_delim_overrides_itself() {
let res = App::new("posix")
.arg(
Arg::from("[opt]... --opt [val]... 'some option'")
arg!(--opt <val> ... "some option")
.required(false)
.overrides_with("opt")
.number_of_values(1)
.takes_value(true)
@ -59,7 +68,12 @@ fn mult_option_require_delim_overrides_itself() {
#[test]
fn mult_option_overrides_itself() {
let res = App::new("posix")
.arg(Arg::from("[opt]... --opt [val]... 'some option'").overrides_with("opt"))
.arg(
arg!(--opt <val> ... "some option")
.required(false)
.multiple_values(true)
.overrides_with("opt"),
)
.try_get_matches_from(vec![
"",
"--opt",
@ -83,7 +97,11 @@ fn mult_option_overrides_itself() {
#[test]
fn option_use_delim_false_override_itself() {
let m = App::new("posix")
.arg(Arg::from("--opt [val] 'some option'").overrides_with("opt"))
.arg(
arg!(--opt <val> "some option")
.required(false)
.overrides_with("opt"),
)
.get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]);
assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 1);
@ -97,7 +115,7 @@ fn option_use_delim_false_override_itself() {
fn pos_mult_overrides_itself() {
// opts with multiple
let res = App::new("posix")
.arg(Arg::from("[val]... 'some pos'").overrides_with("val"))
.arg(arg!([val] ... "some pos").overrides_with("val"))
.try_get_matches_from(vec!["", "some", "other", "value"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -111,8 +129,8 @@ fn pos_mult_overrides_itself() {
#[test]
fn posix_compatible_flags_long() {
let m = App::new("posix")
.arg(Arg::from("--flag 'some flag'").overrides_with("color"))
.arg(Arg::from("--color 'some other flag'"))
.arg(arg!(--flag "some flag").overrides_with("color"))
.arg(arg!(--color "some other flag"))
.get_matches_from(vec!["", "--flag", "--color"]);
assert!(m.is_present("color"));
assert!(!m.is_present("flag"));
@ -121,8 +139,8 @@ fn posix_compatible_flags_long() {
#[test]
fn posix_compatible_flags_long_rev() {
let m = App::new("posix")
.arg(Arg::from("--flag 'some flag'").overrides_with("color"))
.arg(Arg::from("--color 'some other flag'"))
.arg(arg!(--flag "some flag").overrides_with("color"))
.arg(arg!(--color "some other flag"))
.get_matches_from(vec!["", "--color", "--flag"]);
assert!(!m.is_present("color"));
assert!(m.is_present("flag"));
@ -131,8 +149,8 @@ fn posix_compatible_flags_long_rev() {
#[test]
fn posix_compatible_flags_short() {
let m = App::new("posix")
.arg(Arg::from("-f, --flag 'some flag'").overrides_with("color"))
.arg(Arg::from("-c, --color 'some other flag'"))
.arg(arg!(-f --flag "some flag").overrides_with("color"))
.arg(arg!(-c --color "some other flag"))
.get_matches_from(vec!["", "-f", "-c"]);
assert!(m.is_present("color"));
assert!(!m.is_present("flag"));
@ -141,8 +159,8 @@ fn posix_compatible_flags_short() {
#[test]
fn posix_compatible_flags_short_rev() {
let m = App::new("posix")
.arg(Arg::from("-f, --flag 'some flag'").overrides_with("color"))
.arg(Arg::from("-c, --color 'some other flag'"))
.arg(arg!(-f --flag "some flag").overrides_with("color"))
.arg(arg!(-c --color "some other flag"))
.get_matches_from(vec!["", "-c", "-f"]);
assert!(!m.is_present("color"));
assert!(m.is_present("flag"));
@ -151,8 +169,12 @@ fn posix_compatible_flags_short_rev() {
#[test]
fn posix_compatible_opts_long() {
let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color"))
.arg(Arg::from("--color [color] 'some other flag'"))
.arg(
arg!(--flag <flag> "some flag")
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
assert!(m.is_present("color"));
assert_eq!(m.value_of("color").unwrap(), "other");
@ -162,8 +184,12 @@ fn posix_compatible_opts_long() {
#[test]
fn posix_compatible_opts_long_rev() {
let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color"))
.arg(Arg::from("--color [color] 'some other flag'"))
.arg(
arg!(--flag <flag> "some flag")
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.get_matches_from(vec!["", "--color", "some", "--flag", "other"]);
assert!(!m.is_present("color"));
assert!(m.is_present("flag"));
@ -173,8 +199,12 @@ fn posix_compatible_opts_long_rev() {
#[test]
fn posix_compatible_opts_long_equals() {
let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color"))
.arg(Arg::from("--color [color] 'some other flag'"))
.arg(
arg!(--flag <flag> "some flag")
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.get_matches_from(vec!["", "--flag=some", "--color=other"]);
assert!(m.is_present("color"));
assert_eq!(m.value_of("color").unwrap(), "other");
@ -184,8 +214,12 @@ fn posix_compatible_opts_long_equals() {
#[test]
fn posix_compatible_opts_long_equals_rev() {
let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color"))
.arg(Arg::from("--color [color] 'some other flag'"))
.arg(
arg!(--flag <flag> "some flag")
.required(false)
.overrides_with("color"),
)
.arg(arg!(--color <color> "some other flag").required(false))
.get_matches_from(vec!["", "--color=some", "--flag=other"]);
assert!(!m.is_present("color"));
assert!(m.is_present("flag"));
@ -195,8 +229,12 @@ fn posix_compatible_opts_long_equals_rev() {
#[test]
fn posix_compatible_opts_short() {
let m = App::new("posix")
.arg(Arg::from("-f [flag] 'some flag'").overrides_with("c"))
.arg(Arg::from("-c [color] 'some other flag'"))
.arg(
arg!(f: -f <flag> "some flag")
.required(false)
.overrides_with("c"),
)
.arg(arg!(c: -c <color> "some other flag").required(false))
.get_matches_from(vec!["", "-f", "some", "-c", "other"]);
assert!(m.is_present("c"));
assert_eq!(m.value_of("c").unwrap(), "other");
@ -206,8 +244,12 @@ fn posix_compatible_opts_short() {
#[test]
fn posix_compatible_opts_short_rev() {
let m = App::new("posix")
.arg(Arg::from("-f [flag] 'some flag'").overrides_with("c"))
.arg(Arg::from("-c [color] 'some other flag'"))
.arg(
arg!(f: -f <flag> "some flag")
.required(false)
.overrides_with("c"),
)
.arg(arg!(c: -c <color> "some other flag").required(false))
.get_matches_from(vec!["", "-c", "some", "-f", "other"]);
assert!(!m.is_present("c"));
assert!(m.is_present("f"));
@ -217,9 +259,9 @@ fn posix_compatible_opts_short_rev() {
#[test]
fn conflict_overridden() {
let m = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag"))
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(arg!(-d --debug "other flag"))
.arg(arg!(-c --color "third flag").overrides_with("flag"))
.get_matches_from(vec!["", "-f", "-c", "-d"]);
assert!(m.is_present("color"));
assert!(!m.is_present("flag"));
@ -229,9 +271,9 @@ fn conflict_overridden() {
#[test]
fn conflict_overridden_2() {
let result = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag"))
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(arg!(-d --debug "other flag"))
.arg(arg!(-c --color "third flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "-f", "-d", "-c"]);
assert!(result.is_ok());
let m = result.unwrap();
@ -243,9 +285,9 @@ fn conflict_overridden_2() {
#[test]
fn conflict_overridden_3() {
let result = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag"))
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(arg!(-d --debug "other flag"))
.arg(arg!(-c --color "third flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "-d", "-c", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -255,9 +297,9 @@ fn conflict_overridden_3() {
#[test]
fn conflict_overridden_4() {
let m = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag"))
.arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(arg!(-d --debug "other flag"))
.arg(arg!(-c --color "third flag").overrides_with("flag"))
.get_matches_from(vec!["", "-d", "-f", "-c"]);
assert!(m.is_present("color"));
assert!(!m.is_present("flag"));
@ -268,7 +310,7 @@ fn conflict_overridden_4() {
fn pos_required_overridden_by_flag() {
let result = App::new("require_overridden")
.arg(Arg::new("pos").index(1).required(true))
.arg(Arg::from("-c, --color 'some flag'").overrides_with("pos"))
.arg(arg!(-c --color "some flag").overrides_with("pos"))
.try_get_matches_from(vec!["", "test", "-c"]);
assert!(result.is_ok(), "{:?}", result.unwrap_err());
}
@ -277,7 +319,7 @@ fn pos_required_overridden_by_flag() {
fn require_overridden_2() {
let m = App::new("require_overridden")
.arg(Arg::new("req_pos").required(true))
.arg(Arg::from("-c, --color 'other flag'").overrides_with("req_pos"))
.arg(arg!(-c --color "other flag").overrides_with("req_pos"))
.get_matches_from(vec!["", "-c", "req_pos"]);
assert!(!m.is_present("color"));
assert!(m.is_present("req_pos"));
@ -286,9 +328,9 @@ fn require_overridden_2() {
#[test]
fn require_overridden_3() {
let m = App::new("require_overridden")
.arg(Arg::from("-f, --flag 'some flag'").requires("debug"))
.arg(Arg::from("-d, --debug 'other flag'"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag"))
.arg(arg!(-f --flag "some flag").requires("debug"))
.arg(arg!(-d --debug "other flag"))
.arg(arg!(-c --color "third flag").overrides_with("flag"))
.get_matches_from(vec!["", "-f", "-c"]);
assert!(m.is_present("color"));
assert!(!m.is_present("flag"));
@ -298,9 +340,9 @@ fn require_overridden_3() {
#[test]
fn require_overridden_4() {
let result = App::new("require_overridden")
.arg(Arg::from("-f, --flag 'some flag'").requires("debug"))
.arg(Arg::from("-d, --debug 'other flag'"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag"))
.arg(arg!(-f --flag "some flag").requires("debug"))
.arg(arg!(-d --debug "other flag"))
.arg(arg!(-c --color "third flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "-c", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, Arg, ArgGroup, ErrorKind};
use clap::{arg, App, Arg, ArgGroup, ErrorKind};
static REQUIRE_EQUALS: &str = "error: The following required arguments were not provided:
--opt=<FILE>
@ -52,8 +52,8 @@ For more information try --help
#[test]
fn flag_required() {
let result = App::new("flag_required")
.arg(Arg::from("-f, --flag 'some flag'").requires("color"))
.arg(Arg::from("-c, --color 'third flag'"))
.arg(arg!(-f --flag "some flag").requires("color"))
.arg(arg!(-c --color "third flag"))
.try_get_matches_from(vec!["", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -63,8 +63,8 @@ fn flag_required() {
#[test]
fn flag_required_2() {
let m = App::new("flag_required")
.arg(Arg::from("-f, --flag 'some flag'").requires("color"))
.arg(Arg::from("-c, --color 'third flag'"))
.arg(arg!(-f --flag "some flag").requires("color"))
.arg(arg!(-c --color "third flag"))
.get_matches_from(vec!["", "-f", "-c"]);
assert!(m.is_present("color"));
assert!(m.is_present("flag"));
@ -73,8 +73,8 @@ fn flag_required_2() {
#[test]
fn option_required() {
let result = App::new("option_required")
.arg(Arg::from("-f [flag] 'some flag'").requires("c"))
.arg(Arg::from("-c [color] 'third flag'"))
.arg(arg!(f: -f <flag> "some flag").required(false).requires("c"))
.arg(arg!(c: -c <color> "third flag").required(false))
.try_get_matches_from(vec!["", "-f", "val"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -84,8 +84,8 @@ fn option_required() {
#[test]
fn option_required_2() {
let m = App::new("option_required")
.arg(Arg::from("-f [flag] 'some flag'").requires("c"))
.arg(Arg::from("-c [color] 'third flag'"))
.arg(arg!(f: -f <flag> "some flag").required(false).requires("c"))
.arg(arg!(c: -c <color> "third flag").required(false))
.get_matches_from(vec!["", "-f", "val", "-c", "other_val"]);
assert!(m.is_present("c"));
assert_eq!(m.value_of("c").unwrap(), "other_val");
@ -115,10 +115,10 @@ fn positional_required_2() {
#[test]
fn group_required() {
let result = App::new("group_required")
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(arg!(-f --flag "some flag"))
.group(ArgGroup::new("gr").required(true).arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.try_get_matches_from(vec!["", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -128,10 +128,10 @@ fn group_required() {
#[test]
fn group_required_2() {
let m = App::new("group_required")
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(arg!(-f --flag "some flag"))
.group(ArgGroup::new("gr").required(true).arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.get_matches_from(vec!["", "-f", "--some"]);
assert!(m.is_present("some"));
assert!(!m.is_present("other"));
@ -141,10 +141,10 @@ fn group_required_2() {
#[test]
fn group_required_3() {
let m = App::new("group_required")
.arg(Arg::from("-f, --flag 'some flag'"))
.arg(arg!(-f --flag "some flag"))
.group(ArgGroup::new("gr").required(true).arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.get_matches_from(vec!["", "-f", "--other"]);
assert!(!m.is_present("some"));
assert!(m.is_present("other"));
@ -154,10 +154,10 @@ fn group_required_3() {
#[test]
fn arg_require_group() {
let result = App::new("arg_require_group")
.arg(Arg::from("-f, --flag 'some flag'").requires("gr"))
.arg(arg!(-f --flag "some flag").requires("gr"))
.group(ArgGroup::new("gr").arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.try_get_matches_from(vec!["", "-f"]);
assert!(result.is_err());
let err = result.err().unwrap();
@ -167,10 +167,10 @@ fn arg_require_group() {
#[test]
fn arg_require_group_2() {
let res = App::new("arg_require_group")
.arg(Arg::from("-f, --flag 'some flag'").requires("gr"))
.arg(arg!(-f --flag "some flag").requires("gr"))
.group(ArgGroup::new("gr").arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.try_get_matches_from(vec!["", "-f", "--some"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -182,10 +182,10 @@ fn arg_require_group_2() {
#[test]
fn arg_require_group_3() {
let res = App::new("arg_require_group")
.arg(Arg::from("-f, --flag 'some flag'").requires("gr"))
.arg(arg!(-f --flag "some flag").requires("gr"))
.group(ArgGroup::new("gr").arg("some").arg("other"))
.arg(Arg::from("--some 'some arg'"))
.arg(Arg::from("--other 'other arg'"))
.arg(arg!(--some "some arg"))
.arg(arg!(--other "other arg"))
.try_get_matches_from(vec!["", "-f", "--other"]);
assert!(res.is_ok());
let m = res.unwrap();
@ -199,20 +199,25 @@ fn arg_require_group_3() {
#[test]
fn issue_753() {
let m = App::new("test")
.arg(Arg::from(
"-l, --list 'List available interfaces (and stop there)'",
.arg(arg!(
-l --list "List available interfaces (and stop there)"
))
.arg(
Arg::from("-i, --iface=[INTERFACE] 'Ethernet interface for fetching NTP packets'")
.required_unless_present("list"),
arg!(
-i --iface <INTERFACE> "Ethernet interface for fetching NTP packets"
)
.required(false)
.required_unless_present("list"),
)
.arg(
Arg::from("-f, --file=[TESTFILE] 'Fetch NTP packets from pcap file'")
arg!(-f --file <TESTFILE> "Fetch NTP packets from pcap file")
.required(false)
.conflicts_with("iface")
.required_unless_present("list"),
)
.arg(
Arg::from("-s, --server=[SERVER_IP] 'NTP server IP address'")
arg!(-s --server <SERVER_IP> "NTP server IP address")
.required(false)
.required_unless_present("list"),
)
.try_get_matches_from(vec!["test", "--list"]);
@ -925,19 +930,20 @@ For more information try --help
fn issue_1158_app() -> App<'static> {
App::new("example")
.arg(
Arg::from("-c, --config [FILE] 'Custom config file.'")
arg!(-c --config <FILE> "Custom config file.")
.required(false)
.required_unless_present("ID")
.conflicts_with("ID"),
)
.arg(
Arg::from("[ID] 'ID'")
arg!([ID] "ID")
.required_unless_present("config")
.conflicts_with("config")
.requires_all(&["x", "y", "z"]),
)
.arg(Arg::from("-x [X] 'X'"))
.arg(Arg::from("-y [Y] 'Y'"))
.arg(Arg::from("-z [Z] 'Z'"))
.arg(arg!(x: -x <X> "X").required(false))
.arg(arg!(y: -y <Y> "Y").required(false))
.arg(arg!(z: -z <Z> "Z").required(false))
}
#[test]

View file

@ -1,6 +1,6 @@
mod utils;
use clap::{App, AppSettings, Arg, ErrorKind};
use clap::{arg, App, AppSettings, Arg, ErrorKind};
static VISIBLE_ALIAS_HELP: &str = "clap-test 2.6
@ -251,8 +251,9 @@ USAGE:
For more information try --help
";
let app = App::new("dym")
.subcommand(App::new("subcmd").arg(Arg::from("-s --subcmdarg [subcmdarg] 'tests'")));
let app = App::new("dym").subcommand(
App::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)),
);
assert!(utils::compare_output(
app,
@ -276,8 +277,9 @@ USAGE:
For more information try --help
";
let app = App::new("dym")
.subcommand(App::new("subcmd").arg(Arg::from("-s --subcmdarg [subcmdarg] 'tests'")));
let app = App::new("dym").subcommand(
App::new("subcmd").arg(arg!(-s --subcmdarg <subcmdarg> "tests").required(false)),
);
assert!(utils::compare_output(
app,
@ -344,7 +346,7 @@ fn replace() {
#[test]
fn issue_1031_args_with_same_name() {
let res = App::new("prog")
.arg(Arg::from("--ui-path=<PATH>"))
.arg(arg!(--"ui-path" <PATH>))
.subcommand(App::new("signer"))
.try_get_matches_from(vec!["prog", "--ui-path", "signer"]);
@ -356,7 +358,7 @@ fn issue_1031_args_with_same_name() {
#[test]
fn issue_1031_args_with_same_name_no_more_vals() {
let res = App::new("prog")
.arg(Arg::from("--ui-path=<PATH>"))
.arg(arg!(--"ui-path" <PATH>))
.subcommand(App::new("signer"))
.try_get_matches_from(vec!["prog", "--ui-path", "value", "signer"]);

View file

@ -1,6 +1,6 @@
mod utils;
use clap::App;
use clap::{arg, App};
static EXAMPLE1_TMPL_S: &str = "{bin} {version}
{author}
@ -149,12 +149,21 @@ fn get_app() -> App<'static> {
.version("1.0")
.author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'")
.arg("<output> 'Sets an optional output file'")
.arg("-d... 'Turn debugging information on'")
.arg(
arg!(
-c --config <FILE> "Sets a custom config file"
)
.required(false),
)
.arg(arg!(
<output> "Sets an optional output file"
))
.arg(arg!(
d: -d ... "Turn debugging information on"
))
.subcommand(
App::new("test")
.about("does testing things")
.arg("-l, --list 'lists test values'"),
.arg(arg!(-l --list "lists test values")),
)
}

View file

@ -4,7 +4,7 @@
#![cfg(windows)]
use clap::{App, Arg};
use clap::{arg, App};
use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt;
@ -23,7 +23,7 @@ fn bad_osstring(ascii: &[u8]) -> OsString {
#[test]
fn invalid_utf16_lossy_positional() {
let r = App::new("bad_utf16")
.arg(Arg::from("<arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(<arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -34,7 +34,7 @@ fn invalid_utf16_lossy_positional() {
#[test]
fn invalid_utf16_lossy_option_short_space() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![
OsString::from(""),
OsString::from("-a"),
@ -49,7 +49,7 @@ fn invalid_utf16_lossy_option_short_space() {
#[test]
fn invalid_utf16_lossy_option_short_equals() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -60,7 +60,7 @@ fn invalid_utf16_lossy_option_short_equals() {
#[test]
fn invalid_utf16_lossy_option_short_no_space() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -71,7 +71,7 @@ fn invalid_utf16_lossy_option_short_no_space() {
#[test]
fn invalid_utf16_lossy_option_long_space() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![
OsString::from(""),
OsString::from("--arg"),
@ -86,7 +86,7 @@ fn invalid_utf16_lossy_option_long_space() {
#[test]
fn invalid_utf16_lossy_option_long_equals() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -97,7 +97,7 @@ fn invalid_utf16_lossy_option_long_equals() {
#[test]
fn invalid_utf16_positional() {
let r = App::new("bad_utf16")
.arg(Arg::from("<arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(<arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -108,7 +108,7 @@ fn invalid_utf16_positional() {
#[test]
fn invalid_utf16_option_short_space() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![
OsString::from(""),
OsString::from("-a"),
@ -123,7 +123,7 @@ fn invalid_utf16_option_short_space() {
#[test]
fn invalid_utf16_option_short_equals() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -134,7 +134,7 @@ fn invalid_utf16_option_short_equals() {
#[test]
fn invalid_utf16_option_short_no_space() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
assert!(r.is_ok());
let m = r.unwrap();
@ -145,7 +145,7 @@ fn invalid_utf16_option_short_no_space() {
#[test]
fn invalid_utf16_option_long_space() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![
OsString::from(""),
OsString::from("--arg"),
@ -160,7 +160,7 @@ fn invalid_utf16_option_long_space() {
#[test]
fn invalid_utf16_option_long_equals() {
let r = App::new("bad_utf16")
.arg(Arg::from("-a, --arg <arg> 'some arg'").allow_invalid_utf8(true))
.arg(arg!(-a --arg <arg> "some arg").allow_invalid_utf8(true))
.try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
assert!(r.is_ok());
let m = r.unwrap();

View file

@ -5,7 +5,7 @@ use std::str;
use regex::Regex;
use clap::{App, Arg, ArgGroup};
use clap::{arg, App, Arg, ArgGroup};
pub fn compare<S, S2>(l: S, r: S2) -> bool
where
@ -59,31 +59,53 @@ pub fn complex_app() -> App<'static> {
.version("v1.4.8")
.about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>")
.arg("[option]... -o --option=[opt]... 'tests options'")
.arg("[positional] 'tests positionals'")
.arg(Arg::from("-f --flag... 'tests flags'").global(true))
.arg(
arg!(
-o --option <opt> "tests options"
)
.required(false)
.multiple_values(true)
.multiple_occurrences(true),
)
.arg(arg!([positional] "tests positionals"))
.arg(arg!(-f --flag ... "tests flags").global(true))
.args(&[
Arg::from("[flag2] -F 'tests flags with exclusions'")
arg!(flag2: -F "tests flags with exclusions")
.conflicts_with("flag")
.requires("long-option-2"),
Arg::from("--long-option-2 [option2] 'tests long options with exclusions'")
arg!(--"long-option-2" <option2> "tests long options with exclusions")
.required(false)
.conflicts_with("option")
.requires("positional2"),
Arg::from("[positional2] 'tests positionals with exclusions'"),
Arg::from("-O --option3 [option3] 'specific vals'").possible_values(opt3_vals),
Arg::from("[positional3]... 'tests specific values'").possible_values(pos3_vals),
Arg::from("--multvals [one] [two] 'Tests multiple values, not mult occs'"),
Arg::from("--multvalsmo... [one] [two] 'Tests multiple values, and mult occs'"),
Arg::from("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2),
Arg::from("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3),
arg!([positional2] "tests positionals with exclusions"),
arg!(-O --option3 <option3> "specific vals")
.required(false)
.possible_values(opt3_vals),
arg!([positional3] ... "tests specific values").possible_values(pos3_vals),
arg!(--multvals "Tests multiple values, not mult occs")
.value_names(&["one", "two"])
.required(false),
arg!(--multvalsmo ... "Tests multiple values, and mult occs")
.value_names(&["one", "two"])
.required(false),
arg!(--minvals2 <minvals> "Tests 2 min vals")
.required(false)
.min_values(2),
arg!(--maxvals3 <maxvals> "Tests 3 max vals")
.required(false)
.max_values(3),
])
.subcommand(
App::new("subcmd")
.about("tests subcommands")
.version("0.1")
.author("Kevin K. <kbknapp@gmail.com>")
.arg("[option]... -o --option [scoption]... 'tests options'")
.arg("-s --subcmdarg [subcmdarg] 'tests other args'")
.arg("[scpositional] 'tests positionals'"),
.arg(
arg!(-o --option <scoption> "tests options")
.required(false)
.multiple_values(true),
)
.arg(arg!(-s --subcmdarg <subcmdarg> "tests other args").required(false))
.arg(arg!([scpositional] "tests positionals")),
)
}

View file

@ -1,24 +1,25 @@
#![cfg(feature = "yaml")]
#![allow(deprecated)]
use clap::{load_yaml, App, Arg, ErrorKind, ValueHint};
#[test]
fn create_app_from_yaml() {
let yaml = load_yaml!("fixtures/app.yaml");
let _ = App::from(yaml);
let _ = App::from_yaml(yaml);
}
// TODO: Uncomment to test yaml with 2 spaces https://github.com/chyh1990/yaml-rust/issues/101
// #[test]
// fn create_app_from_yaml_2spaces() {
// let yaml = load_yaml!("fixtures/app_2space.yaml");
// App::from(yaml);
// App::from_yaml(yaml);
// }
#[test]
fn help_message() {
let yaml = load_yaml!("fixtures/app.yaml");
let mut app = App::from(yaml);
let mut app = App::from_yaml(yaml);
// Generate the full help message!
let _ = app.try_get_matches_from_mut(Vec::<String>::new());
@ -33,7 +34,7 @@ fn help_message() {
#[test]
fn author() {
let yaml = load_yaml!("fixtures/app.yaml");
let mut app = App::from(yaml);
let mut app = App::from_yaml(yaml);
// Generate the full help message!
let _ = app.try_get_matches_from_mut(Vec::<String>::new());
@ -46,7 +47,7 @@ fn author() {
#[test]
fn app_settings() {
let yaml = load_yaml!("fixtures/app.yaml");
let app = App::from(yaml);
let app = App::from_yaml(yaml);
let m = app.try_get_matches_from(vec!["prog"]);
@ -61,21 +62,21 @@ fn app_settings() {
#[should_panic = "Unknown AppSetting 'random' found in YAML file for app"]
fn app_setting_invalid() {
let yaml = load_yaml!("fixtures/app_setting_invalid.yaml");
let _ = App::from(yaml);
let _ = App::from_yaml(yaml);
}
#[test]
#[should_panic = "Unknown ArgSetting 'random' found in YAML file for arg 'option'"]
fn arg_setting_invalid() {
let yaml = load_yaml!("fixtures/arg_setting_invalid.yaml");
let _ = App::from(yaml);
let _ = App::from_yaml(yaml);
}
// ValueHint must be parsed correctly from Yaml
#[test]
fn value_hint() {
let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
let arg = app
.get_arguments()
@ -87,7 +88,7 @@ fn value_hint() {
#[test]
fn default_value_if_not_triggered_by_argument() {
let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
// Fixtures use "other" as value
let matches = app.try_get_matches_from(vec!["prog", "wrong"]).unwrap();
@ -98,7 +99,7 @@ fn default_value_if_not_triggered_by_argument() {
#[test]
fn default_value_if_triggered_by_matching_argument() {
let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
let matches = app.try_get_matches_from(vec!["prog", "other"]).unwrap();
assert_eq!(matches.value_of("positional2").unwrap(), "something");
@ -107,7 +108,7 @@ fn default_value_if_triggered_by_matching_argument() {
#[test]
fn default_value_if_triggered_by_flag() {
let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
let matches = app
.try_get_matches_from(vec!["prog", "--flag", "flagvalue"])
@ -119,7 +120,7 @@ fn default_value_if_triggered_by_flag() {
#[test]
fn default_value_if_triggered_by_flag_and_argument() {
let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
let matches = app
.try_get_matches_from(vec!["prog", "--flag", "flagvalue", "other"])
@ -132,7 +133,7 @@ fn default_value_if_triggered_by_flag_and_argument() {
#[test]
fn yaml_multiple_occurrences() {
let yaml = load_yaml!("fixtures/app.yaml");
let matches = App::from(yaml)
let matches = App::from_yaml(yaml)
.try_get_matches_from(vec!["prog", "-vvv"])
.unwrap();
assert_eq!(matches.occurrences_of("verbose"), 3);
@ -141,7 +142,7 @@ fn yaml_multiple_occurrences() {
#[test]
fn yaml_multiple_values() {
let yaml = load_yaml!("fixtures/app.yaml");
let matches = App::from(yaml)
let matches = App::from_yaml(yaml)
.try_get_matches_from(vec!["prog", "-s", "aaa", "bbb"])
.unwrap();
assert_eq!(
@ -157,7 +158,7 @@ fn yaml_multiple_values() {
#[test]
fn regex_with_invalid_string() {
let yml = load_yaml!("fixtures/app_regex.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
let res = app.try_get_matches_from(vec!["prog", "not a proper filter"]);
assert!(res.is_err());
@ -167,7 +168,7 @@ fn regex_with_invalid_string() {
#[test]
fn regex_with_valid_string() {
let yml = load_yaml!("fixtures/app_regex.yaml");
let app = App::from(yml);
let app = App::from_yaml(yml);
let matches = app.try_get_matches_from(vec!["prog", "*.txt"]).unwrap();
@ -179,89 +180,89 @@ fn regex_with_valid_string() {
#[should_panic]
fn regex_with_invalid_yaml() {
let yml = load_yaml!("fixtures/app_regex_invalid.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
fn extra_fields() {
let yml = load_yaml!("fixtures/extra_fields.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "Unknown setting 'random' in YAML file for arg 'option'"]
fn extra_fields_invalid_arg() {
let yml = load_yaml!("fixtures/extra_fields_invalid_arg.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "Unknown setting 'random' in YAML file for subcommand 'info'"]
fn extra_fields_invalid_app() {
let yml = load_yaml!("fixtures/extra_fields_invalid_app.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "YAML file must be a hash"]
fn app_not_hash() {
let yml = load_yaml!("fixtures/not_hash.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "YAML file must be a hash"]
fn arg_file_not_hash() {
let yml = load_yaml!("fixtures/not_hash.yaml");
let _ = Arg::from(yml);
let _ = Arg::from_yaml(yml);
}
#[test]
#[should_panic = "Subcommand must be a hash"]
fn subcommand_not_hash() {
let yml = load_yaml!("fixtures/field_not_hash.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "Arg must be a hash"]
fn arg_not_hash() {
let yml = load_yaml!("fixtures/arg_not_hash.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "Subcommand name must be a string"]
fn subcommand_name_not_string() {
let yml = load_yaml!("fixtures/name_not_string.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "Arg name must be a string"]
fn arg_name_not_string() {
let yml = load_yaml!("fixtures/name_not_string.yaml");
let _ = Arg::from(yml);
let _ = Arg::from_yaml(yml);
}
#[test]
#[should_panic = "App fields must be strings"]
fn app_field_not_string() {
let yml = load_yaml!("fixtures/app_field_not_string.yaml");
let _ = App::from(yml);
let _ = App::from_yaml(yml);
}
#[test]
#[should_panic = "Arg fields must be strings"]
fn arg_field_not_string() {
let yml = load_yaml!("fixtures/arg_field_not_string.yaml");
let _ = Arg::from(yml);
let _ = Arg::from_yaml(yml);
}
#[test]
fn multiple_groups() {
let yml = load_yaml!("fixtures/multiple_groups.yaml");
let matches = App::from(yml).try_get_matches_from(&["app", "-a", "-c"]);
let matches = App::from_yaml(yml).try_get_matches_from(&["app", "-a", "-c"]);
eprintln!("{:?}", matches);
assert!(matches.is_ok());
}