Module clap::_tutorial::chapter_2

source ·
Available on crate feature unstable-doc only.
Expand description

§Adding Arguments

  1. Positionals
  2. Options
  3. Flags
  4. Subcommands
  5. Defaults

§Positionals

You can have users specify values by their position on the command-line:

use clap::{command, Arg};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name"))
        .get_matches();

    println!("name: {:?}", matches.get_one::<String>("name"));
}
$ 03_03_positional --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_03_positional[EXE] [name]

Arguments:
  [name]  

Options:
  -h, --help     Print help
  -V, --version  Print version

$ 03_03_positional
name: None

$ 03_03_positional bob
name: Some("bob")

Note that the default ArgAction is Set. To accept multiple values, override the action with Append:

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

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name").action(ArgAction::Append))
        .get_matches();

    let args = matches
        .get_many::<String>("name")
        .unwrap_or_default()
        .map(|v| v.as_str())
        .collect::<Vec<_>>();

    println!("names: {:?}", &args);
}
$ 03_03_positional_mult --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_03_positional_mult[EXE] [name]...

Arguments:
  [name]...  

Options:
  -h, --help     Print help
  -V, --version  Print version

$ 03_03_positional_mult
names: []

$ 03_03_positional_mult bob
names: ["bob"]

$ 03_03_positional_mult bob john
names: ["bob", "john"]

§Options

You can name your arguments with a flag:

  • Order doesn’t matter
  • They can be optional
  • Intent is clearer
use clap::{command, Arg};

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(Arg::new("name").short('n').long("name"))
        .get_matches();

    println!("name: {:?}", matches.get_one::<String>("name"));
}
$ 03_02_option --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_02_option[EXE] [OPTIONS]

Options:
  -n, --name <name>  
  -h, --help         Print help
  -V, --version      Print version

$ 03_02_option
name: None

$ 03_02_option --name bob
name: Some("bob")

$ 03_02_option --name=bob
name: Some("bob")

$ 03_02_option -n bob
name: Some("bob")

$ 03_02_option -n=bob
name: Some("bob")

$ 03_02_option -nbob
name: Some("bob")

Note that the default ArgAction is Set. To accept multiple occurrences, override the action with Append:

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

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            Arg::new("name")
                .short('n')
                .long("name")
                .action(ArgAction::Append),
        )
        .get_matches();

    println!("name: {:?}", matches.get_one::<String>("name"));
}
$ 03_02_option_mult --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_02_option_mult[EXE] [OPTIONS]

Options:
  -n, --name <name>  
  -h, --help         Print help
  -V, --version      Print version

$ 03_02_option_mult
name: None

$ 03_02_option_mult --name bob
name: Some("bob")

$ 03_02_option_mult --name=bob
name: Some("bob")

$ 03_02_option_mult -n bob
name: Some("bob")

$ 03_02_option_mult -n=bob
name: Some("bob")

$ 03_02_option_mult -nbob
name: Some("bob")

§Flags

Flags can also be switches that can be on/off:

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

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

    println!("verbose: {:?}", matches.get_flag("verbose"));
}
$ 03_01_flag_bool --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_01_flag_bool[EXE] [OPTIONS]

Options:
  -v, --verbose  
  -h, --help     Print help
  -V, --version  Print version

$ 03_01_flag_bool
verbose: false

$ 03_01_flag_bool --verbose
verbose: true

$ 03_01_flag_bool --verbose --verbose
? failed
error: the argument '--verbose' cannot be used multiple times

Usage: 03_01_flag_bool[EXE] [OPTIONS]

For more information, try '--help'.

To accept multiple flags, use Count:

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

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            Arg::new("verbose")
                .short('v')
                .long("verbose")
                .action(ArgAction::Count),
        )
        .get_matches();

    println!("verbose: {:?}", matches.get_count("verbose"));
}
$ 03_01_flag_count --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_01_flag_count[EXE] [OPTIONS]

Options:
  -v, --verbose...  
  -h, --help        Print help
  -V, --version     Print version

$ 03_01_flag_count
verbose: 0

$ 03_01_flag_count --verbose
verbose: 1

$ 03_01_flag_count --verbose --verbose
verbose: 2

§Subcommands

Subcommands are defined as Commands that get added via Command::subcommand. Each instance of a Subcommand can have its own version, author(s), Args, and even its own subcommands.

use clap::{arg, command, Command};

fn main() {
    let matches = command!() // requires `cargo` feature
        .propagate_version(true)
        .subcommand_required(true)
        .arg_required_else_help(true)
        .subcommand(
            Command::new("add")
                .about("Adds files to myapp")
                .arg(arg!([NAME])),
        )
        .get_matches();

    match matches.subcommand() {
        Some(("add", sub_matches)) => println!(
            "'myapp add' was used, name is: {:?}",
            sub_matches.get_one::<String>("NAME")
        ),
        _ => unreachable!("Exhausted list of subcommands and subcommand_required prevents `None`"),
    }
}
$ 03_04_subcommands help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_04_subcommands[EXE] <COMMAND>

Commands:
  add   Adds files to myapp
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

$ 03_04_subcommands help add
Adds files to myapp

Usage: 03_04_subcommands[EXE] add [NAME]

Arguments:
  [NAME]  

Options:
  -h, --help     Print help
  -V, --version  Print version

$ 03_04_subcommands add bob
'myapp add' was used, name is: Some("bob")

Because we set Command::arg_required_else_help:

$ 03_04_subcommands
? failed
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_04_subcommands[EXE] <COMMAND>

Commands:
  add   Adds files to myapp
  help  Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

Since we specified Command::propagate_version, the --version flag is available in all subcommands:

$ 03_04_subcommands --version
clap [..]

$ 03_04_subcommands add --version
clap-add [..]

§Defaults

We’ve previously showed that arguments can be required or optional. When optional, you work with a Option and can unwrap_or. Alternatively, you can set Arg::default_value.

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

fn main() {
    let matches = command!() // requires `cargo` feature
        .arg(
            arg!([PORT])
                .value_parser(value_parser!(u16))
                .default_value("2020"),
        )
        .get_matches();

    println!(
        "port: {:?}",
        matches
            .get_one::<u16>("PORT")
            .expect("default ensures there is always a value")
    );
}
$ 03_05_default_values --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_05_default_values[EXE] [PORT]

Arguments:
  [PORT]  [default: 2020]

Options:
  -h, --help     Print help
  -V, --version  Print version

$ 03_05_default_values
port: 2020

$ 03_05_default_values 22
port: 22

Re-exports§