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 * Derive Macros
* Builder Pattern * Builder Pattern
* Yaml
To build an `Arg` there are four: To build an `Arg` there are four:
* Derive Macros * Derive Macros
* Builder Pattern * Builder Pattern
* Usage Strings * Usage Strings
* Yaml
### Why is there a default subcommand of help? ### 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) 4. [Quick Example](#quick-example)
1. [Using Derive Macros](#using-derive-macros) 1. [Using Derive Macros](#using-derive-macros)
2. [Using Builder Pattern](#using-builder-pattern) 2. [Using Builder Pattern](#using-builder-pattern)
3. [Using YAML](#using-yaml) 3. [Running it](#running-it)
4. [Running it](#running-it)
5. [Try it!](#try-it) 5. [Try it!](#try-it)
1. [Pre-Built Test](#pre-built-test) 1. [Pre-Built Test](#pre-built-test)
2. [Build Your Own Binary](#build-your-own-binary) 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`) * **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 - 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 - 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 * **Requirement Rules**: Arguments can define the following types of requirement rules
- Can be required by default - Can be required by default
- Can be required only if certain arguments are present - 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 // This example demonstrates clap's "usage strings" method of creating arguments
// which is less verbose // which is less verbose
use clap::App; use clap::{App, arg};
fn main() { fn main() {
let matches = App::new("myapp") let matches = App::new("myapp")
.version("1.0") .version("1.0")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things") .about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'") .arg(arg!(-c --config <FILE> "Sets a custom config file").required(false))
.arg("<INPUT> 'Sets the input file to use'") .arg(arg!(<INPUT> "Sets the input file to use"))
.arg("-v... 'Sets the level of verbosity'") .arg(arg!(-v --verbose ... "Sets the level of verbosity"))
.subcommand(App::new("test") .subcommand(App::new("test")
.about("controls testing features") .about("controls testing features")
.version("1.3") .version("1.3")
.author("Someone E. <someone_else@other.com>") .author("Someone E. <someone_else@other.com>")
.arg("-d, --debug 'Print debug information'")) .arg(arg!(-d --debug "Print debug information")))
.get_matches(); .get_matches();
// Same as previous example... // 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 #### 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). 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}; use criterion::{criterion_group, criterion_main, Criterion};
macro_rules! create_app { macro_rules! create_app {
@ -7,9 +7,9 @@ macro_rules! create_app {
.version("0.1") .version("0.1")
.about("tests clap library") .about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg("-f --flag 'tests flags'") .arg(arg!(-f --flag "tests flags"))
.arg("-o --option=[opt] 'tests options'") .arg(arg!(-o --option <opt> "tests options").required(false))
.arg("[positional] 'tests positional'") .arg(arg!([positional] "tests positional"))
}}; }};
} }
@ -19,14 +19,14 @@ pub fn build_simple(c: &mut Criterion) {
pub fn build_with_flag(c: &mut Criterion) { pub fn build_with_flag(c: &mut Criterion) {
c.bench_function("build_with_flag", |b| { 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) { pub fn build_with_flag_ref(c: &mut Criterion) {
c.bench_function("build_with_flag_ref", |b| { c.bench_function("build_with_flag_ref", |b| {
b.iter(|| { b.iter(|| {
let arg = Arg::from("-s, --some 'something'"); let arg = arg!(-s --some "something");
App::new("claptests").arg(&arg) 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) { pub fn build_with_opt(c: &mut Criterion) {
c.bench_function("build_with_opt", |b| { 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) { pub fn build_with_opt_ref(c: &mut Criterion) {
c.bench_function("build_with_opt_ref", |b| { c.bench_function("build_with_opt_ref", |b| {
b.iter(|| { b.iter(|| {
let arg = Arg::from("-s, --some <FILE> 'something'"); let arg = arg!(-s --some <FILE> "something");
App::new("claptests").arg(&arg) 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}; use criterion::{criterion_group, criterion_main, Criterion};
static OPT3_VALS: [&str; 2] = ["fast", "slow"]; static OPT3_VALS: [&str; 2] = ["fast", "slow"];
@ -10,43 +10,41 @@ macro_rules! create_app {
.version("0.1") .version("0.1")
.about("tests clap library") .about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg("-o --option=[opt]... 'tests options'") .arg(arg!(-o --option <opt> ... "tests options").required(false))
.arg("[positional] 'tests positionals'") .arg(arg!([positional] "tests positionals"))
.arg(Arg::from("-f --flag... 'tests flags'").global(true)) .arg(arg!(-f --flag ... "tests flags").global(true))
.args(&[ .args(&[
Arg::from("[flag2] -F 'tests flags with exclusions'") arg!(flag2: -F "tests flags with exclusions")
.conflicts_with("flag") .conflicts_with("flag")
.requires("option2"), .requires("option2"),
Arg::from( arg!(option2: --"long-option-2" <option2> "tests long options with exclusions")
"[option2] --long-option-2 [option2] 'tests long options with exclusions'", .required(false)
) .conflicts_with("option")
.conflicts_with("option") .requires("positional2"),
.requires("positional2"), arg!([positional2] "tests positionals with exclusions"),
Arg::from("[positional2] 'tests positionals with exclusions'"), arg!(-O --Option <option3> "tests options with specific value sets")
Arg::from("-O --Option [option3] 'tests options with specific value sets'") .required(false)
.possible_values(OPT3_VALS), .possible_values(OPT3_VALS),
Arg::from("[positional3]... 'tests positionals with specific values'") arg!([positional3] ... "tests positionals with specific values")
.possible_values(POS3_VALS), .possible_values(POS3_VALS),
Arg::from("--multvals [one] [two] 'Tests multiple values, not mult occs'"), arg!(--multvals "Tests multiple values not mult occs").required(false).value_names(&["one", "two"]),
Arg::from("--multvalsmo... [one] [two] 'Tests multiple values, not mult occs'"), arg!(
Arg::from("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2), --multvalsmo "Tests multiple values, not mult occs"
Arg::from("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3), ).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( .subcommand(
App::new("subcmd") App::new("subcmd")
.about("tests subcommands") .about("tests subcommands")
.version("0.1") .version("0.1")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg("-o --option [scoption]... 'tests options'") .arg(arg!(-o --option <scoption> ... "tests options").required(false))
.arg("[scpositional] 'tests positionals'"), .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) { pub fn build_from_builder(c: &mut Criterion) {
c.bench_function("build_from_builder", |b| { c.bench_function("build_from_builder", |b| {
b.iter(|| { b.iter(|| {
@ -291,7 +289,6 @@ pub fn parse_complex_with_sc_complex(c: &mut Criterion) {
criterion_group!( criterion_group!(
benches, benches,
build_from_usage,
build_from_builder, build_from_builder,
parse_complex, parse_complex,
parse_complex_with_flag, parse_complex_with_flag,

View file

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

View file

@ -1,4 +1,4 @@
use clap::App; use clap::{arg, App};
fn main() { fn main() {
// This example shows how to create an application with several arguments using usage strings, which can be // 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") .version("1.0")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things") .about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'") .arg(
.arg("[output] 'Sets an optional output file'") arg!(
.arg("-d..., --debug... 'Turn debugging information on'") -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( .subcommand(
App::new("test") App::new("test")
.about("does testing things") .about("does testing things")
.arg("-l, --list 'lists test values'"), .arg(arg!(-l --list "lists test values")),
) )
.get_matches(); .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 // 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. // 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() // You also set all the valid arguments your App should accept via the arg() and args()
// and args_from_usage() (as well as subcommands via the subcommand() and subcommands() methods) which // (as well as subcommands via the subcommand() and subcommands() methods) which
// will be covered later. // will be covered later.
// //
// Once all options have been set, call one of the .get_matches* family of methods in order to // 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() { fn main() {
// Args describe a possible valid argument which may be supplied by the user at runtime. There // 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" // methods describing various settings for the individual arguments. Or by supplying a "usage"
// string. Both methods have their pros and cons. // 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 // Arguments can be added to applications in two manners, one at a time with the arg()
// arg() method, or multiple arguments at once via a Vec<Arg> inside the args() method, // method, or multiple arguments at once via a `&[Arg]` inside the args() method.
// or a single &str describing multiple Args (one per line) supplied to args_from_usage().
// //
// There are various options which can be set for a given argument, some apply to any of the // 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 // 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 // One "Flag" using a usage string
.arg("--license 'display the license file'") .arg(arg!(--license "display the license file"))
// Two args, one "Positional", and one "Option" using a usage string // Two args one Positional and one Option using a usage string
.arg("[output] 'Supply an output file to use'") .arg(arg!([output] "Supply an output file to use"))
.arg("-i, --int=[IFACE] 'Set an interface to use'") .arg(
arg!(
-i --int <IFACE> "Set an interface to use"
)
.required(false),
)
.get_matches(); .get_matches();
// Here are some examples of using the arguments defined above. Keep in mind that this is only // 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() { fn main() {
// Of the three argument types, flags are the most simple. Flags are simple switches which can // 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>) // also has a conflicts_with_all(Vec<&str>)
// and an exclusive(true) // and an exclusive(true)
) )
.arg("-c, --config=[FILE] 'sets a custom config file'") .arg(
.arg("[output] 'sets an output file'") arg!(
-c --config <FILE> "sets a custom config file"
)
.required(false),
)
.arg(arg!([output] "sets an output file"))
.get_matches(); .get_matches();
// We can find out whether or not awesome was used // 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() { fn main() {
// Option arguments are those that take an additional value, such as "-c value". In clap they // 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>) // also has a conflicts_with_all(Vec<&str>)
// and an exclusive(true) // and an exclusive(true)
) )
.arg("-c, --config=[FILE] 'the config file to use'") .arg(
.arg("[output] 'the output file to use'") arg!(
-c --config <FILE> "the config file to use"
)
.required(false),
)
.arg(arg!([output] "the output file to use"))
.get_matches(); .get_matches();
// We can find out whether or not "input" was used // 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() { fn main() {
// You can use some convenience methods provided by clap to get typed values, so long as the // 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") let matches = App::new("myapp")
// Create two arguments, a required positional which accepts multiple values // Create two arguments, a required positional which accepts multiple values
// and an optional '-l value' // and an optional '-l value'
.arg("<seq>... 'A sequence of whole positive numbers, i.e. 20 25 30'") .arg(arg!(
.arg("-l [len] 'A length to use, defaults to 10 when omitted'") <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(); .get_matches();
// This code loops through all the values provided to "seq" and adds 2 // This code loops through all the values provided to "seq" and adds 2

View file

@ -5,7 +5,7 @@
use std::str::FromStr; use std::str::FromStr;
// Add clap like normal // Add clap like normal
use clap::{App, Arg}; use clap::{arg, App};
// Define your enum // Define your enum
enum Vals { enum Vals {
@ -35,7 +35,7 @@ fn main() {
let m = App::new("myapp") let m = App::new("myapp")
// Use a single positional argument that is required // Use a single positional argument that is required
.arg( .arg(
Arg::from("<type> 'The type to use'") arg!(<type> "The type to use")
// Define the list of possible values // Define the list of possible values
.possible_values(["Foo", "Bar", "Baz", "Qux"]), .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 /// 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 /// 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. /// them is used. For this, you can create a group.
use clap::{App, Arg, ArgGroup}; use clap::{arg, App, Arg, ArgGroup};
fn main() { fn main() {
// Create application like normal // Create application like normal
let matches = App::new("myapp") let matches = App::new("myapp")
// Add the version arguments // Add the version arguments
.arg("--set-ver [ver] 'set version manually'") .arg(arg!(--"set-ver" <ver> "set version manually").required(false))
.arg("--major 'auto inc major'") .arg(arg!(--major "auto inc major"))
.arg("--minor 'auto inc minor'") .arg(arg!(--minor "auto inc minor"))
.arg("--patch 'auto inc patch'") .arg(arg!(--patch "auto inc patch"))
// Create a group, make it required, and add the above arguments // Create a group, make it required, and add the above arguments
.group( .group(
ArgGroup::new("vers") ArgGroup::new("vers")
@ -38,8 +38,12 @@ fn main() {
) )
// Arguments can also be added to a group individually, these two arguments // Arguments can also be added to a group individually, these two arguments
// are part of the "input" group which is not required // are part of the "input" group which is not required
.arg(Arg::from("[INPUT_FILE] 'some regular input'").group("input")) .arg(arg!([INPUT_FILE] "some regular input").group("input"))
.arg(Arg::from("--spec-in [SPEC_IN] 'some special input argument'").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 // Now let's assume we have a -c [config] argument which requires one of
// (but **not** both) the "input" arguments // (but **not** both) the "input" arguments
.arg( .arg(

View file

@ -1,4 +1,4 @@
use clap::{App, AppSettings}; use clap::{arg, App, AppSettings};
fn main() { fn main() {
// You can use AppSettings to change the application level behavior of clap. .setting() function // 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") let matches = App::new("myapp")
.setting(AppSettings::SubcommandsNegateReqs) .setting(AppSettings::SubcommandsNegateReqs)
// Negates requirement of parent command. // Negates requirement of parent command.
.arg("<input> 'input file to use'") .arg(arg!(<input> "input file to use"))
// Required positional argument called input. This // Required positional argument called input. This
// will be only required if subcommand is not present. // will be only required if subcommand is not present.
.subcommand(App::new("test").about("does some testing")) .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_str: Option<&'help str>,
pub(crate) usage: Option<String>, pub(crate) usage: Option<String>,
pub(crate) help_str: Option<&'help str>, 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) term_w: Option<usize>,
pub(crate) max_w: Option<usize>, pub(crate) max_w: Option<usize>,
pub(crate) template: Option<&'help str>, pub(crate) template: Option<&'help str>,
@ -379,7 +379,6 @@ impl<'help> App<'help> {
App { App {
id: Id::from(&*name), id: Id::from(&*name),
name, name,
disp_ord: 999,
..Default::default() ..Default::default()
} }
.arg( .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")] #[cfg(feature = "yaml")]
#[deprecated(since = "3.0.0", note = "Replaced with `App::from`")] #[deprecated(
pub fn from_yaml(yaml: &'help Yaml) -> Self { since = "3.0.0",
Self::from(yaml) 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 /// Sets a string of author(s) that will be displayed to the user when they
@ -793,7 +890,7 @@ impl<'help> App<'help> {
self self
} }
/// Deprecated, see [`App::override_usage`] /// Deprecated, replaced with [`App::override_usage`]
#[deprecated(since = "3.0.0", note = "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 { pub fn usage<S: Into<&'help str>>(self, usage: S) -> Self {
self.override_usage(usage) self.override_usage(usage)
@ -839,7 +936,7 @@ impl<'help> App<'help> {
self self
} }
/// Deprecated, see [`App::override_help`] /// Deprecated, replaced with [`App::override_help`]
#[deprecated(since = "3.0.0", note = "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 { pub fn help<S: Into<&'help str>>(self, help: S) -> Self {
self.override_help(help) self.override_help(help)
@ -893,7 +990,7 @@ impl<'help> App<'help> {
self self
} }
/// Deprecated, see [`App::help_template`] /// Deprecated, replaced with [`App::help_template`]
#[deprecated(since = "3.0.0", note = "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 { pub fn template<S: Into<&'help str>>(self, s: S) -> Self {
self.help_template(s) self.help_template(s)
@ -1061,7 +1158,7 @@ impl<'help> App<'help> {
self self
} }
/// Deprecated, see [`App::term_width`] /// Deprecated, replaced with [`App::term_width`]
#[deprecated(since = "3.0.0", note = "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 { pub fn set_term_width(self, width: usize) -> Self {
self.term_width(width) self.term_width(width)
@ -1102,7 +1199,7 @@ impl<'help> App<'help> {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # use clap::{App, Arg}; /// # use clap::{App, arg, Arg};
/// App::new("myprog") /// App::new("myprog")
/// // Adding a single "flag" argument with a short and help text, using Arg::new() /// // Adding a single "flag" argument with a short and help text, using Arg::new()
/// .arg( /// .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 /// // Adding a single "option" argument with a short, a long, and help text using the less
/// // verbose Arg::from() /// // verbose Arg::from()
/// .arg( /// .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 /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # use clap::{App, Arg}; /// # use clap::{App, arg, Arg};
/// App::new("myprog") /// App::new("myprog")
/// .args(&[ /// .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") /// Arg::new("input").index(1).help("the input file to use")
/// ]) /// ])
/// # ; /// # ;
@ -1174,10 +1271,25 @@ impl<'help> App<'help> {
self self
} }
/// Deprecated, see [`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 `App::arg`")] #[deprecated(since = "3.0.0", note = "Replaced with `arg!`")]
pub fn arg_from_usage(self, usage: &'help str) -> Self { 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 /// 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. /// of the arguments from the specified group is present at runtime.
/// ///
/// ```no_run /// ```no_run
/// # use clap::{App, ArgGroup}; /// # use clap::{App, arg, ArgGroup};
/// App::new("app") /// App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'") /// .arg(arg!("--set-ver [ver] 'set the version manually'"))
/// .arg("--major 'auto increase major'") /// .arg(arg!("--major 'auto increase major'"))
/// .arg("--minor 'auto increase minor'") /// .arg(arg!("--minor 'auto increase minor'"))
/// .arg("--patch 'auto increase patch'") /// .arg(arg!("--patch 'auto increase patch'"))
/// .group(ArgGroup::new("vers") /// .group(ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor","patch"]) /// .args(&["set-ver", "major", "minor","patch"])
/// .required(true)) /// .required(true))
@ -1637,14 +1749,14 @@ impl<'help> App<'help> {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # use clap::{App, ArgGroup}; /// # use clap::{App, arg, ArgGroup};
/// App::new("app") /// App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'") /// .arg(arg!("--set-ver [ver] 'set the version manually'"))
/// .arg("--major 'auto increase major'") /// .arg(arg!("--major 'auto increase major'"))
/// .arg("--minor 'auto increase minor'") /// .arg(arg!("--minor 'auto increase minor'"))
/// .arg("--patch 'auto increase patch'") /// .arg(arg!("--patch 'auto increase patch'"))
/// .arg("-c [FILE] 'a config file'") /// .arg(arg!("-c [FILE] 'a config file'"))
/// .arg("-i [IFACE] 'an interface'") /// .arg(arg!("-i [IFACE] 'an interface'"))
/// .groups(&[ /// .groups(&[
/// ArgGroup::new("vers") /// ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor","patch"]) /// .args(&["set-ver", "major", "minor","patch"])
@ -1673,11 +1785,11 @@ impl<'help> App<'help> {
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # use clap::{App, Arg, }; /// # use clap::{App, arg};
/// App::new("myprog") /// App::new("myprog")
/// .subcommand(App::new("config") /// .subcommand(App::new("config")
/// .about("Controls configuration features") /// .about("Controls configuration features")
/// .arg("<config> 'Required configuration file to use'")) /// .arg(arg!("<config> 'Required configuration file to use'")))
/// # ; /// # ;
/// ``` /// ```
#[inline] #[inline]
@ -1760,7 +1872,7 @@ impl<'help> App<'help> {
/// ``` /// ```
#[inline] #[inline]
pub fn display_order(mut self, ord: usize) -> Self { pub fn display_order(mut self, ord: usize) -> Self {
self.disp_ord = ord; self.disp_ord = Some(ord);
self self
} }
@ -2066,7 +2178,7 @@ impl<'help> App<'help> {
self.try_get_matches_from(&mut env::args_os()) 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`")] #[deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches`")]
pub fn get_matches_safe(self) -> ClapResult<ArgMatches> { pub fn get_matches_safe(self) -> ClapResult<ArgMatches> {
self.try_get_matches() self.try_get_matches()
@ -2142,7 +2254,7 @@ impl<'help> App<'help> {
self.try_get_matches_from_mut(itr) 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`")] #[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> pub fn get_matches_from_safe<I, T>(self, itr: I) -> ClapResult<ArgMatches>
where where
@ -2251,7 +2363,7 @@ impl<'help> App<'help> {
self._do_parse(&mut it) self._do_parse(&mut it)
} }
/// Deprecated, see [`App::try_get_matches_from_mut`] /// Deprecated, replaced with [`App::try_get_matches_from_mut`]
#[deprecated( #[deprecated(
since = "3.0.0", since = "3.0.0",
note = "Replaced with `App::try_get_matches_from_mut`" note = "Replaced with `App::try_get_matches_from_mut`"
@ -2654,19 +2766,19 @@ impl<'help> App<'help> {
.args .args
.args_mut() .args_mut()
.filter(|a| !a.is_positional()) .filter(|a| !a.is_positional())
.filter(|a| a.disp_ord == 999) .filter(|a| a.get_display_order() == 999)
.filter(|a| a.provider != ArgProvider::Generated) .filter(|a| a.provider != ArgProvider::Generated)
.enumerate() .enumerate()
{ {
a.disp_ord = i; a.disp_ord = Some(i);
} }
for (i, mut sc) in &mut self for (i, mut sc) in &mut self
.subcommands .subcommands
.iter_mut() .iter_mut()
.enumerate() .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 { for sc in &mut self.subcommands {
@ -2955,6 +3067,10 @@ impl<'help> App<'help> {
.find(|sc| sc.long_flag_aliases_to(long)) .find(|sc| sc.long_flag_aliases_to(long))
.map(|sc| sc.get_name()) .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> { 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<'_> { impl fmt::Display for App<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name) write!(f, "{}", self.name)

View file

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

View file

@ -69,7 +69,7 @@ impl Default for ArgProvider {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use clap::Arg; /// # use clap::{Arg, arg};
/// // Using the traditional builder pattern and setting each option manually /// // Using the traditional builder pattern and setting each option manually
/// let cfg = Arg::new("config") /// let cfg = Arg::new("config")
/// .short('c') /// .short('c')
@ -78,7 +78,7 @@ impl Default for ArgProvider {
/// .value_name("FILE") /// .value_name("FILE")
/// .help("Provides a config file to myprog"); /// .help("Provides a config file to myprog");
/// // Using a usage string (setting a similar argument to the one above) /// // 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)] #[allow(missing_debug_implementations)]
#[derive(Default, Clone)] #[derive(Default, Clone)]
@ -101,7 +101,7 @@ pub struct Arg<'help> {
pub(crate) long: Option<&'help str>, pub(crate) long: Option<&'help str>,
pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible) pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible)
pub(crate) short_aliases: Vec<(char, 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) possible_vals: Vec<PossibleValue<'help>>,
pub(crate) val_names: Vec<&'help str>, pub(crate) val_names: Vec<&'help str>,
pub(crate) num_vals: Option<usize>, pub(crate) num_vals: Option<usize>,
@ -338,28 +338,154 @@ impl<'help> Arg<'help> {
Arg { Arg {
id: Id::from(&*name), id: Id::from(&*name),
name, name,
disp_ord: 999,
..Default::default() ..Default::default()
} }
} }
/// Deprecated, see [`Arg::new`] /// Deprecated, replaced with [`Arg::new`]
#[deprecated(since = "3.0.0", note = "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 { pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
Self::new(n) 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")] #[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 { 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 in [Issue #8](https://github.com/epage/clapng/issues/8), see [`arg!`][crate::arg!].
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::from`")] #[deprecated(since = "3.0.0", note = "Replaced with `arg!`")]
pub fn from_usage(u: &'help str) -> Self { pub fn from_usage(u: &'help str) -> Self {
Self::from(u) UsageParser::from_usage(u).parse()
} }
pub(crate) fn generated(mut self) -> Self { pub(crate) fn generated(mut self) -> Self {
@ -367,6 +493,17 @@ impl<'help> Arg<'help> {
self 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 `-`. /// Sets the short version of the argument without the preceding `-`.
/// ///
/// By default `clap` automatically assigns `V` and `h` to the auto-generated `version` and /// By default `clap` automatically assigns `V` and `h` to the auto-generated `version` and
@ -834,7 +971,7 @@ impl<'help> Arg<'help> {
self 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`")] #[deprecated(since = "3.0.0", note = "Replaced with `Arg::required_unless_present`")]
pub fn required_unless<T: Key>(self, arg_id: T) -> Self { pub fn required_unless<T: Key>(self, arg_id: T) -> Self {
self.required_unless_present(arg_id) self.required_unless_present(arg_id)
@ -914,7 +1051,7 @@ impl<'help> Arg<'help> {
self self
} }
/// Deprecated, see [`Arg::required_unless_present_all`] /// Deprecated, replaced with [`Arg::required_unless_present_all`]
#[deprecated( #[deprecated(
since = "3.0.0", since = "3.0.0",
note = "Replaced with `Arg::required_unless_present_all`" note = "Replaced with `Arg::required_unless_present_all`"
@ -1003,7 +1140,7 @@ impl<'help> Arg<'help> {
self self
} }
/// Deprecated, see [`Arg::required_unless_present_any`] /// Deprecated, replaced with [`Arg::required_unless_present_any`]
#[deprecated( #[deprecated(
since = "3.0.0", since = "3.0.0",
note = "Replaced with `Arg::required_unless_present_any`" note = "Replaced with `Arg::required_unless_present_any`"
@ -1180,12 +1317,12 @@ impl<'help> Arg<'help> {
/// # Examples /// # Examples
/// ///
/// ```rust # use clap::{App, Arg}; /// ```rust # use clap::{App, Arg};
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// let m = App::new("prog") /// let m = App::new("prog")
/// .arg(Arg::from("-f, --flag 'some flag'") /// .arg(arg!(-f --flag "some flag")
/// .conflicts_with("debug")) /// .conflicts_with("debug"))
/// .arg(Arg::from("-d, --debug 'other flag'")) /// .arg(arg!(-d --debug "other flag"))
/// .arg(Arg::from("-c, --color 'third flag'") /// .arg(arg!(-c --color "third flag")
/// .overrides_with("flag")) /// .overrides_with("flag"))
/// .get_matches_from(vec![ /// .get_matches_from(vec![
/// "prog", "-f", "-d", "-c"]); /// "prog", "-f", "-d", "-c"]);
@ -1205,9 +1342,9 @@ impl<'help> Arg<'help> {
/// preventing a "Unexpected multiple usage" error): /// preventing a "Unexpected multiple usage" error):
/// ///
/// ```rust /// ```rust
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// let m = App::new("posix") /// 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"]); /// .get_matches_from(vec!["posix", "--flag", "--flag"]);
/// assert!(m.is_present("flag")); /// assert!(m.is_present("flag"));
/// assert_eq!(m.occurrences_of("flag"), 1); /// 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. /// if it's a flag and it already accepts multiple occurrences.
/// ///
/// ``` /// ```
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// let m = App::new("posix") /// 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"]); /// .get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
/// assert!(m.is_present("flag")); /// assert!(m.is_present("flag"));
/// assert_eq!(m.occurrences_of("flag"), 4); /// assert_eq!(m.occurrences_of("flag"), 4);
@ -1231,9 +1368,9 @@ impl<'help> Arg<'help> {
/// occurrence happened. /// occurrence happened.
/// ///
/// ``` /// ```
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// let m = App::new("posix") /// 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"]); /// .get_matches_from(vec!["", "--opt=some", "--opt=other"]);
/// assert!(m.is_present("opt")); /// assert!(m.is_present("opt"));
/// assert_eq!(m.occurrences_of("opt"), 1); /// assert_eq!(m.occurrences_of("opt"), 1);
@ -1262,9 +1399,10 @@ impl<'help> Arg<'help> {
/// will ignore the "override self" setting. /// will ignore the "override self" setting.
/// ///
/// ``` /// ```
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// let m = App::new("posix") /// 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")) /// .overrides_with("opt"))
/// .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]); /// .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]);
/// assert!(m.is_present("opt")); /// assert!(m.is_present("opt"));
@ -1286,12 +1424,12 @@ impl<'help> Arg<'help> {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// let m = App::new("prog") /// let m = App::new("prog")
/// .arg(Arg::from("-f, --flag 'some flag'") /// .arg(arg!(-f --flag "some flag")
/// .conflicts_with("color")) /// .conflicts_with("color"))
/// .arg(Arg::from("-d, --debug 'other flag'")) /// .arg(arg!(-d --debug "other flag"))
/// .arg(Arg::from("-c, --color 'third flag'") /// .arg(arg!(-c --color "third flag")
/// .overrides_with_all(&["flag", "debug"])) /// .overrides_with_all(&["flag", "debug"]))
/// .get_matches_from(vec![ /// .get_matches_from(vec![
/// "prog", "-f", "-d", "-c"]); /// "prog", "-f", "-d", "-c"]);
@ -1583,7 +1721,7 @@ impl<'help> Arg<'help> {
self 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`")] #[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 { pub fn required_if<T: Key>(self, arg_id: T, val: &'help str) -> Self {
self.required_if_eq(arg_id, val) self.required_if_eq(arg_id, val)
@ -1675,7 +1813,7 @@ impl<'help> Arg<'help> {
self 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`")] #[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 { pub fn required_ifs<T: Key>(self, ifs: &[(T, &'help str)]) -> Self {
self.required_if_eq_any(ifs) self.required_if_eq_any(ifs)
@ -3382,7 +3520,7 @@ impl<'help> Arg<'help> {
/// [index]: Arg::index() /// [index]: Arg::index()
#[inline] #[inline]
pub fn display_order(mut self, ord: usize) -> Self { pub fn display_order(mut self, ord: usize) -> Self {
self.disp_ord = ord; self.disp_ord = Some(ord);
self 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`")] #[deprecated(since = "3.0.0", note = "Replaced with `Arg::forbid_empty_values`")]
pub fn empty_values(self, empty: bool) -> Self { pub fn empty_values(self, empty: bool) -> Self {
self.forbid_empty_values(!empty) 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`] /// [`Arg::multiple_values`]
#[deprecated( #[deprecated(
since = "3.0.0", since = "3.0.0",
@ -4745,7 +4883,7 @@ impl<'help> Arg<'help> {
self self
} }
/// Deprecated, see [`Arg::setting`] /// Deprecated, replaced with [`Arg::setting`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::setting`")] #[deprecated(since = "3.0.0", note = "Replaced with `Arg::setting`")]
pub fn set(self, s: ArgSettings) -> Self { pub fn set(self, s: ArgSettings) -> Self {
self.setting(s) self.setting(s)
@ -4780,7 +4918,7 @@ impl<'help> Arg<'help> {
self self
} }
/// Deprecated, see [`Arg::unset_setting`] /// Deprecated, replaced with [`Arg::unset_setting`]
#[deprecated(since = "3.0.0", note = "Replaced with `Arg::unset_setting`")] #[deprecated(since = "3.0.0", note = "Replaced with `Arg::unset_setting`")]
pub fn unset(self, s: ArgSettings) -> Self { pub fn unset(self, s: ArgSettings) -> Self {
self.unset_setting(s) self.unset_setting(s)
@ -4903,146 +5041,9 @@ impl<'help> Arg<'help> {
pub(crate) fn is_multiple(&self) -> bool { pub(crate) fn is_multiple(&self) -> bool {
self.is_set(ArgSettings::MultipleValues) | self.is_set(ArgSettings::MultipleOccurrences) self.is_set(ArgSettings::MultipleValues) | self.is_set(ArgSettings::MultipleOccurrences)
} }
}
#[cfg(feature = "yaml")] pub(crate) fn get_display_order(&self) -> usize {
impl<'help> From<&'help Yaml> for Arg<'help> { self.disp_ord.unwrap_or(999)
/// 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
} }
} }
@ -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> { impl<'help> PartialEq for Arg<'help> {
fn eq(&self, other: &Arg<'help>) -> bool { fn eq(&self, other: &Arg<'help>) -> bool {
self.name == other.name self.name == other.name

View file

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

View file

@ -1,28 +1,4 @@
use super::{settings::ArgSettings, Arg}; use crate::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());
}
// This test will *fail to compile* if Arg is not Send + Sync // This test will *fail to compile* if Arg is not Send + Sync
#[test] #[test]

View file

@ -36,12 +36,12 @@ use yaml_rust::Yaml;
/// the arguments from the specified group is present at runtime. /// the arguments from the specified group is present at runtime.
/// ///
/// ```rust /// ```rust
/// # use clap::{App, ArgGroup, ErrorKind}; /// # use clap::{App, arg, ArgGroup, ErrorKind};
/// let result = App::new("app") /// let result = App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'") /// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg("--major 'auto increase major'") /// .arg(arg!(--major "auto increase major"))
/// .arg("--minor 'auto increase minor'") /// .arg(arg!(--minor "auto increase minor"))
/// .arg("--patch 'auto increase patch'") /// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers") /// .group(ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor", "patch"]) /// .args(&["set-ver", "major", "minor", "patch"])
/// .required(true)) /// .required(true))
@ -54,12 +54,12 @@ use yaml_rust::Yaml;
/// This next example shows a passing parse of the same scenario /// This next example shows a passing parse of the same scenario
/// ///
/// ```rust /// ```rust
/// # use clap::{App, ArgGroup}; /// # use clap::{App, arg, ArgGroup};
/// let result = App::new("app") /// let result = App::new("app")
/// .arg("--set-ver [ver] 'set the version manually'") /// .arg(arg!(--"set-ver" <ver> "set the version manually").required(false))
/// .arg("--major 'auto increase major'") /// .arg(arg!(--major "auto increase major"))
/// .arg("--minor 'auto increase minor'") /// .arg(arg!(--minor "auto increase minor"))
/// .arg("--patch 'auto increase patch'") /// .arg(arg!(--patch "auto increase patch"))
/// .group(ArgGroup::new("vers") /// .group(ArgGroup::new("vers")
/// .args(&["set-ver", "major", "minor","patch"]) /// .args(&["set-ver", "major", "minor","patch"])
/// .required(true)) /// .required(true))
@ -108,15 +108,18 @@ impl<'help> ArgGroup<'help> {
ArgGroup::default().name(n) ArgGroup::default().name(n)
} }
/// Deprecated, see [`ArgGroup::new`] /// Deprecated, replaced with [`ArgGroup::new`]
#[deprecated(since = "3.0.0", note = "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 { pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
Self::new(n) 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")] #[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 { pub fn from_yaml(yaml: &'help Yaml) -> Self {
Self::from(yaml) 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")] #[cfg(feature = "yaml")]
impl<'help> From<&'help Yaml> for ArgGroup<'help> { impl<'help> From<&'help Yaml> for ArgGroup<'help> {
/// Creates a new instance of `ArgGroup` from a .yaml (YAML) file. /// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
///
/// # Examples
///
/// ```ignore
/// # use clap::{ArgGroup, load_yaml};
/// let yaml = load_yaml!("group.yaml");
/// let ag = ArgGroup::from(yaml);
/// ```
fn from(y: &'help Yaml) -> Self { fn from(y: &'help Yaml) -> Self {
let b = y.as_hash().expect("ArgGroup::from::<Yaml> expects a table"); let b = y.as_hash().expect("ArgGroup::from::<Yaml> expects a table");
// We WANT this to panic on error...so expect() is good. // 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> { pub(crate) fn parse(mut self) -> Arg<'help> {
debug!("UsageParser::parse"); debug!("UsageParser::parse");
let mut arg = Arg { let mut arg = Arg::default();
disp_ord: 999,
..Default::default()
};
loop { loop {
debug!("UsageParser::parse:iter: pos={}", self.pos); debug!("UsageParser::parse:iter: pos={}", self.pos);
self.stop_at(token); self.stop_at(token);
@ -173,12 +170,11 @@ impl<'help> UsageParser<'help> {
self.pos += 1; self.pos += 1;
if dot_counter == 3 { if dot_counter == 3 {
debug!("UsageParser::multiple: setting multiple"); debug!("UsageParser::multiple: setting multiple");
arg.settings.set(ArgSettings::MultipleOccurrences);
if arg.is_set(ArgSettings::TakesValue) { if arg.is_set(ArgSettings::TakesValue) {
// This is after `--name=value`, so requesting multiple value
arg.settings.set(ArgSettings::MultipleValues); arg.settings.set(ArgSettings::MultipleValues);
} else { arg.settings.set(ArgSettings::UseValueDelimiter);
// This is after `[name]` (or a flag), so requesting multiple occurrences arg.val_delim.get_or_insert(',');
arg.settings.set(ArgSettings::MultipleOccurrences);
} }
self.prev = UsageToken::Multiple; self.prev = UsageToken::Multiple;
self.pos += 1; self.pos += 1;
@ -245,12 +241,14 @@ fn default_value_end(b: u8) -> bool {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
#![allow(deprecated)]
use crate::build::{Arg, ArgSettings}; use crate::build::{Arg, ArgSettings};
#[allow(clippy::cognitive_complexity)] #[allow(clippy::cognitive_complexity)]
#[test] #[test]
fn create_flag_usage() { 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.name, "flag");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -258,7 +256,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flag");
assert_eq!(a.long.unwrap(), "flag"); assert_eq!(a.long.unwrap(), "flag");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -266,7 +264,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flag");
assert_eq!(a.long.unwrap(), "flag"); assert_eq!(a.long.unwrap(), "flag");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -274,7 +272,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flag");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert_eq!(a.long.unwrap(), "flag"); assert_eq!(a.long.unwrap(), "flag");
@ -282,7 +280,7 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flag");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -290,7 +288,7 @@ mod test {
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flag");
assert_eq!(a.long.unwrap(), "flag"); assert_eq!(a.long.unwrap(), "flag");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
@ -298,7 +296,7 @@ mod test {
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flag");
assert_eq!(a.long.unwrap(), "flag"); assert_eq!(a.long.unwrap(), "flag");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
@ -306,29 +304,29 @@ mod test {
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flags");
assert_eq!(a.long.unwrap(), "flags"); assert_eq!(a.long.unwrap(), "flags");
assert!(a.val_names.is_empty()); 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.name, "flags");
assert_eq!(a.long.unwrap(), "flags"); assert_eq!(a.long.unwrap(), "flags");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "flags");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.val_names.is_empty()); 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.name, "flags");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "f");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -336,12 +334,12 @@ mod test {
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(a.val_names.is_empty()); 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.name, "f");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.val_names.is_empty()); 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.name, "f");
assert_eq!(a.short.unwrap(), 'f'); assert_eq!(a.short.unwrap(), 'f');
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -351,7 +349,7 @@ mod test {
#[test] #[test]
fn create_option_usage0() { fn create_option_usage0() {
// Short only // 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.name, "option");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -365,7 +363,7 @@ mod test {
#[test] #[test]
fn create_option_usage1() { 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.name, "o");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -379,7 +377,7 @@ mod test {
#[test] #[test]
fn create_option_usage2() { 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.name, "option");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -393,7 +391,7 @@ mod test {
#[test] #[test]
fn create_option_usage3() { 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.name, "o");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -407,12 +405,12 @@ mod test {
#[test] #[test]
fn create_option_usage4() { 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.name, "option");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -421,7 +419,7 @@ mod test {
#[test] #[test]
fn create_option_usage5() { 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.name, "option");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -435,12 +433,12 @@ mod test {
#[test] #[test]
fn create_option_usage6() { 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.name, "o");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -449,12 +447,12 @@ mod test {
#[test] #[test]
fn create_option_usage7() { 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.name, "option");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -463,7 +461,7 @@ mod test {
#[test] #[test]
fn create_option_usage8() { 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.name, "option");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
@ -477,35 +475,21 @@ mod test {
#[test] #[test]
fn create_option_usage9() { 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.name, "o");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
assert_eq!(a.val_names.iter().collect::<Vec<_>>(), [&"opt"]); 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] #[test]
fn create_option_usage_long1() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -519,7 +503,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long2() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -533,7 +517,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long3() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -547,7 +531,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long4() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -561,12 +545,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long5() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -575,7 +559,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long6() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -589,12 +573,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long7() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -603,12 +587,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long8() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -617,7 +601,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long9() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -631,12 +615,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long10() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -645,7 +629,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals1() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -659,7 +643,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals2() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -673,7 +657,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals3() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -687,7 +671,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals4() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -701,12 +685,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals5() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -715,7 +699,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals6() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -729,12 +713,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals7() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -743,12 +727,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals8() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -757,7 +741,7 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals9() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
@ -771,12 +755,12 @@ mod test {
#[test] #[test]
fn create_option_usage_long_equals10() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -785,7 +769,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both1() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -799,7 +783,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both2() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -813,7 +797,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both3() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -827,7 +811,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both4() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -841,7 +825,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both5() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -855,12 +839,12 @@ mod test {
#[test] #[test]
fn create_option_usage_both6() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -869,7 +853,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both7() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -883,12 +867,12 @@ mod test {
#[test] #[test]
fn create_option_usage_both8() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -897,7 +881,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals1() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -911,7 +895,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals2() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -925,7 +909,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals3() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -939,7 +923,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals4() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -953,7 +937,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals5() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -967,12 +951,12 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals6() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(!a.is_set(ArgSettings::Required)); assert!(!a.is_set(ArgSettings::Required));
@ -981,7 +965,7 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals7() { 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.name, "option");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -995,12 +979,12 @@ mod test {
#[test] #[test]
fn create_option_usage_both_equals8() { 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.name, "opt");
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -1009,7 +993,7 @@ mod test {
#[test] #[test]
fn create_option_with_vals1() { 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_eq!(a.name, "o");
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -1023,12 +1007,12 @@ mod test {
#[test] #[test]
fn create_option_with_vals2() { 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_eq!(a.name, "o");
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -1037,12 +1021,12 @@ mod test {
#[test] #[test]
fn create_option_with_vals3() { 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_eq!(a.name, "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
assert_eq!(a.help.unwrap(), "some help info"); 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::MultipleValues));
assert!(a.is_set(ArgSettings::TakesValue)); assert!(a.is_set(ArgSettings::TakesValue));
assert!(a.is_set(ArgSettings::Required)); assert!(a.is_set(ArgSettings::Required));
@ -1051,7 +1035,7 @@ mod test {
#[test] #[test]
fn create_option_with_vals4() { 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_eq!(a.name, "myopt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
@ -1065,7 +1049,7 @@ mod test {
#[test] #[test]
fn create_option_with_vals5() { 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_eq!(a.name, "opt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
@ -1078,7 +1062,7 @@ mod test {
#[test] #[test]
fn create_positional_usage() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
@ -1089,7 +1073,7 @@ mod test {
#[test] #[test]
fn create_positional_usage0() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
@ -1100,7 +1084,7 @@ mod test {
#[test] #[test]
fn pos_mult_help() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1111,7 +1095,7 @@ mod test {
#[test] #[test]
fn pos_help_lit_single_quote() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some help' info"); assert_eq!(a.help.unwrap(), "some help' info");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1122,7 +1106,7 @@ mod test {
#[test] #[test]
fn pos_help_double_lit_single_quote() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some 'help' info"); assert_eq!(a.help.unwrap(), "some 'help' info");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1133,7 +1117,7 @@ mod test {
#[test] #[test]
fn pos_help_newline() { fn pos_help_newline() {
let a = Arg::from( let a = Arg::from_usage(
"[pos]... 'some help\n\ "[pos]... 'some help\n\
info'", info'",
); );
@ -1147,7 +1131,7 @@ mod test {
#[test] #[test]
fn pos_help_newline_lit_sq() { fn pos_help_newline_lit_sq() {
let a = Arg::from( let a = Arg::from_usage(
"[pos]... 'some help\' stuff\n\ "[pos]... 'some help\' stuff\n\
info'", info'",
); );
@ -1161,7 +1145,7 @@ mod test {
#[test] #[test]
fn pos_req_mult_help() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1172,7 +1156,7 @@ mod test {
#[test] #[test]
fn pos_req() { fn pos_req() {
let a = Arg::from("<pos>"); let a = Arg::from_usage("<pos>");
assert_eq!(a.name, "pos"); assert_eq!(a.name, "pos");
assert!(!a.is_set(ArgSettings::MultipleOccurrences)); assert!(!a.is_set(ArgSettings::MultipleOccurrences));
assert!(!a.is_set(ArgSettings::MultipleValues)); assert!(!a.is_set(ArgSettings::MultipleValues));
@ -1182,7 +1166,7 @@ mod test {
#[test] #[test]
fn pos_mult() { fn pos_mult() {
let a = Arg::from("[pos]..."); let a = Arg::from_usage("[pos]...");
assert_eq!(a.name, "pos"); assert_eq!(a.name, "pos");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
assert!(!a.is_set(ArgSettings::MultipleValues)); assert!(!a.is_set(ArgSettings::MultipleValues));
@ -1192,7 +1176,7 @@ mod test {
#[test] #[test]
fn pos_req_mult_def_help() { 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.name, "pos");
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(a.is_set(ArgSettings::MultipleOccurrences)); assert!(a.is_set(ArgSettings::MultipleOccurrences));
@ -1204,7 +1188,7 @@ mod test {
#[test] #[test]
fn create_option_with_vals1_def() { 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_eq!(a.name, "o");
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.short.unwrap(), 'o'); assert_eq!(a.short.unwrap(), 'o');
@ -1219,7 +1203,7 @@ mod test {
#[test] #[test]
fn create_option_with_vals4_def() { 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_eq!(a.name, "myopt");
assert!(a.short.is_none()); assert!(a.short.is_none());
assert_eq!(a.long.unwrap(), "opt"); assert_eq!(a.long.unwrap(), "opt");
@ -1234,27 +1218,59 @@ mod test {
#[test] #[test]
fn nonascii() { fn nonascii() {
let a = Arg::from("<ASCII> 'üñíčöĐ€'"); let a = Arg::from_usage("<ASCII> 'üñíčöĐ€'");
assert_eq!(a.name, "ASCII"); assert_eq!(a.name, "ASCII");
assert_eq!(a.help, Some("üñíčöĐ€")); assert_eq!(a.help, Some("üñíčöĐ€"));
let a = Arg::from("<üñíčöĐ€> 'ASCII'"); let a = Arg::from_usage("<üñíčöĐ€> 'ASCII'");
assert_eq!(a.name, "üñíčöĐ€"); assert_eq!(a.name, "üñíčöĐ€");
assert_eq!(a.help, Some("ASCII")); assert_eq!(a.help, Some("ASCII"));
let a = Arg::from("<üñíčöĐ€> 'üñíčöĐ€'"); let a = Arg::from_usage("<üñíčöĐ€> 'üñíčöĐ€'");
assert_eq!(a.name, "üñíčöĐ€"); assert_eq!(a.name, "üñíčöĐ€");
assert_eq!(a.help, Some("üñíčöĐ€")); assert_eq!(a.help, Some("üñíčöĐ€"));
let a = Arg::from("-ø 'ø'"); let a = Arg::from_usage("-ø 'ø'");
assert_eq!(a.name, "ø"); assert_eq!(a.name, "ø");
assert_eq!(a.short, Some('ø')); assert_eq!(a.short, Some('ø'));
assert_eq!(a.help, 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.name, "üñíčöĐ€");
assert_eq!(a.long, Some("üñíčöĐ€")); assert_eq!(a.long, Some("üñíčöĐ€"));
assert_eq!(a.help, Some("Nōṫ ASCII")); 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.name, "ñämê");
assert_eq!(a.long, Some("ôpt")); assert_eq!(a.long, Some("ôpt"));
assert_eq!(a.val_names.iter().collect::<Vec<_>>(), [&"üñíčöĐ€"]); assert_eq!(a.val_names.iter().collect::<Vec<_>>(), [&"üñíčöĐ€"]);
assert_eq!(a.help, Some("hælp")); 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")] #[cfg(feature = "yaml")]
#[doc(hidden)] #[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; pub use yaml_rust::YamlLoader;
#[cfg(feature = "derive")] #[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"; report at https://github.com/clap-rs/clap/issues";
const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point"; 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)] #[derive(Debug, Copy, Clone)]
pub struct SubCommand {} pub struct SubCommand {}
#[allow(deprecated)]
impl SubCommand { impl SubCommand {
/// Deprecated, see [`App::new`] /// Deprecated, replaced with [`App::new`]
#[deprecated(since = "3.0.0", note = "Replaced with `App::new`)")] #[deprecated(since = "3.0.0", note = "Replaced with `App::new`")]
pub fn with_name<'help>(name: &str) -> App<'help> { pub fn with_name<'help>(name: &str) -> App<'help> {
App::new(name) 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")] #[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 { 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, /// Deprecated in [Issue #9](https://github.com/epage/clapng/issues/9), maybe [`clap::Parser`][crate::Parser] would fit your use case?
/// 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.
/// # }
/// ```
#[cfg(feature = "yaml")] #[cfg(feature = "yaml")]
#[deprecated(
since = "3.0.0",
note = "Deprecated in Issue #9, maybe clap::Parser would fit your use case?"
)]
#[macro_export] #[macro_export]
macro_rules! load_yaml { macro_rules! load_yaml {
($yaml:expr) => { ($yaml:expr) => {
@ -175,96 +155,304 @@ macro_rules! app_from_crate {
}; };
} }
/// Build `App`, `Arg` and `Group` with Usage-string like input #[doc(hidden)]
/// but without the associated parsing runtime cost. #[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 /// # Examples
/// ///
/// ```no_run /// ```rust
/// # #[macro_use] /// # use clap::{App, Arg, arg};
/// # extern crate clap; /// App::new("prog")
/// # fn main() { /// .args(&[
/// let matches = clap_app!(myapp => /// arg!(--config <FILE> "a required file for the configuration and no short"),
/// (version: "1.0") /// arg!(-d --debug ... "turns on debugging information and allows multiples"),
/// (author: "Kevin K. <kbknapp@gmail.com>") /// arg!([input] "an optional input file to use")
/// (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();
/// # }
/// ``` /// ```
/// /// [`Arg`]: ./struct.Arg.html
/// # Shorthand Syntax for Args #[macro_export]
/// macro_rules! arg {
/// * A single hyphen followed by a character (such as `-c`) sets the [`Arg::short`] ( $name:ident: $($tail:tt)+ ) => {
/// * A double hyphen followed by a character or word (such as `--config`) sets [`Arg::long`] $crate::arg_impl! {
/// * Three dots (`...`) sets [`Arg::multiple_values(true)`] @arg ($crate::Arg::new($crate::arg_impl! { @string $name })) $($tail)+
/// * 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 ( $($tail:tt)+ ) => {{
/// `Arg::required(true)` let arg = $crate::arg_impl! {
/// * Square brackets after either a short or long will set [`Arg::value_name`] and @arg ($crate::Arg::default()) $($tail)+
/// `Arg::required(false)` such as `--config [FILE]` = `Arg::value_name("FILE")` and };
/// `Arg::required(false)` debug_assert!(!arg.get_name().is_empty(), "Without a value or long flag, the `name:` prefix is required");
/// * There are short hand syntaxes for Arg methods that accept booleans arg
/// * 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)` /// Deprecated, replaced with [`clap::Parser`][crate::Parser] and [`clap::arg!`][crate::arg] (Issue clap-rs/clap#2835)
/// * 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()
#[deprecated( #[deprecated(
since = "3.0.0", 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_export]
macro_rules! clap_app { macro_rules! clap_app {
@ -627,7 +815,7 @@ macro_rules! debug {
($($arg:tt)*) => {}; ($($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] #[macro_export]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::value_of_t`")] #[deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::value_of_t`")]
macro_rules! value_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] #[macro_export]
#[deprecated( #[deprecated(
since = "3.0.0", 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] #[macro_export]
#[deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::values_of_t`")] #[deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::values_of_t`")]
macro_rules! values_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] #[macro_export]
#[deprecated( #[deprecated(
since = "3.0.0", 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())); longest = longest.max(display_width(arg.to_string().as_str()));
debug!("Help::write_args: New Longest...{}", longest); 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: // Formatting key like this to ensure that:
// 1. Argument has long flags are printed just after short flags. // 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)) .filter(|subcommand| should_show_subcommand(subcommand))
{ {
let btm = ord_m let btm = ord_m
.entry(subcommand.disp_ord) .entry(subcommand.get_display_order())
.or_insert_with(BTreeMap::new); .or_insert_with(BTreeMap::new);
let mut sc_str = String::new(); let mut sc_str = String::new();
sc_str.push_str( sc_str.push_str(

View file

@ -47,9 +47,9 @@ pub enum ErrorKind {
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// # use clap::{App, Arg, ErrorKind}; /// # use clap::{App, arg, ErrorKind};
/// let result = App::new("prog") /// let result = App::new("prog")
/// .arg(Arg::from("--flag 'some flag'")) /// .arg(arg!(--flag "some flag"))
/// .try_get_matches_from(vec!["prog", "--other"]); /// .try_get_matches_from(vec!["prog", "--other"]);
/// assert!(result.is_err()); /// assert!(result.is_err());
/// assert_eq!(result.unwrap_err().kind, ErrorKind::UnknownArgument); /// assert_eq!(result.unwrap_err().kind, ErrorKind::UnknownArgument);
@ -1106,7 +1106,7 @@ impl Error {
Self::new(c, ErrorKind::ArgumentNotFound, false).set_info(vec![arg]) Self::new(c, ErrorKind::ArgumentNotFound, false).set_info(vec![arg])
} }
/// Deprecated, see [`App::error`] /// Deprecated, replaced with [`App::error`]
/// ///
/// [`App::error`]: crate::App::error /// [`App::error`]: crate::App::error
#[deprecated(since = "3.0.0", note = "Replaced with `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(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")] #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// use std::ffi::OsString; /// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt}; /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
/// ///
/// let m = App::new("utf8") /// let m = App::new("utf8")
/// .arg(Arg::from("<arg> 'some arg'") /// .arg(arg!(<arg> "some arg")
/// .allow_invalid_utf8(true)) /// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"), /// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi {0xe9}!" /// // "Hi {0xe9}!"
@ -221,12 +221,12 @@ impl ArgMatches {
/// ///
#[cfg_attr(not(unix), doc = " ```ignore")] #[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")] #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// use std::ffi::OsString; /// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt}; /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
/// ///
/// let m = App::new("utf8") /// let m = App::new("utf8")
/// .arg(Arg::from("<arg> 'some arg'") /// .arg(arg!(<arg> "some arg")
/// .allow_invalid_utf8(true)) /// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"), /// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi {0xe9}!" /// // "Hi {0xe9}!"
@ -306,12 +306,12 @@ impl ArgMatches {
/// ///
#[cfg_attr(not(unix), doc = " ```ignore")] #[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")] #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// use std::ffi::OsString; /// use std::ffi::OsString;
/// use std::os::unix::ffi::OsStringExt; /// use std::os::unix::ffi::OsStringExt;
/// ///
/// let m = App::new("utf8") /// let m = App::new("utf8")
/// .arg(Arg::from("<arg>... 'some arg'") /// .arg(arg!(<arg> ... "some arg")
/// .allow_invalid_utf8(true)) /// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"), /// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi" /// // "Hi"
@ -343,12 +343,12 @@ impl ArgMatches {
/// ///
#[cfg_attr(not(unix), doc = " ```ignore")] #[cfg_attr(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")] #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// use std::ffi::{OsStr,OsString}; /// use std::ffi::{OsStr,OsString};
/// use std::os::unix::ffi::{OsStrExt,OsStringExt}; /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
/// ///
/// let m = App::new("utf8") /// let m = App::new("utf8")
/// .arg(Arg::from("<arg>... 'some arg'") /// .arg(arg!(<arg> ... "some arg")
/// .allow_invalid_utf8(true)) /// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"), /// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi" /// // "Hi"
@ -392,10 +392,9 @@ impl ArgMatches {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate clap; /// # use clap::{App, arg};
/// # use clap::App;
/// let matches = App::new("myapp") /// 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"]); /// .get_matches_from(&["test", "12"]);
/// ///
/// // Specify the type explicitly (or use turbofish) /// // Specify the type explicitly (or use turbofish)
@ -443,10 +442,9 @@ impl ArgMatches {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate clap; /// # use clap::{App, arg};
/// # use clap::App;
/// let matches = App::new("myapp") /// 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"]); /// .get_matches_from(&["test", "12"]);
/// ///
/// // Specify the type explicitly (or use turbofish) /// // Specify the type explicitly (or use turbofish)
@ -481,10 +479,9 @@ impl ArgMatches {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate clap; /// # use clap::{App, arg};
/// # use clap::App;
/// let matches = App::new("myapp") /// 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"]); /// .get_matches_from(&["test", "12", "77", "40"]);
/// ///
/// // Specify the type explicitly (or use turbofish) /// // Specify the type explicitly (or use turbofish)
@ -534,10 +531,9 @@ impl ArgMatches {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # extern crate clap; /// # use clap::{App, arg};
/// # use clap::App;
/// let matches = App::new("myapp") /// 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"]); /// .get_matches_from(&["test", "12", "77", "40"]);
/// ///
/// // Specify the type explicitly (or use turbofish) /// // 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(not(unix), doc = " ```ignore")]
#[cfg_attr(unix, doc = " ```")] #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg}; /// # use clap::{App, arg};
/// use std::ffi::OsString; /// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt}; /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
/// ///
/// let m = App::new("utf8") /// let m = App::new("utf8")
/// .arg(Arg::from("<arg> 'some arg'") /// .arg(arg!(<arg> "some arg")
/// .allow_invalid_utf8(true)) /// .allow_invalid_utf8(true))
/// .get_matches_from(vec![OsString::from("myprog"), /// .get_matches_from(vec![OsString::from("myprog"),
/// // "Hi {0xe9}!" /// // "Hi {0xe9}!"

View file

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

View file

@ -1,6 +1,6 @@
mod utils; mod utils;
use clap::{App, Arg}; use clap::{arg, App, Arg};
static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2 static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2
@ -167,7 +167,7 @@ fn invisible_arg_aliases_help_output() {
.takes_value(true) .takes_value(true)
.aliases(&["invisible", "als1", "more"]), .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( assert!(utils::compare_output(
app, app,

View file

@ -1,6 +1,6 @@
mod utils; mod utils;
use clap::{App, Arg}; use clap::{arg, App, Arg};
static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2 static SC_VISIBLE_ALIAS_HELP: &str = "ct-test 1.2
@ -163,7 +163,7 @@ fn invisible_short_arg_aliases_help_output() {
.takes_value(true) .takes_value(true)
.short_aliases(&['a', 'b', 'c']), .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( assert!(utils::compare_output(
app, app,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,10 +1,10 @@
use clap::{App, AppSettings, Arg}; use clap::{arg, App, AppSettings, Arg};
#[test] #[test]
fn single_short_arg_without_value() { fn single_short_arg_without_value() {
let app = App::new("app") let app = App::new("app").setting(AppSettings::IgnoreErrors).arg(arg!(
.setting(AppSettings::IgnoreErrors) -c --config [FILE] "Sets a custom config file"
.arg("-c, --config=[FILE] 'Sets a custom config file'"); ));
let r = app.try_get_matches_from(vec!["app", "-c" /* missing: , "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] #[test]
fn single_long_arg_without_value() { fn single_long_arg_without_value() {
let app = App::new("app") let app = App::new("app").setting(AppSettings::IgnoreErrors).arg(arg!(
.setting(AppSettings::IgnoreErrors) -c --config [FILE] "Sets a custom config file"
.arg("-c, --config=[FILE] 'Sets a custom config file'"); ));
let r = app.try_get_matches_from(vec!["app", "--config" /* missing: , "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() { fn multiple_args_and_final_arg_without_value() {
let app = App::new("app") let app = App::new("app")
.setting(AppSettings::IgnoreErrors) .setting(AppSettings::IgnoreErrors)
.arg("-c, --config=[FILE] 'Sets a custom config file'") .arg(arg!(
.arg("-x, --stuff=[FILE] 'Sets a custom stuff file'") -c --config [FILE] "Sets a custom config file"
.arg("-f 'Flag'"); ))
.arg(arg!(
-x --stuff [FILE] "Sets a custom stuff file"
))
.arg(arg!(f: -f "Flag"));
let r = app.try_get_matches_from(vec![ let r = app.try_get_matches_from(vec![
"app", "-c", "file", "-f", "-x", /* missing: , "some stuff" */ "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() { fn multiple_args_and_intermittent_arg_without_value() {
let app = App::new("app") let app = App::new("app")
.setting(AppSettings::IgnoreErrors) .setting(AppSettings::IgnoreErrors)
.arg("-c, --config=[FILE] 'Sets a custom config file'") .arg(arg!(
.arg("-x, --stuff=[FILE] 'Sets a custom stuff file'") -c --config[FILE] "Sets a custom config file"
.arg("-f 'Flag'"); ))
.arg(arg!(
-x --stuff[FILE] "Sets a custom stuff file"
))
.arg(arg!(f: -f "Flag"));
let r = app.try_get_matches_from(vec![ let r = app.try_get_matches_from(vec![
"app", "-x", /* missing: ,"some stuff" */ "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>("func1").ok(), Some(34));
assert_eq!(matches.value_of_t::<u16>("func2").ok(), Some(56)); 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] #[test]
fn multiple_occurrences_of_flags_long() { fn multiple_occurrences_of_flags_long() {
let m = App::new("mo_flags_long") let m = App::new("mo_flags_long")
.arg( .arg(arg!(--multflag "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
Arg::from("--multflag 'allowed multiple flag'") .arg(arg!(--flag "disallowed multiple flag"))
.setting(ArgSettings::MultipleOccurrences),
)
.arg(Arg::from("--flag 'disallowed multiple flag'"))
.get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]); .get_matches_from(vec!["", "--multflag", "--flag", "--multflag"]);
assert!(m.is_present("multflag")); assert!(m.is_present("multflag"));
assert_eq!(m.occurrences_of("multflag"), 2); assert_eq!(m.occurrences_of("multflag"), 2);
@ -18,11 +15,8 @@ fn multiple_occurrences_of_flags_long() {
#[test] #[test]
fn multiple_occurrences_of_flags_short() { fn multiple_occurrences_of_flags_short() {
let m = App::new("mo_flags_short") let m = App::new("mo_flags_short")
.arg( .arg(arg!(-m --multflag "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
Arg::from("-m --multflag 'allowed multiple flag'") .arg(arg!(-f --flag "disallowed multiple flag"))
.setting(ArgSettings::MultipleOccurrences),
)
.arg(Arg::from("-f --flag 'disallowed multiple flag'"))
.get_matches_from(vec!["", "-m", "-f", "-m"]); .get_matches_from(vec!["", "-m", "-f", "-m"]);
assert!(m.is_present("multflag")); assert!(m.is_present("multflag"));
assert_eq!(m.occurrences_of("multflag"), 2); assert_eq!(m.occurrences_of("multflag"), 2);
@ -33,15 +27,12 @@ fn multiple_occurrences_of_flags_short() {
#[test] #[test]
fn multiple_occurrences_of_flags_mixed() { fn multiple_occurrences_of_flags_mixed() {
let m = App::new("mo_flags_mixed") let m = App::new("mo_flags_mixed")
.arg(arg!(-m --multflag1 "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
.arg( .arg(
Arg::from("-m, --multflag1 'allowed multiple flag'") arg!(-n --multflag2 "another allowed multiple flag")
.setting(ArgSettings::MultipleOccurrences), .setting(ArgSettings::MultipleOccurrences),
) )
.arg( .arg(arg!(-f --flag "disallowed multiple flag"))
Arg::from("-n, --multflag2 'another allowed multiple flag'")
.setting(ArgSettings::MultipleOccurrences),
)
.arg(Arg::from("-f, --flag 'disallowed multiple flag'"))
.get_matches_from(vec![ .get_matches_from(vec![
"", "",
"-m", "-m",
@ -98,10 +89,7 @@ fn multiple_occurrences_of_flags_large_quantity() {
.chain(vec!["-m"; 1024].into_iter()) .chain(vec!["-m"; 1024].into_iter())
.collect(); .collect();
let m = App::new("mo_flags_large_qty") let m = App::new("mo_flags_large_qty")
.arg( .arg(arg!(-m --multflag "allowed multiple flag").setting(ArgSettings::MultipleOccurrences))
Arg::from("-m --multflag 'allowed multiple flag'")
.setting(ArgSettings::MultipleOccurrences),
)
.get_matches_from(args); .get_matches_from(args);
assert!(m.is_present("multflag")); assert!(m.is_present("multflag"));
assert_eq!(m.occurrences_of("multflag"), 1024); 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] #[test]
fn value_names_building_num_vals_for_positional() { fn value_names_building_num_vals_for_positional() {
let m = App::new("test") let m = App::new("test")

View file

@ -1,6 +1,6 @@
mod utils; mod utils;
use clap::{App, AppSettings, Arg, ArgMatches, ArgSettings, ErrorKind}; use clap::{arg, App, AppSettings, Arg, ArgMatches, ArgSettings, ErrorKind};
#[cfg(feature = "suggestions")] #[cfg(feature = "suggestions")]
static DYM: &str = static DYM: &str =
@ -146,7 +146,7 @@ fn require_equals_pass() {
#[test] #[test]
fn stdin_char() { fn stdin_char() {
let r = App::new("opts") 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", "-"]); .try_get_matches_from(vec!["", "-f", "-"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -158,8 +158,8 @@ fn stdin_char() {
fn opts_using_short() { fn opts_using_short() {
let r = App::new("opts") let r = App::new("opts")
.args(&[ .args(&[
Arg::from("-f [flag] 'some flag'"), arg!(f: -f [flag] "some flag"),
Arg::from("-c [color] 'some other flag'"), arg!(c: -c [color] "some other flag"),
]) ])
.try_get_matches_from(vec!["", "-f", "some", "-c", "other"]); .try_get_matches_from(vec!["", "-f", "some", "-c", "other"]);
assert!(r.is_ok()); assert!(r.is_ok());
@ -173,7 +173,7 @@ fn opts_using_short() {
#[test] #[test]
fn lots_o_vals() { fn lots_o_vals() {
let r = App::new("opts") 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![ .try_get_matches_from(vec![
"", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some", "", "-o", "some", "some", "some", "some", "some", "some", "some", "some", "some",
"some", "some", "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() { fn opts_using_long_space() {
let r = App::new("opts") let r = App::new("opts")
.args(&[ .args(&[
Arg::from("--flag [flag] 'some flag'"), arg!(--flag [flag] "some flag"),
Arg::from("--color [color] 'some other flag'"), arg!(--color [color] "some other flag"),
]) ])
.try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]); .try_get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
assert!(r.is_ok()); assert!(r.is_ok());
@ -230,8 +230,8 @@ fn opts_using_long_space() {
fn opts_using_long_equals() { fn opts_using_long_equals() {
let r = App::new("opts") let r = App::new("opts")
.args(&[ .args(&[
Arg::from("--flag [flag] 'some flag'"), arg!(--flag [flag] "some flag"),
Arg::from("--color [color] 'some other flag'"), arg!(--color [color] "some other flag"),
]) ])
.try_get_matches_from(vec!["", "--flag=some", "--color=other"]); .try_get_matches_from(vec!["", "--flag=some", "--color=other"]);
assert!(r.is_ok()); assert!(r.is_ok());
@ -246,8 +246,8 @@ fn opts_using_long_equals() {
fn opts_using_mixed() { fn opts_using_mixed() {
let r = App::new("opts") let r = App::new("opts")
.args(&[ .args(&[
Arg::from("-f, --flag [flag] 'some flag'"), arg!(-f --flag [flag] "some flag"),
Arg::from("-c, --color [color] 'some other flag'"), arg!(-c --color [color] "some other flag"),
]) ])
.try_get_matches_from(vec!["", "-f", "some", "--color", "other"]); .try_get_matches_from(vec!["", "-f", "some", "--color", "other"]);
assert!(r.is_ok()); assert!(r.is_ok());
@ -262,8 +262,8 @@ fn opts_using_mixed() {
fn opts_using_mixed2() { fn opts_using_mixed2() {
let r = App::new("opts") let r = App::new("opts")
.args(&[ .args(&[
Arg::from("-f, --flag [flag] 'some flag'"), arg!(-f --flag [flag] "some flag"),
Arg::from("-c, --color [color] 'some other flag'"), arg!(-c --color [color] "some other flag"),
]) ])
.try_get_matches_from(vec!["", "--flag=some", "-c", "other"]); .try_get_matches_from(vec!["", "--flag=some", "-c", "other"]);
assert!(r.is_ok()); assert!(r.is_ok());
@ -277,7 +277,7 @@ fn opts_using_mixed2() {
#[test] #[test]
fn default_values_user_value() { fn default_values_user_value() {
let r = App::new("df") 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"]); .try_get_matches_from(vec!["", "-o", "value"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -288,8 +288,8 @@ fn default_values_user_value() {
#[test] #[test]
fn multiple_vals_pos_arg_equals() { fn multiple_vals_pos_arg_equals() {
let r = App::new("mvae") let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'")) .arg(arg!(o: -o [opt] ... "some opt"))
.arg(Arg::from("[file] 'some file'")) .arg(arg!([file] "some file"))
.try_get_matches_from(vec!["", "-o=1", "some"]); .try_get_matches_from(vec!["", "-o=1", "some"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -302,8 +302,12 @@ fn multiple_vals_pos_arg_equals() {
#[test] #[test]
fn multiple_vals_pos_arg_delim() { fn multiple_vals_pos_arg_delim() {
let r = App::new("mvae") let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::UseValueDelimiter)) .arg(
.arg(Arg::from("[file] 'some file'")) 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"]); .try_get_matches_from(vec!["", "-o", "1,2", "some"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -317,11 +321,11 @@ fn multiple_vals_pos_arg_delim() {
fn require_delims_no_delim() { fn require_delims_no_delim() {
let r = App::new("mvae") let r = App::new("mvae")
.arg( .arg(
Arg::from("-o [opt]... 'some opt'") arg!(o: -o [opt] ... "some opt")
.setting(ArgSettings::UseValueDelimiter) .setting(ArgSettings::UseValueDelimiter)
.setting(ArgSettings::RequireDelimiter), .setting(ArgSettings::RequireDelimiter),
) )
.arg(Arg::from("[file] 'some file'")) .arg(arg!([file] "some file"))
.try_get_matches_from(vec!["mvae", "-o", "1", "2", "some"]); .try_get_matches_from(vec!["mvae", "-o", "1", "2", "some"]);
assert!(r.is_err()); assert!(r.is_err());
let err = r.unwrap_err(); let err = r.unwrap_err();
@ -332,11 +336,12 @@ fn require_delims_no_delim() {
fn require_delims() { fn require_delims() {
let r = App::new("mvae") let r = App::new("mvae")
.arg( .arg(
Arg::from("-o [opt]... 'some opt'") arg!(o: -o <opt> "some opt")
.multiple_values(true)
.setting(ArgSettings::UseValueDelimiter) .setting(ArgSettings::UseValueDelimiter)
.setting(ArgSettings::RequireDelimiter), .setting(ArgSettings::RequireDelimiter),
) )
.arg(Arg::from("[file] 'some file'")) .arg(arg!([file] "some file"))
.try_get_matches_from(vec!["", "-o", "1,2", "some"]); .try_get_matches_from(vec!["", "-o", "1,2", "some"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -349,7 +354,11 @@ fn require_delims() {
#[test] #[test]
fn leading_hyphen_pass() { fn leading_hyphen_pass() {
let r = App::new("mvae") 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"]); .try_get_matches_from(vec!["", "-o", "-2", "3"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -360,7 +369,7 @@ fn leading_hyphen_pass() {
#[test] #[test]
fn leading_hyphen_fail() { fn leading_hyphen_fail() {
let r = App::new("mvae") 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"]); .try_get_matches_from(vec!["", "-o", "-2"]);
assert!(r.is_err()); assert!(r.is_err());
let m = r.unwrap_err(); let m = r.unwrap_err();
@ -370,8 +379,12 @@ fn leading_hyphen_fail() {
#[test] #[test]
fn leading_hyphen_with_flag_after() { fn leading_hyphen_with_flag_after() {
let r = App::new("mvae") let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues)) .arg(
.arg("-f 'some flag'") 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"]); .try_get_matches_from(vec!["", "-o", "-2", "-f"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -383,8 +396,8 @@ fn leading_hyphen_with_flag_after() {
#[test] #[test]
fn leading_hyphen_with_flag_before() { fn leading_hyphen_with_flag_before() {
let r = App::new("mvae") let r = App::new("mvae")
.arg(Arg::from("-o [opt]... 'some opt'").setting(ArgSettings::AllowHyphenValues)) .arg(arg!(o: -o [opt] ... "some opt").setting(ArgSettings::AllowHyphenValues))
.arg("-f 'some flag'") .arg(arg!(f: -f "some flag"))
.try_get_matches_from(vec!["", "-f", "-o", "-2"]); .try_get_matches_from(vec!["", "-f", "-o", "-2"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -397,12 +410,12 @@ fn leading_hyphen_with_flag_before() {
fn leading_hyphen_with_only_pos_follows() { fn leading_hyphen_with_only_pos_follows() {
let r = App::new("mvae") let r = App::new("mvae")
.arg( .arg(
Arg::from("-o [opt]... 'some opt'") arg!(o: -o [opt] ... "some opt")
.number_of_values(1) .number_of_values(1)
.setting(ArgSettings::TakesValue) .setting(ArgSettings::TakesValue)
.setting(ArgSettings::AllowHyphenValues), .setting(ArgSettings::AllowHyphenValues),
) )
.arg("[arg] 'some arg'") .arg(arg!([arg] "some arg"))
.try_get_matches_from(vec!["", "-o", "-2", "--", "val"]); .try_get_matches_from(vec!["", "-o", "-2", "--", "val"]);
assert!(r.is_ok(), "{:?}", r); assert!(r.is_ok(), "{:?}", r);
let m = r.unwrap(); 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] #[test]
fn issue_1047_min_zero_vals_default_val() { fn issue_1047_min_zero_vals_default_val() {
let m = App::new("foo") 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> { fn issue_1105_setup(argv: Vec<&'static str>) -> Result<ArgMatches, clap::Error> {
App::new("opts") App::new("opts")
.arg(Arg::from("-o, --option [opt] 'some option'")) .arg(arg!(-o --option <opt> "some option"))
.arg(Arg::from("--flag 'some flag'")) .arg(arg!(--flag "some flag"))
.try_get_matches_from(argv) .try_get_matches_from(argv)
} }
@ -531,7 +530,7 @@ fn issue_1073_suboptimal_flag_suggestion() {
#[test] #[test]
fn short_non_ascii_no_space() { fn short_non_ascii_no_space() {
let matches = App::new("app") let matches = App::new("app")
.arg("<opt> -磨 <opt>") .arg(arg!(opt: -'磨' <opt>))
.get_matches_from(&["test", "-磨VALUE"]); .get_matches_from(&["test", "-磨VALUE"]);
assert_eq!("VALUE", matches.value_of("opt").unwrap()); assert_eq!("VALUE", matches.value_of("opt").unwrap());
@ -540,7 +539,7 @@ fn short_non_ascii_no_space() {
#[test] #[test]
fn short_eq_val_starts_with_eq() { fn short_eq_val_starts_with_eq() {
let matches = App::new("app") let matches = App::new("app")
.arg("<opt> -f <opt>") .arg(arg!(opt: -f <opt>))
.get_matches_from(&["test", "-f==value"]); .get_matches_from(&["test", "-f==value"]);
assert_eq!("=value", matches.value_of("opt").unwrap()); assert_eq!("=value", matches.value_of("opt").unwrap());
@ -549,7 +548,7 @@ fn short_eq_val_starts_with_eq() {
#[test] #[test]
fn long_eq_val_starts_with_eq() { fn long_eq_val_starts_with_eq() {
let matches = App::new("app") let matches = App::new("app")
.arg("<opt> --foo <opt>") .arg(arg!(opt: --foo <opt>))
.get_matches_from(&["test", "--foo==value"]); .get_matches_from(&["test", "--foo==value"]);
assert_eq!("=value", matches.value_of("opt").unwrap()); 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] #[test]
fn only_pos_follow() { fn only_pos_follow() {
let r = App::new("onlypos") let r = App::new("onlypos")
.args(&[ .args(&[arg!(f: -f [flag] "some opt"), arg!([arg] "some arg")])
Arg::from("-f [flag] 'some opt'"),
Arg::from("[arg] 'some arg'"),
])
.try_get_matches_from(vec!["", "--", "-f"]); .try_get_matches_from(vec!["", "--", "-f"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -19,7 +16,7 @@ fn only_pos_follow() {
fn issue_946() { fn issue_946() {
let r = App::new("compiletest") let r = App::new("compiletest")
.setting(clap::AppSettings::AllowLeadingHyphen) .setting(clap::AppSettings::AllowLeadingHyphen)
.arg("--exact 'filters match exactly'") .arg(arg!(--exact "filters match exactly"))
.arg( .arg(
clap::Arg::new("filter") clap::Arg::new("filter")
.index(1) .index(1)
@ -37,10 +34,7 @@ fn issue_946() {
#[test] #[test]
fn positional() { fn positional() {
let r = App::new("positional") let r = App::new("positional")
.args(&[ .args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
Arg::from("-f, --flag 'some flag'"),
Arg::new("positional").index(1),
])
.try_get_matches_from(vec!["", "-f", "test"]); .try_get_matches_from(vec!["", "-f", "test"]);
assert!(r.is_ok(), "{:#?}", r); assert!(r.is_ok(), "{:#?}", r);
let m = r.unwrap(); let m = r.unwrap();
@ -49,10 +43,7 @@ fn positional() {
assert_eq!(m.value_of("positional").unwrap(), "test"); assert_eq!(m.value_of("positional").unwrap(), "test");
let m = App::new("positional") let m = App::new("positional")
.args(&[ .args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
Arg::from("-f, --flag 'some flag'"),
Arg::new("positional").index(1),
])
.get_matches_from(vec!["", "test", "--flag"]); .get_matches_from(vec!["", "test", "--flag"]);
assert!(m.is_present("positional")); assert!(m.is_present("positional"));
assert!(m.is_present("flag")); assert!(m.is_present("flag"));
@ -62,7 +53,7 @@ fn positional() {
#[test] #[test]
fn lots_o_vals() { fn lots_o_vals() {
let r = App::new("opts") let r = App::new("opts")
.arg(Arg::from("[opt]... 'some pos'")) .arg(arg!(<opt>... "some pos"))
.try_get_matches_from(vec![ .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", "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() { fn positional_multiple() {
let r = App::new("positional_multiple") let r = App::new("positional_multiple")
.args(&[ .args(&[
Arg::from("-f, --flag 'some flag'"), arg!(-f --flag "some flag"),
Arg::new("positional") Arg::new("positional")
.index(1) .index(1)
.takes_value(true) .takes_value(true)
@ -124,7 +115,7 @@ fn positional_multiple() {
fn positional_multiple_3() { fn positional_multiple_3() {
let r = App::new("positional_multiple") let r = App::new("positional_multiple")
.args(&[ .args(&[
Arg::from("-f, --flag 'some flag'"), arg!(-f --flag "some flag"),
Arg::new("positional") Arg::new("positional")
.index(1) .index(1)
.takes_value(true) .takes_value(true)
@ -144,10 +135,7 @@ fn positional_multiple_3() {
#[test] #[test]
fn positional_multiple_2() { fn positional_multiple_2() {
let result = App::new("positional_multiple") let result = App::new("positional_multiple")
.args(&[ .args(&[arg!(-f --flag "some flag"), Arg::new("positional").index(1)])
Arg::from("-f, --flag 'some flag'"),
Arg::new("positional").index(1),
])
.try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]); .try_get_matches_from(vec!["", "-f", "test1", "test2", "test3"]);
assert!(result.is_err()); assert!(result.is_err());
let err = result.err().unwrap(); let err = result.err().unwrap();
@ -158,7 +146,7 @@ fn positional_multiple_2() {
fn positional_possible_values() { fn positional_possible_values() {
let r = App::new("positional_possible_values") let r = App::new("positional_possible_values")
.args(&[ .args(&[
Arg::from("-f, --flag 'some flag'"), arg!(-f --flag "some flag"),
Arg::new("positional").index(1).possible_value("test123"), Arg::new("positional").index(1).possible_value("test123"),
]) ])
.try_get_matches_from(vec!["", "-f", "test123"]); .try_get_matches_from(vec!["", "-f", "test123"]);
@ -188,35 +176,35 @@ fn positional_hyphen_does_not_panic() {
#[test] #[test]
fn single_positional_usage_string() { 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]"); assert_eq!(app.render_usage(), "USAGE:\n test [FILE]");
} }
#[test] #[test]
fn single_positional_multiple_usage_string() { 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]..."); assert_eq!(app.render_usage(), "USAGE:\n test [FILE]...");
} }
#[test] #[test]
fn multiple_positional_usage_string() { fn multiple_positional_usage_string() {
let mut app = App::new("test") let mut app = App::new("test")
.arg("[FILE] 'some file'") .arg(arg!([FILE] "some file"))
.arg("[FILES]... 'some file'"); .arg(arg!([FILES]... "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test [ARGS]"); assert_eq!(app.render_usage(), "USAGE:\n test [ARGS]");
} }
#[test] #[test]
fn multiple_positional_one_required_usage_string() { fn multiple_positional_one_required_usage_string() {
let mut app = App::new("test") let mut app = App::new("test")
.arg("<FILE> 'some file'") .arg(arg!(<FILE> "some file"))
.arg("[FILES]... 'some file'"); .arg(arg!([FILES]... "some file"));
assert_eq!(app.render_usage(), "USAGE:\n test <FILE> [FILES]..."); assert_eq!(app.render_usage(), "USAGE:\n test <FILE> [FILES]...");
} }
#[test] #[test]
fn single_positional_required_usage_string() { 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>"); 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"] with a lower index than a required positional argument"]
fn missing_required() { fn missing_required() {
let _ = App::new("test") let _ = App::new("test")
.arg("[FILE1] 'some file'") .arg(arg!([FILE1] "some file"))
.arg("<FILE2> 'some file'") .arg(arg!(<FILE2> "some file"))
.try_get_matches_from(vec![""]); .try_get_matches_from(vec![""]);
} }
#[test] #[test]
fn missing_required_2() { fn missing_required_2() {
let r = App::new("test") let r = App::new("test")
.arg("<FILE1> 'some file'") .arg(arg!(<FILE1> "some file"))
.arg("<FILE2> 'some file'") .arg(arg!(<FILE2> "some file"))
.try_get_matches_from(vec!["test", "file"]); .try_get_matches_from(vec!["test", "file"]);
assert!(r.is_err()); assert!(r.is_err());
assert_eq!(r.unwrap_err().kind, ErrorKind::MissingRequiredArgument); assert_eq!(r.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
@ -245,9 +233,9 @@ fn missing_required_2() {
#[test] #[test]
fn last_positional() { fn last_positional() {
let r = App::new("test") let r = App::new("test")
.arg("<TARGET> 'some target'") .arg(arg!(<TARGET> "some target"))
.arg("[CORPUS] 'some corpus'") .arg(arg!([CORPUS] "some corpus"))
.arg(Arg::from("[ARGS]... 'some file'").last(true)) .arg(arg!([ARGS]... "some file").last(true))
.try_get_matches_from(vec!["test", "tgt", "--", "arg"]); .try_get_matches_from(vec!["test", "tgt", "--", "arg"]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -257,9 +245,9 @@ fn last_positional() {
#[test] #[test]
fn last_positional_no_double_dash() { fn last_positional_no_double_dash() {
let r = App::new("test") let r = App::new("test")
.arg("<TARGET> 'some target'") .arg(arg!(<TARGET> "some target"))
.arg("[CORPUS] 'some corpus'") .arg(arg!([CORPUS] "some corpus"))
.arg(Arg::from("[ARGS]... 'some file'").last(true)) .arg(arg!([ARGS]... "some file").last(true))
.try_get_matches_from(vec!["test", "tgt", "crp", "arg"]); .try_get_matches_from(vec!["test", "tgt", "crp", "arg"]);
assert!(r.is_err()); assert!(r.is_err());
assert_eq!(r.unwrap_err().kind, ErrorKind::UnknownArgument); assert_eq!(r.unwrap_err().kind, ErrorKind::UnknownArgument);
@ -268,9 +256,9 @@ fn last_positional_no_double_dash() {
#[test] #[test]
fn last_positional_second_to_last_mult() { fn last_positional_second_to_last_mult() {
let r = App::new("test") let r = App::new("test")
.arg("<TARGET> 'some target'") .arg(arg!(<TARGET> "some target"))
.arg("[CORPUS]... 'some corpus'") .arg(arg!([CORPUS]... "some corpus"))
.arg(Arg::from("[ARGS]... 'some file'").last(true)) .arg(arg!([ARGS]... "some file").last(true))
.try_get_matches_from(vec!["test", "tgt", "crp1", "crp2", "--", "arg"]); .try_get_matches_from(vec!["test", "tgt", "crp1", "crp2", "--", "arg"]);
assert!(r.is_ok(), "{:?}", r.unwrap_err().kind); 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] #[test]
fn flag_overrides_itself() { fn flag_overrides_itself() {
let res = App::new("posix") 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"]); .try_get_matches_from(vec!["", "--flag", "--flag"]);
assert!(res.is_ok()); assert!(res.is_ok());
let m = res.unwrap(); let m = res.unwrap();
@ -14,7 +18,7 @@ fn flag_overrides_itself() {
#[test] #[test]
fn mult_flag_overrides_itself() { fn mult_flag_overrides_itself() {
let res = App::new("posix") 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"]); .try_get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
assert!(res.is_ok()); assert!(res.is_ok());
let m = res.unwrap(); let m = res.unwrap();
@ -25,7 +29,11 @@ fn mult_flag_overrides_itself() {
#[test] #[test]
fn option_overrides_itself() { fn option_overrides_itself() {
let res = App::new("posix") 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"]); .try_get_matches_from(vec!["", "--opt=some", "--opt=other"]);
assert!(res.is_ok()); assert!(res.is_ok());
let m = res.unwrap(); let m = res.unwrap();
@ -38,7 +46,8 @@ fn option_overrides_itself() {
fn mult_option_require_delim_overrides_itself() { fn mult_option_require_delim_overrides_itself() {
let res = App::new("posix") let res = App::new("posix")
.arg( .arg(
Arg::from("[opt]... --opt [val]... 'some option'") arg!(--opt <val> ... "some option")
.required(false)
.overrides_with("opt") .overrides_with("opt")
.number_of_values(1) .number_of_values(1)
.takes_value(true) .takes_value(true)
@ -59,7 +68,12 @@ fn mult_option_require_delim_overrides_itself() {
#[test] #[test]
fn mult_option_overrides_itself() { fn mult_option_overrides_itself() {
let res = App::new("posix") 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![ .try_get_matches_from(vec![
"", "",
"--opt", "--opt",
@ -83,7 +97,11 @@ fn mult_option_overrides_itself() {
#[test] #[test]
fn option_use_delim_false_override_itself() { fn option_use_delim_false_override_itself() {
let m = App::new("posix") 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"]); .get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]);
assert!(m.is_present("opt")); assert!(m.is_present("opt"));
assert_eq!(m.occurrences_of("opt"), 1); assert_eq!(m.occurrences_of("opt"), 1);
@ -97,7 +115,7 @@ fn option_use_delim_false_override_itself() {
fn pos_mult_overrides_itself() { fn pos_mult_overrides_itself() {
// opts with multiple // opts with multiple
let res = App::new("posix") 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"]); .try_get_matches_from(vec!["", "some", "other", "value"]);
assert!(res.is_ok()); assert!(res.is_ok());
let m = res.unwrap(); let m = res.unwrap();
@ -111,8 +129,8 @@ fn pos_mult_overrides_itself() {
#[test] #[test]
fn posix_compatible_flags_long() { fn posix_compatible_flags_long() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("--flag 'some flag'").overrides_with("color")) .arg(arg!(--flag "some flag").overrides_with("color"))
.arg(Arg::from("--color 'some other flag'")) .arg(arg!(--color "some other flag"))
.get_matches_from(vec!["", "--flag", "--color"]); .get_matches_from(vec!["", "--flag", "--color"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert!(!m.is_present("flag")); assert!(!m.is_present("flag"));
@ -121,8 +139,8 @@ fn posix_compatible_flags_long() {
#[test] #[test]
fn posix_compatible_flags_long_rev() { fn posix_compatible_flags_long_rev() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("--flag 'some flag'").overrides_with("color")) .arg(arg!(--flag "some flag").overrides_with("color"))
.arg(Arg::from("--color 'some other flag'")) .arg(arg!(--color "some other flag"))
.get_matches_from(vec!["", "--color", "--flag"]); .get_matches_from(vec!["", "--color", "--flag"]);
assert!(!m.is_present("color")); assert!(!m.is_present("color"));
assert!(m.is_present("flag")); assert!(m.is_present("flag"));
@ -131,8 +149,8 @@ fn posix_compatible_flags_long_rev() {
#[test] #[test]
fn posix_compatible_flags_short() { fn posix_compatible_flags_short() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("-f, --flag 'some flag'").overrides_with("color")) .arg(arg!(-f --flag "some flag").overrides_with("color"))
.arg(Arg::from("-c, --color 'some other flag'")) .arg(arg!(-c --color "some other flag"))
.get_matches_from(vec!["", "-f", "-c"]); .get_matches_from(vec!["", "-f", "-c"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert!(!m.is_present("flag")); assert!(!m.is_present("flag"));
@ -141,8 +159,8 @@ fn posix_compatible_flags_short() {
#[test] #[test]
fn posix_compatible_flags_short_rev() { fn posix_compatible_flags_short_rev() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("-f, --flag 'some flag'").overrides_with("color")) .arg(arg!(-f --flag "some flag").overrides_with("color"))
.arg(Arg::from("-c, --color 'some other flag'")) .arg(arg!(-c --color "some other flag"))
.get_matches_from(vec!["", "-c", "-f"]); .get_matches_from(vec!["", "-c", "-f"]);
assert!(!m.is_present("color")); assert!(!m.is_present("color"));
assert!(m.is_present("flag")); assert!(m.is_present("flag"));
@ -151,8 +169,12 @@ fn posix_compatible_flags_short_rev() {
#[test] #[test]
fn posix_compatible_opts_long() { fn posix_compatible_opts_long() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color")) .arg(
.arg(Arg::from("--color [color] 'some other flag'")) 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"]); .get_matches_from(vec!["", "--flag", "some", "--color", "other"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert_eq!(m.value_of("color").unwrap(), "other"); assert_eq!(m.value_of("color").unwrap(), "other");
@ -162,8 +184,12 @@ fn posix_compatible_opts_long() {
#[test] #[test]
fn posix_compatible_opts_long_rev() { fn posix_compatible_opts_long_rev() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color")) .arg(
.arg(Arg::from("--color [color] 'some other flag'")) 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"]); .get_matches_from(vec!["", "--color", "some", "--flag", "other"]);
assert!(!m.is_present("color")); assert!(!m.is_present("color"));
assert!(m.is_present("flag")); assert!(m.is_present("flag"));
@ -173,8 +199,12 @@ fn posix_compatible_opts_long_rev() {
#[test] #[test]
fn posix_compatible_opts_long_equals() { fn posix_compatible_opts_long_equals() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color")) .arg(
.arg(Arg::from("--color [color] 'some other flag'")) 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"]); .get_matches_from(vec!["", "--flag=some", "--color=other"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert_eq!(m.value_of("color").unwrap(), "other"); assert_eq!(m.value_of("color").unwrap(), "other");
@ -184,8 +214,12 @@ fn posix_compatible_opts_long_equals() {
#[test] #[test]
fn posix_compatible_opts_long_equals_rev() { fn posix_compatible_opts_long_equals_rev() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("--flag [flag] 'some flag'").overrides_with("color")) .arg(
.arg(Arg::from("--color [color] 'some other flag'")) 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"]); .get_matches_from(vec!["", "--color=some", "--flag=other"]);
assert!(!m.is_present("color")); assert!(!m.is_present("color"));
assert!(m.is_present("flag")); assert!(m.is_present("flag"));
@ -195,8 +229,12 @@ fn posix_compatible_opts_long_equals_rev() {
#[test] #[test]
fn posix_compatible_opts_short() { fn posix_compatible_opts_short() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("-f [flag] 'some flag'").overrides_with("c")) .arg(
.arg(Arg::from("-c [color] 'some other flag'")) 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"]); .get_matches_from(vec!["", "-f", "some", "-c", "other"]);
assert!(m.is_present("c")); assert!(m.is_present("c"));
assert_eq!(m.value_of("c").unwrap(), "other"); assert_eq!(m.value_of("c").unwrap(), "other");
@ -206,8 +244,12 @@ fn posix_compatible_opts_short() {
#[test] #[test]
fn posix_compatible_opts_short_rev() { fn posix_compatible_opts_short_rev() {
let m = App::new("posix") let m = App::new("posix")
.arg(Arg::from("-f [flag] 'some flag'").overrides_with("c")) .arg(
.arg(Arg::from("-c [color] 'some other flag'")) 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"]); .get_matches_from(vec!["", "-c", "some", "-f", "other"]);
assert!(!m.is_present("c")); assert!(!m.is_present("c"));
assert!(m.is_present("f")); assert!(m.is_present("f"));
@ -217,9 +259,9 @@ fn posix_compatible_opts_short_rev() {
#[test] #[test]
fn conflict_overridden() { fn conflict_overridden() {
let m = App::new("conflict_overridden") let m = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug")) .arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'")) .arg(arg!(-d --debug "other flag"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag")) .arg(arg!(-c --color "third flag").overrides_with("flag"))
.get_matches_from(vec!["", "-f", "-c", "-d"]); .get_matches_from(vec!["", "-f", "-c", "-d"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert!(!m.is_present("flag")); assert!(!m.is_present("flag"));
@ -229,9 +271,9 @@ fn conflict_overridden() {
#[test] #[test]
fn conflict_overridden_2() { fn conflict_overridden_2() {
let result = App::new("conflict_overridden") let result = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug")) .arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'")) .arg(arg!(-d --debug "other flag"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag")) .arg(arg!(-c --color "third flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "-f", "-d", "-c"]); .try_get_matches_from(vec!["", "-f", "-d", "-c"]);
assert!(result.is_ok()); assert!(result.is_ok());
let m = result.unwrap(); let m = result.unwrap();
@ -243,9 +285,9 @@ fn conflict_overridden_2() {
#[test] #[test]
fn conflict_overridden_3() { fn conflict_overridden_3() {
let result = App::new("conflict_overridden") let result = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug")) .arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'")) .arg(arg!(-d --debug "other flag"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag")) .arg(arg!(-c --color "third flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "-d", "-c", "-f"]); .try_get_matches_from(vec!["", "-d", "-c", "-f"]);
assert!(result.is_err()); assert!(result.is_err());
let err = result.err().unwrap(); let err = result.err().unwrap();
@ -255,9 +297,9 @@ fn conflict_overridden_3() {
#[test] #[test]
fn conflict_overridden_4() { fn conflict_overridden_4() {
let m = App::new("conflict_overridden") let m = App::new("conflict_overridden")
.arg(Arg::from("-f, --flag 'some flag'").conflicts_with("debug")) .arg(arg!(-f --flag "some flag").conflicts_with("debug"))
.arg(Arg::from("-d, --debug 'other flag'")) .arg(arg!(-d --debug "other flag"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag")) .arg(arg!(-c --color "third flag").overrides_with("flag"))
.get_matches_from(vec!["", "-d", "-f", "-c"]); .get_matches_from(vec!["", "-d", "-f", "-c"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert!(!m.is_present("flag")); assert!(!m.is_present("flag"));
@ -268,7 +310,7 @@ fn conflict_overridden_4() {
fn pos_required_overridden_by_flag() { fn pos_required_overridden_by_flag() {
let result = App::new("require_overridden") let result = App::new("require_overridden")
.arg(Arg::new("pos").index(1).required(true)) .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"]); .try_get_matches_from(vec!["", "test", "-c"]);
assert!(result.is_ok(), "{:?}", result.unwrap_err()); assert!(result.is_ok(), "{:?}", result.unwrap_err());
} }
@ -277,7 +319,7 @@ fn pos_required_overridden_by_flag() {
fn require_overridden_2() { fn require_overridden_2() {
let m = App::new("require_overridden") let m = App::new("require_overridden")
.arg(Arg::new("req_pos").required(true)) .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"]); .get_matches_from(vec!["", "-c", "req_pos"]);
assert!(!m.is_present("color")); assert!(!m.is_present("color"));
assert!(m.is_present("req_pos")); assert!(m.is_present("req_pos"));
@ -286,9 +328,9 @@ fn require_overridden_2() {
#[test] #[test]
fn require_overridden_3() { fn require_overridden_3() {
let m = App::new("require_overridden") let m = App::new("require_overridden")
.arg(Arg::from("-f, --flag 'some flag'").requires("debug")) .arg(arg!(-f --flag "some flag").requires("debug"))
.arg(Arg::from("-d, --debug 'other flag'")) .arg(arg!(-d --debug "other flag"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag")) .arg(arg!(-c --color "third flag").overrides_with("flag"))
.get_matches_from(vec!["", "-f", "-c"]); .get_matches_from(vec!["", "-f", "-c"]);
assert!(m.is_present("color")); assert!(m.is_present("color"));
assert!(!m.is_present("flag")); assert!(!m.is_present("flag"));
@ -298,9 +340,9 @@ fn require_overridden_3() {
#[test] #[test]
fn require_overridden_4() { fn require_overridden_4() {
let result = App::new("require_overridden") let result = App::new("require_overridden")
.arg(Arg::from("-f, --flag 'some flag'").requires("debug")) .arg(arg!(-f --flag "some flag").requires("debug"))
.arg(Arg::from("-d, --debug 'other flag'")) .arg(arg!(-d --debug "other flag"))
.arg(Arg::from("-c, --color 'third flag'").overrides_with("flag")) .arg(arg!(-c --color "third flag").overrides_with("flag"))
.try_get_matches_from(vec!["", "-c", "-f"]); .try_get_matches_from(vec!["", "-c", "-f"]);
assert!(result.is_err()); assert!(result.is_err());
let err = result.err().unwrap(); let err = result.err().unwrap();

View file

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

View file

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

View file

@ -1,6 +1,6 @@
mod utils; mod utils;
use clap::App; use clap::{arg, App};
static EXAMPLE1_TMPL_S: &str = "{bin} {version} static EXAMPLE1_TMPL_S: &str = "{bin} {version}
{author} {author}
@ -149,12 +149,21 @@ fn get_app() -> App<'static> {
.version("1.0") .version("1.0")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.about("Does awesome things") .about("Does awesome things")
.arg("-c, --config=[FILE] 'Sets a custom config file'") .arg(
.arg("<output> 'Sets an optional output file'") arg!(
.arg("-d... 'Turn debugging information on'") -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( .subcommand(
App::new("test") App::new("test")
.about("does testing things") .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)] #![cfg(windows)]
use clap::{App, Arg}; use clap::{arg, App};
use std::ffi::OsString; use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt; use std::os::windows::ffi::OsStringExt;
@ -23,7 +23,7 @@ fn bad_osstring(ascii: &[u8]) -> OsString {
#[test] #[test]
fn invalid_utf16_lossy_positional() { fn invalid_utf16_lossy_positional() {
let r = App::new("bad_utf16") 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"")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -34,7 +34,7 @@ fn invalid_utf16_lossy_positional() {
#[test] #[test]
fn invalid_utf16_lossy_option_short_space() { fn invalid_utf16_lossy_option_short_space() {
let r = App::new("bad_utf16") 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![ .try_get_matches_from(vec![
OsString::from(""), OsString::from(""),
OsString::from("-a"), OsString::from("-a"),
@ -49,7 +49,7 @@ fn invalid_utf16_lossy_option_short_space() {
#[test] #[test]
fn invalid_utf16_lossy_option_short_equals() { fn invalid_utf16_lossy_option_short_equals() {
let r = App::new("bad_utf16") 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=")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -60,7 +60,7 @@ fn invalid_utf16_lossy_option_short_equals() {
#[test] #[test]
fn invalid_utf16_lossy_option_short_no_space() { fn invalid_utf16_lossy_option_short_no_space() {
let r = App::new("bad_utf16") 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")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -71,7 +71,7 @@ fn invalid_utf16_lossy_option_short_no_space() {
#[test] #[test]
fn invalid_utf16_lossy_option_long_space() { fn invalid_utf16_lossy_option_long_space() {
let r = App::new("bad_utf16") 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![ .try_get_matches_from(vec![
OsString::from(""), OsString::from(""),
OsString::from("--arg"), OsString::from("--arg"),
@ -86,7 +86,7 @@ fn invalid_utf16_lossy_option_long_space() {
#[test] #[test]
fn invalid_utf16_lossy_option_long_equals() { fn invalid_utf16_lossy_option_long_equals() {
let r = App::new("bad_utf16") 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=")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -97,7 +97,7 @@ fn invalid_utf16_lossy_option_long_equals() {
#[test] #[test]
fn invalid_utf16_positional() { fn invalid_utf16_positional() {
let r = App::new("bad_utf16") 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"")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -108,7 +108,7 @@ fn invalid_utf16_positional() {
#[test] #[test]
fn invalid_utf16_option_short_space() { fn invalid_utf16_option_short_space() {
let r = App::new("bad_utf16") 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![ .try_get_matches_from(vec![
OsString::from(""), OsString::from(""),
OsString::from("-a"), OsString::from("-a"),
@ -123,7 +123,7 @@ fn invalid_utf16_option_short_space() {
#[test] #[test]
fn invalid_utf16_option_short_equals() { fn invalid_utf16_option_short_equals() {
let r = App::new("bad_utf16") 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=")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a=")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -134,7 +134,7 @@ fn invalid_utf16_option_short_equals() {
#[test] #[test]
fn invalid_utf16_option_short_no_space() { fn invalid_utf16_option_short_no_space() {
let r = App::new("bad_utf16") 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")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"-a")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();
@ -145,7 +145,7 @@ fn invalid_utf16_option_short_no_space() {
#[test] #[test]
fn invalid_utf16_option_long_space() { fn invalid_utf16_option_long_space() {
let r = App::new("bad_utf16") 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![ .try_get_matches_from(vec![
OsString::from(""), OsString::from(""),
OsString::from("--arg"), OsString::from("--arg"),
@ -160,7 +160,7 @@ fn invalid_utf16_option_long_space() {
#[test] #[test]
fn invalid_utf16_option_long_equals() { fn invalid_utf16_option_long_equals() {
let r = App::new("bad_utf16") 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=")]); .try_get_matches_from(vec![OsString::from(""), bad_osstring(b"--arg=")]);
assert!(r.is_ok()); assert!(r.is_ok());
let m = r.unwrap(); let m = r.unwrap();

View file

@ -5,7 +5,7 @@ use std::str;
use regex::Regex; use regex::Regex;
use clap::{App, Arg, ArgGroup}; use clap::{arg, App, Arg, ArgGroup};
pub fn compare<S, S2>(l: S, r: S2) -> bool pub fn compare<S, S2>(l: S, r: S2) -> bool
where where
@ -59,31 +59,53 @@ pub fn complex_app() -> App<'static> {
.version("v1.4.8") .version("v1.4.8")
.about("tests clap library") .about("tests clap library")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg("[option]... -o --option=[opt]... 'tests options'") .arg(
.arg("[positional] 'tests positionals'") arg!(
.arg(Arg::from("-f --flag... 'tests flags'").global(true)) -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(&[ .args(&[
Arg::from("[flag2] -F 'tests flags with exclusions'") arg!(flag2: -F "tests flags with exclusions")
.conflicts_with("flag") .conflicts_with("flag")
.requires("long-option-2"), .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") .conflicts_with("option")
.requires("positional2"), .requires("positional2"),
Arg::from("[positional2] 'tests positionals with exclusions'"), arg!([positional2] "tests positionals with exclusions"),
Arg::from("-O --option3 [option3] 'specific vals'").possible_values(opt3_vals), arg!(-O --option3 <option3> "specific vals")
Arg::from("[positional3]... 'tests specific values'").possible_values(pos3_vals), .required(false)
Arg::from("--multvals [one] [two] 'Tests multiple values, not mult occs'"), .possible_values(opt3_vals),
Arg::from("--multvalsmo... [one] [two] 'Tests multiple values, and mult occs'"), arg!([positional3] ... "tests specific values").possible_values(pos3_vals),
Arg::from("--minvals2 [minvals]... 'Tests 2 min vals'").min_values(2), arg!(--multvals "Tests multiple values, not mult occs")
Arg::from("--maxvals3 [maxvals]... 'Tests 3 max vals'").max_values(3), .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( .subcommand(
App::new("subcmd") App::new("subcmd")
.about("tests subcommands") .about("tests subcommands")
.version("0.1") .version("0.1")
.author("Kevin K. <kbknapp@gmail.com>") .author("Kevin K. <kbknapp@gmail.com>")
.arg("[option]... -o --option [scoption]... 'tests options'") .arg(
.arg("-s --subcmdarg [subcmdarg] 'tests other args'") arg!(-o --option <scoption> "tests options")
.arg("[scpositional] 'tests positionals'"), .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")] #![cfg(feature = "yaml")]
#![allow(deprecated)]
use clap::{load_yaml, App, Arg, ErrorKind, ValueHint}; use clap::{load_yaml, App, Arg, ErrorKind, ValueHint};
#[test] #[test]
fn create_app_from_yaml() { fn create_app_from_yaml() {
let yaml = load_yaml!("fixtures/app.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 // TODO: Uncomment to test yaml with 2 spaces https://github.com/chyh1990/yaml-rust/issues/101
// #[test] // #[test]
// fn create_app_from_yaml_2spaces() { // fn create_app_from_yaml_2spaces() {
// let yaml = load_yaml!("fixtures/app_2space.yaml"); // let yaml = load_yaml!("fixtures/app_2space.yaml");
// App::from(yaml); // App::from_yaml(yaml);
// } // }
#[test] #[test]
fn help_message() { fn help_message() {
let yaml = load_yaml!("fixtures/app.yaml"); 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! // Generate the full help message!
let _ = app.try_get_matches_from_mut(Vec::<String>::new()); let _ = app.try_get_matches_from_mut(Vec::<String>::new());
@ -33,7 +34,7 @@ fn help_message() {
#[test] #[test]
fn author() { fn author() {
let yaml = load_yaml!("fixtures/app.yaml"); 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! // Generate the full help message!
let _ = app.try_get_matches_from_mut(Vec::<String>::new()); let _ = app.try_get_matches_from_mut(Vec::<String>::new());
@ -46,7 +47,7 @@ fn author() {
#[test] #[test]
fn app_settings() { fn app_settings() {
let yaml = load_yaml!("fixtures/app.yaml"); 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"]); 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"] #[should_panic = "Unknown AppSetting 'random' found in YAML file for app"]
fn app_setting_invalid() { fn app_setting_invalid() {
let yaml = load_yaml!("fixtures/app_setting_invalid.yaml"); let yaml = load_yaml!("fixtures/app_setting_invalid.yaml");
let _ = App::from(yaml); let _ = App::from_yaml(yaml);
} }
#[test] #[test]
#[should_panic = "Unknown ArgSetting 'random' found in YAML file for arg 'option'"] #[should_panic = "Unknown ArgSetting 'random' found in YAML file for arg 'option'"]
fn arg_setting_invalid() { fn arg_setting_invalid() {
let yaml = load_yaml!("fixtures/arg_setting_invalid.yaml"); 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 // ValueHint must be parsed correctly from Yaml
#[test] #[test]
fn value_hint() { fn value_hint() {
let yml = load_yaml!("fixtures/app.yaml"); let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml); let app = App::from_yaml(yml);
let arg = app let arg = app
.get_arguments() .get_arguments()
@ -87,7 +88,7 @@ fn value_hint() {
#[test] #[test]
fn default_value_if_not_triggered_by_argument() { fn default_value_if_not_triggered_by_argument() {
let yml = load_yaml!("fixtures/app.yaml"); let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml); let app = App::from_yaml(yml);
// Fixtures use "other" as value // Fixtures use "other" as value
let matches = app.try_get_matches_from(vec!["prog", "wrong"]).unwrap(); let matches = app.try_get_matches_from(vec!["prog", "wrong"]).unwrap();
@ -98,7 +99,7 @@ fn default_value_if_not_triggered_by_argument() {
#[test] #[test]
fn default_value_if_triggered_by_matching_argument() { fn default_value_if_triggered_by_matching_argument() {
let yml = load_yaml!("fixtures/app.yaml"); 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(); let matches = app.try_get_matches_from(vec!["prog", "other"]).unwrap();
assert_eq!(matches.value_of("positional2").unwrap(), "something"); assert_eq!(matches.value_of("positional2").unwrap(), "something");
@ -107,7 +108,7 @@ fn default_value_if_triggered_by_matching_argument() {
#[test] #[test]
fn default_value_if_triggered_by_flag() { fn default_value_if_triggered_by_flag() {
let yml = load_yaml!("fixtures/app.yaml"); let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml); let app = App::from_yaml(yml);
let matches = app let matches = app
.try_get_matches_from(vec!["prog", "--flag", "flagvalue"]) .try_get_matches_from(vec!["prog", "--flag", "flagvalue"])
@ -119,7 +120,7 @@ fn default_value_if_triggered_by_flag() {
#[test] #[test]
fn default_value_if_triggered_by_flag_and_argument() { fn default_value_if_triggered_by_flag_and_argument() {
let yml = load_yaml!("fixtures/app.yaml"); let yml = load_yaml!("fixtures/app.yaml");
let app = App::from(yml); let app = App::from_yaml(yml);
let matches = app let matches = app
.try_get_matches_from(vec!["prog", "--flag", "flagvalue", "other"]) .try_get_matches_from(vec!["prog", "--flag", "flagvalue", "other"])
@ -132,7 +133,7 @@ fn default_value_if_triggered_by_flag_and_argument() {
#[test] #[test]
fn yaml_multiple_occurrences() { fn yaml_multiple_occurrences() {
let yaml = load_yaml!("fixtures/app.yaml"); 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"]) .try_get_matches_from(vec!["prog", "-vvv"])
.unwrap(); .unwrap();
assert_eq!(matches.occurrences_of("verbose"), 3); assert_eq!(matches.occurrences_of("verbose"), 3);
@ -141,7 +142,7 @@ fn yaml_multiple_occurrences() {
#[test] #[test]
fn yaml_multiple_values() { fn yaml_multiple_values() {
let yaml = load_yaml!("fixtures/app.yaml"); 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"]) .try_get_matches_from(vec!["prog", "-s", "aaa", "bbb"])
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@ -157,7 +158,7 @@ fn yaml_multiple_values() {
#[test] #[test]
fn regex_with_invalid_string() { fn regex_with_invalid_string() {
let yml = load_yaml!("fixtures/app_regex.yaml"); 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"]); let res = app.try_get_matches_from(vec!["prog", "not a proper filter"]);
assert!(res.is_err()); assert!(res.is_err());
@ -167,7 +168,7 @@ fn regex_with_invalid_string() {
#[test] #[test]
fn regex_with_valid_string() { fn regex_with_valid_string() {
let yml = load_yaml!("fixtures/app_regex.yaml"); 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(); let matches = app.try_get_matches_from(vec!["prog", "*.txt"]).unwrap();
@ -179,89 +180,89 @@ fn regex_with_valid_string() {
#[should_panic] #[should_panic]
fn regex_with_invalid_yaml() { fn regex_with_invalid_yaml() {
let yml = load_yaml!("fixtures/app_regex_invalid.yaml"); let yml = load_yaml!("fixtures/app_regex_invalid.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
fn extra_fields() { fn extra_fields() {
let yml = load_yaml!("fixtures/extra_fields.yaml"); let yml = load_yaml!("fixtures/extra_fields.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Unknown setting 'random' in YAML file for arg 'option'"] #[should_panic = "Unknown setting 'random' in YAML file for arg 'option'"]
fn extra_fields_invalid_arg() { fn extra_fields_invalid_arg() {
let yml = load_yaml!("fixtures/extra_fields_invalid_arg.yaml"); let yml = load_yaml!("fixtures/extra_fields_invalid_arg.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Unknown setting 'random' in YAML file for subcommand 'info'"] #[should_panic = "Unknown setting 'random' in YAML file for subcommand 'info'"]
fn extra_fields_invalid_app() { fn extra_fields_invalid_app() {
let yml = load_yaml!("fixtures/extra_fields_invalid_app.yaml"); let yml = load_yaml!("fixtures/extra_fields_invalid_app.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "YAML file must be a hash"] #[should_panic = "YAML file must be a hash"]
fn app_not_hash() { fn app_not_hash() {
let yml = load_yaml!("fixtures/not_hash.yaml"); let yml = load_yaml!("fixtures/not_hash.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "YAML file must be a hash"] #[should_panic = "YAML file must be a hash"]
fn arg_file_not_hash() { fn arg_file_not_hash() {
let yml = load_yaml!("fixtures/not_hash.yaml"); let yml = load_yaml!("fixtures/not_hash.yaml");
let _ = Arg::from(yml); let _ = Arg::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Subcommand must be a hash"] #[should_panic = "Subcommand must be a hash"]
fn subcommand_not_hash() { fn subcommand_not_hash() {
let yml = load_yaml!("fixtures/field_not_hash.yaml"); let yml = load_yaml!("fixtures/field_not_hash.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Arg must be a hash"] #[should_panic = "Arg must be a hash"]
fn arg_not_hash() { fn arg_not_hash() {
let yml = load_yaml!("fixtures/arg_not_hash.yaml"); let yml = load_yaml!("fixtures/arg_not_hash.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Subcommand name must be a string"] #[should_panic = "Subcommand name must be a string"]
fn subcommand_name_not_string() { fn subcommand_name_not_string() {
let yml = load_yaml!("fixtures/name_not_string.yaml"); let yml = load_yaml!("fixtures/name_not_string.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Arg name must be a string"] #[should_panic = "Arg name must be a string"]
fn arg_name_not_string() { fn arg_name_not_string() {
let yml = load_yaml!("fixtures/name_not_string.yaml"); let yml = load_yaml!("fixtures/name_not_string.yaml");
let _ = Arg::from(yml); let _ = Arg::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "App fields must be strings"] #[should_panic = "App fields must be strings"]
fn app_field_not_string() { fn app_field_not_string() {
let yml = load_yaml!("fixtures/app_field_not_string.yaml"); let yml = load_yaml!("fixtures/app_field_not_string.yaml");
let _ = App::from(yml); let _ = App::from_yaml(yml);
} }
#[test] #[test]
#[should_panic = "Arg fields must be strings"] #[should_panic = "Arg fields must be strings"]
fn arg_field_not_string() { fn arg_field_not_string() {
let yml = load_yaml!("fixtures/arg_field_not_string.yaml"); let yml = load_yaml!("fixtures/arg_field_not_string.yaml");
let _ = Arg::from(yml); let _ = Arg::from_yaml(yml);
} }
#[test] #[test]
fn multiple_groups() { fn multiple_groups() {
let yml = load_yaml!("fixtures/multiple_groups.yaml"); 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); eprintln!("{:?}", matches);
assert!(matches.is_ok()); assert!(matches.is_ok());
} }