Skip to content

Commit

Permalink
Merge pull request #3814 from epage/contains
Browse files Browse the repository at this point in the history
feat(parser): Provide updated version of 'is_present'
  • Loading branch information
epage committed Jun 10, 2022
2 parents d5e2622 + 9caec5a commit 1c462be
Show file tree
Hide file tree
Showing 56 changed files with 1,244 additions and 1,274 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ _gated behind `unstable-v4`_
- Default `ValueParser` is determined by `value_parser!` (#3199, #3496)
- Default `ArgAction` is determine by a hard-coded lookup on the type (#3794)
- `Command::multicall` is now stable for busybox-like programs and REPLs (#2861, #3684)
- `ArgMatches::{try_,}contains_id` for checking if there are values for an argument that mirrors the new `get_{one,many}` API

### Fixes

Expand Down Expand Up @@ -96,6 +97,7 @@ Replaced
- `ArgMatches::{values_of, values_of_os, values_of_os_lossy, values_of_t}` with `ArgMatches::{get_many,remove_many}` (#3753)
- `ArgMatches::is_valid_arg` with `ArgMatches::{try_get_one,try_get_many}` (#3753)
- `ArgMatches::occurrences_of` with `ArgMatches::value_source` or `ArgAction::Count` (#3797)
- `ArgMatches::is_present` with `ArgMatches::contains_id` or `ArgAction::SetTrue` (#3797)
- `ArgAction::StoreValue` with `ArgAction::Set` or `ArgAction::Append` (#3797)
- `ArgAction::IncOccurrences` with `ArgAction::SetTrue` or `ArgAction::Count` (#3797)
- *(derive)* `#[clap(parse(from_flag))]` replaced with `#[clap(action = ArgAction::SetTrue)]` (#3794)
Expand Down
6 changes: 3 additions & 3 deletions clap_derive/src/derives/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ fn gen_parsers(
}

Ty::OptionOption => quote_spanned! { ty.span()=>
if #arg_matches.is_present(#id) {
if #arg_matches.contains_id(#id) {
Some(
#arg_matches.#get_one(#id)
.map(#deref)
Expand All @@ -675,7 +675,7 @@ fn gen_parsers(
},

Ty::OptionVec => quote_spanned! { ty.span()=>
if #arg_matches.is_present(#id) {
if #arg_matches.contains_id(#id) {
Some(#arg_matches.#get_many(#id)
.map(|v| v.map(#deref).map::<::std::result::Result<#convert_type, clap::Error>, _>(#parse).collect::<::std::result::Result<Vec<_>, clap::Error>>())
.transpose()?
Expand Down Expand Up @@ -724,7 +724,7 @@ fn gen_parsers(

if let Some(access) = update {
quote_spanned! { field.span()=>
if #arg_matches.is_present(#id) {
if #arg_matches.contains_id(#id) {
#access
*#field_name = #field_value
}
Expand Down
2 changes: 1 addition & 1 deletion clap_derive/src/derives/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ fn gen_from_arg_matches(

if cfg!(feature = "unstable-v4") {
quote! {
if #sub_name == #subcommand_name_var && !#sub_arg_matches_var.is_present("") {
if #sub_name == #subcommand_name_var && !#sub_arg_matches_var.contains_id("") {
return ::std::result::Result::Ok(#name :: #variant_name #constructor_block)
}
}
Expand Down
44 changes: 32 additions & 12 deletions examples/derive_ref/flatten_hand_args.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clap::error::Error;
use clap::{Arg, ArgMatches, Args, Command, FromArgMatches, Parser};
use clap::{Arg, ArgAction, ArgMatches, Args, Command, FromArgMatches, Parser};

#[derive(Debug)]
struct CliArgs {
Expand All @@ -15,8 +15,8 @@ impl FromArgMatches for CliArgs {
}
fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result<Self, Error> {
Ok(Self {
foo: matches.is_present("foo"),
bar: matches.is_present("bar"),
foo: *matches.get_one::<bool>("foo").expect("defaulted by clap"),
bar: *matches.get_one::<bool>("bar").expect("defaulted by clap"),
quuz: matches.remove_one::<String>("quuz"),
})
}
Expand All @@ -25,8 +25,8 @@ impl FromArgMatches for CliArgs {
self.update_from_arg_matches_mut(&mut matches)
}
fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> {
self.foo |= matches.is_present("foo");
self.bar |= matches.is_present("bar");
self.foo |= *matches.get_one::<bool>("foo").expect("defaulted by clap");
self.bar |= *matches.get_one::<bool>("bar").expect("defaulted by clap");
if let Some(quuz) = matches.remove_one::<String>("quuz") {
self.quuz = Some(quuz);
}
Expand All @@ -36,20 +36,40 @@ impl FromArgMatches for CliArgs {

impl Args for CliArgs {
fn augment_args(cmd: Command<'_>) -> Command<'_> {
cmd.arg(Arg::new("foo").short('f').long("foo"))
.arg(Arg::new("bar").short('b').long("bar"))
.arg(Arg::new("quuz").short('q').long("quuz").takes_value(true))
cmd.arg(
Arg::new("foo")
.short('f')
.long("foo")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("bar")
.short('b')
.long("bar")
.action(ArgAction::SetTrue),
)
.arg(Arg::new("quuz").short('q').long("quuz").takes_value(true))
}
fn augment_args_for_update(cmd: Command<'_>) -> Command<'_> {
cmd.arg(Arg::new("foo").short('f').long("foo"))
.arg(Arg::new("bar").short('b').long("bar"))
.arg(Arg::new("quuz").short('q').long("quuz").takes_value(true))
cmd.arg(
Arg::new("foo")
.short('f')
.long("foo")
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("bar")
.short('b')
.long("bar")
.action(ArgAction::SetTrue),
)
.arg(Arg::new("quuz").short('q').long("quuz").takes_value(true))
}
}

#[derive(Parser, Debug)]
struct Cli {
#[clap(short, long)]
#[clap(short, long, action)]
top_level: bool,
#[clap(flatten)]
more_args: CliArgs,
Expand Down
9 changes: 6 additions & 3 deletions examples/escaped-positional.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Note: this requires the `cargo` feature

use clap::{arg, command, value_parser};
use clap::{arg, command, value_parser, ArgAction};

fn main() {
let matches = command!()
.arg(arg!(eff: -f))
.arg(arg!(eff: -f).action(ArgAction::SetTrue))
.arg(
arg!(pea: -p <PEAR>)
.required(false)
Expand All @@ -22,7 +22,10 @@ fn main() {
// This is what will happen with `myprog -f -p=bob -- sloppy slop slop`...

// -f used: true
println!("-f used: {:?}", matches.is_present("eff"));
println!(
"-f used: {:?}",
*matches.get_one::<bool>("eff").expect("defaulted by clap")
);
// -p's value: Some("bob")
println!("-p's value: {:?}", matches.get_one::<String>("pea"));
// 'slops' values: Some(["sloppy", "slop", "slop"])
Expand Down
2 changes: 1 addition & 1 deletion examples/multicall-busybox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn main() {
let matches = cmd.get_matches();
let mut subcommand = matches.subcommand();
if let Some(("busybox", cmd)) = subcommand {
if cmd.is_present("install") {
if cmd.contains_id("install") {
unimplemented!("Make hardlinks to the executable here");
}
subcommand = cmd.subcommand();
Expand Down
12 changes: 8 additions & 4 deletions examples/pacman.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use clap::{Arg, Command};
use clap::{Arg, ArgAction, Command};

fn main() {
let matches = Command::new("pacman")
Expand Down Expand Up @@ -56,6 +56,7 @@ fn main() {
.long("info")
.conflicts_with("search")
.short('i')
.action(ArgAction::SetTrue)
.help("view package information"),
)
.arg(
Expand All @@ -70,10 +71,10 @@ fn main() {

match matches.subcommand() {
Some(("sync", sync_matches)) => {
if sync_matches.is_present("search") {
if sync_matches.contains_id("search") {
let packages: Vec<_> = sync_matches
.get_many::<String>("search")
.expect("is present")
.expect("contains_id")
.map(|s| s.as_str())
.collect();
let values = packages.join(", ");
Expand All @@ -88,7 +89,10 @@ fn main() {
.collect();
let values = packages.join(", ");

if sync_matches.is_present("info") {
if *sync_matches
.get_one::<bool>("info")
.expect("defaulted by clap")
{
println!("Retrieving info for {}...", values);
} else {
println!("Installing {}...", values);
Expand Down
4 changes: 2 additions & 2 deletions examples/tutorial_builder/01_quick.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn main() {
.subcommand(
Command::new("test")
.about("does testing things")
.arg(arg!(-l --list "lists test values")),
.arg(arg!(-l --list "lists test values").action(ArgAction::SetTrue)),
)
.get_matches();

Expand Down Expand Up @@ -53,7 +53,7 @@ fn main() {
// matches just as you would the top level cmd
if let Some(matches) = matches.subcommand_matches("test") {
// "$ myapp test" was run
if matches.is_present("list") {
if *matches.get_one::<bool>("list").expect("defaulted by clap") {
// "$ myapp test -l" was run
println!("Printing testing lists...");
} else {
Expand Down
18 changes: 15 additions & 3 deletions examples/tutorial_builder/03_01_flag_bool.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
// Note: this requires the `cargo` feature

use clap::{arg, command};
use clap::{command, Arg, ArgAction};

fn main() {
let matches = command!().arg(arg!(-v - -verbose)).get_matches();
let matches = command!()
.arg(
Arg::new("verbose")
.short('v')
.long("verbose")
.action(ArgAction::SetTrue),
)
.get_matches();

println!("verbose: {:?}", matches.is_present("verbose"));
println!(
"verbose: {:?}",
*matches
.get_one::<bool>("verbose")
.expect("defaulted by clap")
);
}
16 changes: 8 additions & 8 deletions examples/tutorial_builder/04_03_relations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

use std::path::PathBuf;

use clap::{arg, command, value_parser, ArgGroup};
use clap::{arg, command, value_parser, ArgAction, ArgGroup};

fn main() {
// Create application like normal
let matches = command!()
// Add the version arguments
.arg(arg!(--"set-ver" <VER> "set version manually").required(false))
.arg(arg!(--major "auto inc major"))
.arg(arg!(--minor "auto inc minor"))
.arg(arg!(--patch "auto inc patch"))
.arg(arg!(--major "auto inc major").action(ArgAction::SetTrue))
.arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue))
.arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue))
// Create a group, make it required, and add the above arguments
.group(
ArgGroup::new("vers")
Expand Down Expand Up @@ -52,9 +52,9 @@ fn main() {
} else {
// Increment the one requested (in a real program, we'd reset the lower numbers)
let (maj, min, pat) = (
matches.is_present("major"),
matches.is_present("minor"),
matches.is_present("patch"),
*matches.get_one::<bool>("major").expect("defaulted by clap"),
*matches.get_one::<bool>("minor").expect("defaulted by clap"),
*matches.get_one::<bool>("patch").expect("defaulted by clap"),
);
match (maj, min, pat) {
(true, _, _) => major += 1,
Expand All @@ -68,7 +68,7 @@ fn main() {
println!("Version: {}", version);

// Check for usage of -c
if matches.is_present("config") {
if matches.contains_id("config") {
let input = matches
.get_one::<PathBuf>("INPUT_FILE")
.unwrap_or_else(|| matches.get_one::<PathBuf>("spec-in").unwrap())
Expand Down
20 changes: 11 additions & 9 deletions examples/tutorial_builder/04_04_custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

use std::path::PathBuf;

use clap::{arg, command, value_parser, ErrorKind};
use clap::{arg, command, value_parser, ArgAction, ErrorKind};

fn main() {
// Create application like normal
let mut cmd = command!()
// Add the version arguments
.arg(arg!(--"set-ver" <VER> "set version manually").required(false))
.arg(arg!(--major "auto inc major"))
.arg(arg!(--minor "auto inc minor"))
.arg(arg!(--patch "auto inc patch"))
.arg(arg!(--major "auto inc major").action(ArgAction::SetTrue))
.arg(arg!(--minor "auto inc minor").action(ArgAction::SetTrue))
.arg(arg!(--patch "auto inc patch").action(ArgAction::SetTrue))
// Arguments can also be added to a group individually, these two arguments
// are part of the "input" group which is not required
.arg(arg!([INPUT_FILE] "some regular input").value_parser(value_parser!(PathBuf)))
Expand All @@ -36,7 +36,9 @@ fn main() {

// See if --set-ver was used to set the version manually
let version = if let Some(ver) = matches.get_one::<String>("set-ver") {
if matches.is_present("major") || matches.is_present("minor") || matches.is_present("patch")
if *matches.get_one::<bool>("major").expect("defaulted by clap")
|| *matches.get_one::<bool>("minor").expect("defaulted by clap")
|| *matches.get_one::<bool>("patch").expect("defaulted by clap")
{
cmd.error(
ErrorKind::ArgumentConflict,
Expand All @@ -48,9 +50,9 @@ fn main() {
} else {
// Increment the one requested (in a real program, we'd reset the lower numbers)
let (maj, min, pat) = (
matches.is_present("major"),
matches.is_present("minor"),
matches.is_present("patch"),
*matches.get_one::<bool>("major").expect("defaulted by clap"),
*matches.get_one::<bool>("minor").expect("defaulted by clap"),
*matches.get_one::<bool>("patch").expect("defaulted by clap"),
);
match (maj, min, pat) {
(true, false, false) => major += 1,
Expand All @@ -70,7 +72,7 @@ fn main() {
println!("Version: {}", version);

// Check for usage of -c
if matches.is_present("config") {
if matches.contains_id("config") {
let input = matches
.get_one::<PathBuf>("INPUT_FILE")
.or_else(|| matches.get_one::<PathBuf>("spec-in"))
Expand Down
8 changes: 1 addition & 7 deletions examples/tutorial_builder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,7 @@ $ 03_01_flag_bool --verbose
verbose: true

$ 03_01_flag_bool --verbose --verbose
? failed
error: The argument '--verbose' was provided more than once, but cannot be used multiple times

USAGE:
03_01_flag_bool[EXE] [OPTIONS]

For more information try --help
verbose: true

```

Expand Down

0 comments on commit 1c462be

Please sign in to comment.