Available on crate feature unstable-doc only.
Expand description

§Adding Arguments

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

Arguments are inferred from the fields of your struct.

§Positionals

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

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    name: Option<String>,
}

fn main() {
    let cli = Cli::parse();

    println!("name: {:?}", cli.name.as_deref());
}
$ 03_03_positional_derive --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_03_positional_derive[EXE] [NAME]

Arguments:
  [NAME]  

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

$ 03_03_positional_derive
name: None

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

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

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    name: Vec<String>,
}

fn main() {
    let cli = Cli::parse();

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

Usage: 03_03_positional_mult_derive[EXE] [NAME]...

Arguments:
  [NAME]...  

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

$ 03_03_positional_mult_derive
name: []

$ 03_03_positional_mult_derive bob
name: ["bob"]

$ 03_03_positional_mult_derive bob john
name: ["bob", "john"]

§Options

You can name your arguments with a flag:

  • Order doesn’t matter
  • They can be optional
  • Intent is clearer

To specify the flags for an argument, you can use #[arg(short = 'n')] and/or #[arg(long = "name")] attributes on a field. When no value is given (e.g. #[arg(short)]), the flag is inferred from the field’s name.

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(short, long)]
    name: Option<String>,
}

fn main() {
    let cli = Cli::parse();

    println!("name: {:?}", cli.name.as_deref());
}
$ 03_02_option_derive --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_02_option_derive[EXE] [OPTIONS]

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

$ 03_02_option_derive
name: None

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

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

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

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

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

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

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(short, long)]
    name: Vec<String>,
}

fn main() {
    let cli = Cli::parse();

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

Usage: 03_02_option_mult_derive[EXE] [OPTIONS]

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

$ 03_02_option_mult_derive
name: []

$ 03_02_option_mult_derive --name bob
name: ["bob"]

$ 03_02_option_mult_derive --name=bob
name: ["bob"]

$ 03_02_option_mult_derive -n bob
name: ["bob"]

$ 03_02_option_mult_derive -n=bob
name: ["bob"]

$ 03_02_option_mult_derive -nbob
name: ["bob"]

§Flags

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

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(short, long)]
    verbose: bool,
}

fn main() {
    let cli = Cli::parse();

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

Usage: 03_01_flag_bool_derive[EXE] [OPTIONS]

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

$ 03_01_flag_bool_derive
verbose: false

$ 03_01_flag_bool_derive --verbose
verbose: true

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

Usage: 03_01_flag_bool_derive[EXE] [OPTIONS]

For more information, try '--help'.

Note that the default ArgAction for a bool field is SetTrue. To accept multiple flags, override the action with Count:

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(short, long, action = clap::ArgAction::Count)]
    verbose: u8,
}

fn main() {
    let cli = Cli::parse();

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

Usage: 03_01_flag_count_derive[EXE] [OPTIONS]

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

$ 03_01_flag_count_derive
verbose: 0

$ 03_01_flag_count_derive --verbose
verbose: 1

$ 03_01_flag_count_derive --verbose --verbose
verbose: 2

This also shows that anyArg method may be used as an attribute.

§Subcommands

Subcommands are derived with #[derive(Subcommand)] and be added via #[command(subcommand)] attribute on the field using that type. Each instance of a Subcommand can have its own version, author(s), Args, and even its own subcommands.

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Adds files to myapp
    Add { name: Option<String> },
}

fn main() {
    let cli = Cli::parse();

    // You can check for the existence of subcommands, and if found use their
    // matches just as you would the top level cmd
    match &cli.command {
        Commands::Add { name } => {
            println!("'myapp add' was used, name is: {name:?}")
        }
    }
}

We used a struct-variant to define the add subcommand. Alternatively, you can use a struct for your subcommand’s arguments:

use clap::{Args, Parser, Subcommand};

#[derive(Parser)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Adds files to myapp
    Add(AddArgs),
}

#[derive(Args)]
struct AddArgs {
    name: Option<String>,
}

fn main() {
    let cli = Cli::parse();

    // You can check for the existence of subcommands, and if found use their
    // matches just as you would the top level cmd
    match &cli.command {
        Commands::Add(name) => {
            println!("'myapp add' was used, name is: {:?}", name.name)
        }
    }
}
$ 03_04_subcommands_derive help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_04_subcommands_derive[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_derive help add
Adds files to myapp

Usage: 03_04_subcommands_derive[EXE] add [NAME]

Arguments:
  [NAME]  

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

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

When specifying commands with command: Commands, they are required. Alternatively, you could do command: Option<Commands> to make it optional.

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

Usage: 03_04_subcommands_derive[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 = true)], the --version flag is available in all subcommands:

$ 03_04_subcommands_derive --version
clap [..]

$ 03_04_subcommands_derive 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_t)].

use clap::Parser;

#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
    #[arg(default_value_t = 2020)]
    port: u16,
}

fn main() {
    let cli = Cli::parse();

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

Usage: 03_05_default_values_derive[EXE] [PORT]

Arguments:
  [PORT]  [default: 2020]

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

$ 03_05_default_values_derive
port: 2020

$ 03_05_default_values_derive 22
port: 22

Re-exports§