title: CLI with Clap
Boilerplate for a command-line application using clap with the derive API.
Cargo.toml
[package]
name = "my-cli"
version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4", features = ["derive"] }Basic CLI with subcommands
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "my-cli")]
#[command(about = "A simple CLI tool", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Add a new item
Add {
/// Name of the item to add
name: String,
/// Optional description
#[arg(short, long)]
description: Option<String>,
},
/// List all items
List {
/// Show verbose output
#[arg(short, long)]
verbose: bool,
},
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::Add { name, description } => {
println!("Adding: {name}");
if let Some(desc) = description {
println!("Description: {desc}");
}
}
Commands::List { verbose } => {
if verbose {
println!("Listing all items (verbose)...");
} else {
println!("Listing all items...");
}
}
}
}Usage
my-cli add "foo"
my-cli add "foo" --description "bar"
my-cli list
my-cli list --verbose
my-cli --help
my-cli add --helpGlobal flags
Add flags to the top-level Cli struct to make them available to all subcommands:
#[derive(Parser)]
struct Cli {
/// Enable debug output
#[arg(short, long, global = true)]
debug: bool,
#[command(subcommand)]
command: Commands,
}Common arg types
/// A required positional argument
name: String,
/// An optional positional argument
name: Option<String>,
/// A flag (--verbose or -v)
#[arg(short, long)]
verbose: bool,
/// An option with a value (--output file.txt or -o file.txt)
#[arg(short, long)]
output: Option<String>,
/// A required option
#[arg(short, long)]
config: String,
/// Repeatable flag (--verbose -v -v counts occurrences)
#[arg(short, long, action = clap::ArgAction::Count)]
verbose: u8,