clap Command Line Argument Parser
repository·master·Indexed 12 days ago
https://github.com/clap-rs/clapA simple to use, efficient, and full-featured command-line argument parser for Rust. Version 4.6.6 provides both a declarative approach via the clap_derive macro-based API and a programmatic approach via the clap_builder API. The ecosystem includes clap_complete for shell completions (including Nushell), clap_mangen for generating ROFF man pages, and clap_lex for minimal command line lexical analysis.
What's inside clap
- clap is a command-line argument parser for Rust. It allows you to create sophisticated command-line interfaces (CLIs) using either a declarative approach or a procedural approach (via derive macros).
Overview of clap_lex
masterclap_lexis a minimal and flexible command line lexer. It is designed to be a lightweight component for parsing command line arguments, providing the foundational lexical analysis required for command line interfaces.Use `clap_derive` for declarative CLI parsing
masterclap_deriveprovides procedural macros that allow you to define your command-line interface (CLI) by deriving theParsertrait on a struct or enum. This is the most ergonomic way to useclap, as it allows you to map CLI arguments directly to Rust data structures using attributes.For detailed usage, refer to the official documentation:
Use the clap Builder API
masterThe
clap_builderpackage provides the Builder implementation forclap. This approach allows you to programmatically construct command-line argument parsers by calling methods on aCommandobject to define arguments, subcommands, and help text. This is an alternative to theclap_derivemacro-based approach.For detailed API documentation, visit docs.rs/clap.
Generate shell completions with `clap_complete`
masterclap_completeis a library used to generate shell completion scripts for command-line applications built withclap. It allows your users to benefit from tab-completion in their terminal by providing scripts tailored to specific shells.Access clap cookbook and tutorials
masterFor practical guidance on using
clap, refer to the following documentation types:- Cookbook / How-To Guides: Specific recipes for common tasks.
- Tutorials: Step-by-step guides for both the
deriveandbuilderAPIs.
You can find these on docs.rs.
Generate man pages from `clap::Command` with `clap_mangen`
masterThe
clap_mangencrate allows you to generate ROFF man pages directly from aclap::Commandinstance. This is useful for generating documentation during the build process rather than requiring a runtime flag in your application.To use it in a build script (
build.rs), follow these steps:- Add
clap_mangento your[build-dependencies]inCargo.toml. - Use
clap_mangen::Man::new(cmd)to create a man page generator from your command. - Call
.render(&mut buffer)to write the ROFF content into a byte buffer. - Write the buffer to a file in the
OUT_DIR(e.g.,mybin.1).
fn main() -> std::io::Result<()> { let out_dir = std::path::PathBuf::from(std::env::var_os("OUT_DIR").ok_or(std::io::ErrorKind::NotFound)?); let cmd = clap::Command::new("mybin") .arg(clap::arg!(-n --name <NAME>)) .arg(clap::arg!(-c --count <NUM>)); let man = clap_mangen::Man::new(cmd); let mut buffer: Vec<u8> = Default::default(); man.render(&mut buffer)?; std::fs::write(out_dir.join("mybin.1"), buffer)?; Ok(()) }- Add
Install clap via cargo
masterTo add
clapto your Rust project, use thecargo addcommand. This will add the crate to yourCargo.tomldependencies.$ cargo add clapGenerate Nushell completions for clap CLIs
masterUse the
clap_complete_nushellcrate to generate Nushell-compatible completion scripts for yourclap-based command-line applications. This is done by passing theNushelltype to theclap_complete::generatefunction.To implement this, you need to:
- Define your
Commandstructure usingclap. - Import
clap_complete::generateandclap_complete_nushell::Nushell. - Call
generate(Nushell, &mut cmd, "name", &mut io::stdout())to output the completion script.
use clap::{builder::PossibleValue, Arg, ArgAction, Command, ValueHint}; use clap_complete::generate; use clap_complete_nushell::Nushell; use std::io; fn main() { let mut cmd = Command::new("myapp") .version("3.0") .propagate_version(true) .about("Tests completions") .arg( Arg::new("file") .value_hint(ValueHint::FilePath) .help("some input file"), ) .arg( Arg::new("config") .action(ArgAction::Count) .help("some config file") .short('c') .visible_short_alias('C') .long("config") .visible_alias("conf"), ) .arg(Arg::new("choice").value_parser(["first", "second"])) .subcommand( Command::new("test").about("tests things").arg( Arg::new("case") .long("case") .action(ArgAction::Set) .help("the case to test"), ), ) .subcommand( Command::new("some_cmd") .about("top level subcommand") .subcommand( Command::new("sub_cmd").about("sub-subcommand").arg( Arg::new("config") .long("config") .action(ArgAction::Set) .value_parser([PossibleValue::new("Lest quotes aren't escaped.")]) .help("the other case to test"), ), ), ); generate(Nushell, &mut cmd, "myapp", &mut io::stdout()); }- Define your
Reviewing help output for CLI changes
masterWhen developing CLI tools, you can automate the review of help output to ensure changes are intentional. The
pacmanexample uses a testing pattern where:- Every command's long help is rendered.
- Each Markdown heading represents a complete command path.
term_width(0)is used to prevent terminal-dependent line wrapping, ensuring consistent output.- The output is compared against a snapshot using
snapbox.
To accept intentional changes to your help text, set the
SNAPSHOTSenvironment variable tooverwrite.SNAPSHOTS=overwriteInstall `clap_mangen` as a build dependency
masterTo add
clap_mangento your project specifically for use during the build process, run the following command:cargo add --build clap_mangenUnderstand clap indices vs argv indices
masterThe
index_of(id)andindices_of(id)methods return indices that are similar to, but not exactly the same as, standardargvindices.Key Differences:
- Flags: For flags (switches without values), the index refers to the occurrence of the switch itself.
- Options: For options (switches with values), the index refers to the value provided, not the switch. For example, in
-o val, the index recorded is forval. - Separation: Clap indices continue counting after arguments have been properly separated by the parser, whereas
argvindices do not. - Delimiters: If a value is split by a
value_delimiter, each resulting value receives its own distinct index.
# use clap_builder as clap; # use clap::{Command, Arg, ArgAction}; let m = Command::new("myapp") .arg(Arg::new("flag").short('f').action(ArgAction::SetTrue)) .arg(Arg::new("option").short('o').action(ArgAction::Set)) .get_matches_from(vec!["myapp", "-f", "-o", "val"]); // ARGV: [0:myapp, 1:-f, 2:-o, 3:val] // Clap: [1:flag, 3:option] assert_eq!(m.index_of("flag"), Some(1)); assert_eq!(m.index_of("option"), Some(3));