clap/examples/23_flag_subcommands_pacman.rs
Ed Page 7e899cd340 Revert "Deprecate Arg::help in favour of Arg::about"
This reverts commits 24cb8b1..d0abb37 from clap-rs/clap#1840

This is part of #16.  clap-rs/clap#1840 wasn't the right call but we
don't have time to make the decision now, so instead of having one
option and changing it in 4.0, this reverts back to clap2 behavior.
2021-11-18 12:25:49 -06:00

121 lines
4.8 KiB
Rust

// This feature allows users of the app to pass subcommands in the fashion of short or long flags.
// You may be familiar with it if you ever used [`pacman`](https://wiki.archlinux.org/index.php/pacman).
// Some made up examples of what flag subcommands are:
//
// ```shell
// $ pacman -S
// ^--- short flag subcommand.
// $ pacman --sync
// ^--- long flag subcommand.
// $ pacman -Ss
// ^--- short flag subcommand followed by a short flag
// (users can "stack" short subcommands with short flags or with other short flag subcommands)
// $ pacman -S -s
// ^--- same as above
// $ pacman -S --sync
// ^--- short flag subcommand followed by a long flag
// ```
// NOTE: Keep in mind that subcommands, flags, and long flags are *case sensitive*: `-Q` and `-q` are different flags/subcommands. For example, you can have both `-Q` subcommand and `-q` flag, and they will be properly disambiguated.
// Let's make a quick program to illustrate.
use clap::{App, AppSettings, Arg};
fn main() {
let matches = App::new("pacman")
.about("package manager utility")
.version("5.2.1")
.setting(AppSettings::SubcommandRequiredElseHelp)
.author("Pacman Development Team")
// Query subcommand
//
// Only a few of its arguments are implemented below.
.subcommand(
App::new("query")
.short_flag('Q')
.long_flag("query")
.about("Query the package database.")
.arg(
Arg::new("search")
.short('s')
.long("search")
.help("search locally installed packages for matching strings")
.conflicts_with("info")
.takes_value(true)
.multiple_values(true),
)
.arg(
Arg::new("info")
.long("info")
.short('i')
.conflicts_with("search")
.help("view package information")
.takes_value(true)
.multiple_values(true),
),
)
// Sync subcommand
//
// Only a few of its arguments are implemented below.
.subcommand(
App::new("sync")
.short_flag('S')
.long_flag("sync")
.about("Synchronize packages.")
.arg(
Arg::new("search")
.short('s')
.long("search")
.conflicts_with("info")
.takes_value(true)
.multiple_values(true)
.help("search remote repositories for matching strings"),
)
.arg(
Arg::new("info")
.long("info")
.conflicts_with("search")
.short('i')
.help("view package information"),
)
.arg(
Arg::new("package")
.help("packages")
.required_unless_present("search")
.takes_value(true)
.multiple_values(true),
),
)
.get_matches();
match matches.subcommand() {
Some(("sync", sync_matches)) => {
if sync_matches.is_present("search") {
let packages: Vec<_> = sync_matches.values_of("search").unwrap().collect();
let values = packages.join(", ");
println!("Searching for {}...", values);
return;
}
let packages: Vec<_> = sync_matches.values_of("package").unwrap().collect();
let values = packages.join(", ");
if sync_matches.is_present("info") {
println!("Retrieving info for {}...", values);
} else {
println!("Installing {}...", values);
}
}
Some(("query", query_matches)) => {
if let Some(packages) = query_matches.values_of("info") {
let comma_sep = packages.collect::<Vec<_>>().join(", ");
println!("Retrieving info for {}...", comma_sep);
} else if let Some(queries) = query_matches.values_of("search") {
let comma_sep = queries.collect::<Vec<_>>().join(", ");
println!("Searching Locally for {}...", comma_sep);
} else {
println!("Displaying all locally installed packages...");
}
}
_ => unreachable!(), // If all subcommands are defined above, anything else is unreachable
}
}