CLI with clap
Use case
You need a command-line tool: flags, positional args, subcommands, and help. clap is the standard choice in Rust. Use the derive API: define a struct, derive Parser, and get parsing and --help for free.
In C#: Like System.CommandLine (new) or parsing string[] args manually. In Rust, clap gives validation, help, and typo suggestions.
Basic struct and Parser
Derive Parser on a struct. Fields become arguments: Option<T> or bool for flags, String/u32 etc. for required values.
use clap::Parser;
#[derive(Parser)]
#[command(name = "myapp", about = "My CLI tool")]
struct Args {
/// Input file
#[arg(short, long)]
input: String,
/// Optional count
#[arg(short, long, default_value_t = 1)]
count: u32,
/// Enable verbose
#[arg(short, long)]
verbose: bool,
}
fn main() {
let args = Args::parse();
println!("input: {}, count: {}, verbose: {}", args.input, args.count, args.verbose);
}In C#: Like defining options and binding from args. #[arg(short, long)] gives -i/--input; default_value_t gives a default.
Subcommands
Use an enum with Subcommand for git-style subcommands (e.g. myapp init, myapp build).
use clap::{Parser, Subcommand};
#[derive(Parser)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
/// Initialize a new project
Init,
/// Build the project
Build { release: bool },
}
fn main() {
let cli = Cli::parse();
match &cli.command {
Commands::Init => println!("init"),
Commands::Build { release } => println!("build --release={}", release),
}
}In C#: Like System.CommandLine with RootCommand and subcommands. Match on the enum to dispatch.
Validation and help
- Use
#[arg(value_parser = clap::value_parser!(u32).range(1..))]for ranges. - Doc comments on fields become help text. Use
#[command(about = "...")]for the top-level description. Args::parse()exits with an error and prints help if parsing fails; useArgs::try_parse()for custom handling.
In C#: Similar to validators and description attributes in command-line libraries.
Key takeaway
Define a struct (or enum for subcommands), derive Parser (and Subcommand), then call YourArgs::parse(). Use #[arg(short, long)] for flags and options; doc comments become help text.