### Install hardlinks with --install option Source: https://docs.rs/clap/latest/clap/_cookbook/multicall_busybox/index.html Shows an example of using the `--install` option, which is intended to install hardlinks for all subcommands. This example is noted as failing without proper link setup. ```bash $ busybox --install ? failed ... ``` -------------------------------- ### Quick start application Source: https://docs.rs/clap/latest/src/clap/_tutorial.rs.html A basic example of creating a command-line application using the builder API. ```rust #![doc = include_str!("../examples/tutorial_builder/01_quick.rs")] ``` -------------------------------- ### Busybox-like CLI with Builder API Source: https://docs.rs/clap/latest/clap/_cookbook/multicall_busybox/index.html This example sets up a command-line interface that mimics busybox, allowing multiple subcommands to be invoked via a single executable. It uses the Builder API for command definition and includes an example of a `--install` argument. ```rust use std::path::PathBuf; use std::process::exit; use clap::{Arg, ArgAction, Command, value_parser}; fn applet_commands() -> [Command; 2] { [ Command::new("true").about("does nothing successfully"), Command::new("false").about("does nothing unsuccessfully"), ] } fn main() { let cmd = Command::new(env!("CARGO_CRATE_NAME")) .multicall(true) .subcommand( Command::new("busybox") .arg_required_else_help(true) .subcommand_value_name("APPLET") .subcommand_help_heading("APPLETS") .arg( Arg::new("install") .long("install") .help("Install hardlinks for all subcommands in path") .exclusive(true) .action(ArgAction::Set) .default_missing_value("/usr/local/bin") .value_parser(value_parser!(PathBuf)), ) .subcommands(applet_commands()), ) .subcommands(applet_commands()); let matches = cmd.get_matches(); let mut subcommand = matches.subcommand(); if let Some(("busybox", cmd)) = subcommand { if cmd.contains_id("install") { unimplemented!("Make hardlinks to the executable here"); } subcommand = cmd.subcommand(); } match subcommand { Some(("false", _)) => exit(1), Some(("true", _)) => exit(0), _ => unreachable!("parser should ensure only valid subcommand names are used"), } } ``` -------------------------------- ### CLI Execution Examples Source: https://docs.rs/clap/latest/clap/_cookbook/typed_derive/index.html Examples of running the CLI with valid and invalid inputs for various types. ```text $ typed-derive implicit -O 1 Implicit(ImplicitParsers { optimization: Some(1), include: None, bind: None, sleep: None, bump_level: None }) $ typed-derive implicit -O plaid ? failed error: invalid value 'plaid' for '-O ': invalid digit found in string For more information, try '--help'. ``` ```text $ typed-derive implicit -I../hello Implicit(ImplicitParsers { optimization: None, include: Some("../hello"), bind: None, sleep: None, bump_level: None }) ``` ```text $ typed-derive implicit --bind 192.0.0.1 Implicit(ImplicitParsers { optimization: None, include: None, bind: Some(192.0.0.1), sleep: None, bump_level: None }) $ typed-derive implicit --bind localhost ? failed error: invalid value 'localhost' for '--bind ': invalid IP address syntax For more information, try '--help'. ``` ```text $ typed-derive implicit --sleep 10s Implicit(ImplicitParsers { optimization: None, include: None, bind: None, sleep: Some(10s), bump_level: None }) $ typed-derive implicit --sleep forever ? failed error: invalid value 'forever' for '--sleep ': failed to parse input in the "friendly" duration format: expected duration to start with a unit value (a decimal integer) after an optional sign, but no integer was found For more information, try '--help'. ``` ```text $ typed-derive implicit --bump-level minor Implicit(ImplicitParsers { optimization: None, include: None, bind: None, sleep: None, bump_level: Some(Minor) }) $ typed-derive implicit --bump-level 10.0.0 ? failed error: invalid value '10.0.0' for '--bump-level ' [possible values: major, minor, patch] For more information, try '--help'. $ typed-derive implicit --bump-level blue ? failed error: invalid value 'blue' for '--bump-level ' [possible values: major, minor, patch] For more information, try '--help'. ``` -------------------------------- ### Cargo Example Help Output Source: https://docs.rs/clap/latest/clap/_cookbook/cargo_example/index.html Displays the help message for the main 'cargo-example' command and its 'example' subcommand. ```bash $ cargo-example --help Usage: cargo Commands: example A simple to use, efficient, and full-featured Command Line Argument Parser help Print this message or the help of the given subcommand(s) Options: -h, --help Print help $ cargo-example example --help A simple to use, efficient, and full-featured Command Line Argument Parser Usage: cargo example [OPTIONS] Options: --manifest-path -h, --help Print help -V, --version Print version ``` -------------------------------- ### Command Example Usage Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html An example demonstrating how to create a Command, set author, version, about information, add arguments, and retrieve matches. ```APIDOC ## §Examples ```rust let m = Command::new("My Program") .author("Me, me@mail.com") .version("1.0.2") .about("Explains in brief what the program does") .arg( Arg::new("in_file") ) .after_help("Longer explanation to appear after the options when \ displaying the help information from --help or -h") .get_matches(); // Your program logic starts here... ``` ``` -------------------------------- ### Include Command REPL Example Source: https://docs.rs/clap/latest/src/clap/_cookbook/repl.rs.html Uses the include_str! macro to embed the REPL example source code into the documentation. ```rust #![doc = include_str!("../../examples/repl.rs")] ``` -------------------------------- ### CLI Execution Examples Source: https://docs.rs/clap/latest/clap/_derive/_tutorial/index.html Example command line interactions demonstrating validation errors and successful execution. ```bash $ 04_04_custom_derive --help A simple to use, efficient, and full-featured Command Line Argument Parser Usage: 04_04_custom_derive[EXE] [OPTIONS] [INPUT_FILE] Arguments: [INPUT_FILE] some regular input Options: --set-ver set version manually --major auto inc major --minor auto inc minor --patch auto inc patch --spec-in some special input argument -c -h, --help Print help -V, --version Print version $ 04_04_custom_derive ? failed error: Can only modify one version field Usage: clap [OPTIONS] [INPUT_FILE] For more information, try '--help'. $ 04_04_custom_derive --major Version: 2.2.3 $ 04_04_custom_derive --major --minor ? failed error: Can only modify one version field Usage: clap [OPTIONS] [INPUT_FILE] For more information, try '--help'. $ 04_04_custom_derive --major -c config.toml ? failed Version: 2.2.3 error: INPUT_FILE or --spec-in is required when using --config Usage: clap [OPTIONS] [INPUT_FILE] For more information, try '--help'. $ 04_04_custom_derive --major -c config.toml --spec-in input.txt Version: 2.2.3 Doing work using input input.txt and config config.toml ``` -------------------------------- ### Git CLI Example Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html An example demonstrating how to build a 'git'-like CLI using Clap, including various subcommands like clone, diff, push, add, and stash. ```APIDOC ## Git CLI Example ### Description This example showcases the creation of a fictional versioning CLI named 'git' using the Clap library. It defines multiple subcommands with their respective arguments and configurations. ### Subcommands - **clone**: Clones repositories. Requires a `` argument. - **diff**: Compares two commits. Accepts `base`, `head` commits, an optional `PATH`, and a `--color` argument. - **push**: Pushes changes to a remote. Requires a `` argument. - **add**: Adds files or directories. Accepts one or more `` arguments. - **stash**: Manages stashes. Supports nested subcommands like `push`, `pop`, and `apply`, and can conflict with arguments. ### Configuration - `subcommand_required(true)`: Ensures a subcommand is always provided. - `arg_required_else_help(true)`: Displays help if arguments are missing for a subcommand. - `allow_external_subcommands(true)`: Permits the use of external commands as subcommands. ``` -------------------------------- ### Define and Get Command-Line Arguments with ArgMatches Source: https://docs.rs/clap/latest/clap/struct.ArgMatches.html This example demonstrates how to define arguments using Command and Arg, then retrieve parsed results using get_matches. It shows how to access optional and required arguments, including their values and sources. ```rust let matches = Command::new("MyApp") .arg(Arg::new("out") .long("output") .required(true) .action(ArgAction::Set) .default_value("-")) .arg(Arg::new("cfg") .short('c') .action(ArgAction::Set)) .get_matches(); // builds the instance of ArgMatches // to get information about the "cfg" argument we created, such as the value supplied we use // various ArgMatches methods, such as [ArgMatches::get_one] if let Some(c) = matches.get_one::("cfg") { println!("Value for -c: {c}"); } // The ArgMatches::get_one method returns an Option because the user may not have supplied // that argument at runtime. But if we specified that the argument was "required" as we did // with the "out" argument, we can safely unwrap because `clap` verifies that was actually // used at runtime. println!("Value for --output: {}", matches.get_one::("out").unwrap()); // You can check the presence of an argument's values if matches.contains_id("out") { // However, if you want to know where the value came from if matches.value_source("out").expect("checked contains_id") == ValueSource::CommandLine { println!("`out` set by user"); } else { println!("`out` is defaulted"); } } ``` -------------------------------- ### Example CLI Output Source: https://docs.rs/clap/latest/clap/_cookbook/multicall_hostname/index.html This shows the expected output when running the 'hostname' subcommand of the example CLI. ```bash $ hostname www ``` -------------------------------- ### Execute CLI demo Source: https://docs.rs/clap/latest/clap/index.html Example output of the generated CLI help and usage. ```shell $ demo --help A simple to use, efficient, and full-featured Command Line Argument Parser Usage: demo[EXE] [OPTIONS] --name Options: -n, --name Name of the person to greet -c, --count Number of times to greet [default: 1] -h, --help Print help -V, --version Print version $ demo --name Me Hello Me! ``` -------------------------------- ### Example: from_arg_matches calling from_arg_matches_mut Source: https://docs.rs/clap/latest/clap/trait.FromArgMatches.html This example demonstrates how the `from_arg_matches` method can delegate its work to `from_arg_matches_mut` by cloning the `ArgMatches`. ```rust fn from_arg_matches(matches: &ArgMatches) -> Result { let mut matches = matches.clone(); Self::from_arg_matches_mut(&mut matches) } ``` -------------------------------- ### Multicall Busybox Example Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html Implements a multicall application mimicking busybox. It includes a 'busybox' subcommand with an 'install' argument and handles 'true' and 'false' subcommands for exit codes. ```rust 13fn main() { let cmd = Command::new(env!("CARGO_CRATE_NAME")) .multicall(true) .subcommand( Command::new("busybox") .arg_required_else_help(true) .subcommand_value_name("APPLET") .subcommand_help_heading("APPLETS") .arg( Arg::new("install") .long("install") .help("Install hardlinks for all subcommands in path") .exclusive(true) .action(ArgAction::Set) .default_missing_value("/usr/local/bin") .value_parser(value_parser!(PathBuf)), ) .subcommands(applet_commands()), ) .subcommands(applet_commands()); let matches = cmd.get_matches(); let mut subcommand = matches.subcommand(); if let Some(("busybox", cmd)) = subcommand { if cmd.contains_id("install") { unimplemented!("Make hardlinks to the executable here"); } subcommand = cmd.subcommand(); } match subcommand { Some(("false", _)) => exit(1), Some(("true", _)) => exit(0), _ => unreachable!("parser should ensure only valid subcommand names are used"), } } ``` -------------------------------- ### Git CLI Example Source: https://docs.rs/clap/latest/clap/struct.Command.html An example of defining a Git-like command-line interface using Clap, including various subcommands and arguments. ```APIDOC ## Git CLI Example ### Description This example demonstrates how to build a command-line interface similar to Git using the Clap library. It includes subcommands like `clone`, `diff`, `push`, `add`, and `stash`, each with its own set of arguments. ### Method N/A (Code definition) ### Endpoint N/A (Code definition) ### Parameters N/A (Code definition) ### Request Example N/A (Code definition) ### Response N/A (Code definition) ``` -------------------------------- ### Multicall Example: Hostname Source: https://docs.rs/clap/latest/clap/struct.Command.html Example demonstrating a multicall executable for 'hostname' and 'dnsdomainname'. ```APIDOC ## GET /api/users/{id} ### Description Retrieves details for a specific user account. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the user to retrieve. ### Response #### Success Response (200) - **id** (integer) - The unique identifier for the user. - **username** (string) - The username of the user. - **email** (string) - The email address of the user. #### Response Example ```json { "id": 123, "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### Git-like CLI Example (Derive API) Source: https://docs.rs/clap/latest/src/clap/_cookbook/git_derive.rs.html This snippet demonstrates how to build a git-like command-line interface using clap's Derive API. It includes the necessary Rust code for the example. ```rust #![doc = include_str!("../../examples/git-derive.rs")] ``` ```rust #![doc = include_str!("../../examples/git-derive.md")] ``` -------------------------------- ### CLI Usage Examples Source: https://docs.rs/clap/latest/clap/_derive/_cookbook/typed_derive/index.html Demonstrates valid and invalid inputs for the custom argument parser. ```text $ typed-derive custom --target-version major Custom(CustomParser { target_version: Some(Relative(Major)) }) $ typed-derive custom --target-version 10.0.0 Custom(CustomParser { target_version: Some(Absolute(Version { major: 10, minor: 0, patch: 0 })) }) $ typed-derive custom --target-version 10 ? failed error: invalid value '10' for '--target-version ': unexpected end of input while parsing major version number For more information, try '--help'. $ typed-derive custom --target-version blue ? failed error: invalid value 'blue' for '--target-version ': unexpected character 'b' while parsing major version number For more information, try '--help'. ``` -------------------------------- ### Execution Examples for Defines Source: https://docs.rs/clap/latest/clap/_derive/_cookbook/typed_derive/index.html Demonstrates valid and invalid inputs for the custom key-value parser. ```text $ typed-derive fn-parser -D Foo=10 -D Alice=30 FnParser(FnParser { defines: [("Foo", 10), ("Alice", 30)] }) $ typed-derive fn-parser -D Foo ? failed error: invalid value 'Foo' for '-D ': invalid KEY=value: no `=` found in `Foo` For more information, try '--help'. $ typed-derive fn-parser -D Foo=Bar ? failed error: invalid value 'Foo=Bar' for '-D ': invalid digit found in string For more information, try '--help'. ``` -------------------------------- ### Example Calling a Documented Function Source: https://docs.rs/clap/latest/scrape-examples-help.html This demonstrates an example file that calls a documented function from another crate. This usage will be scraped by Rustdoc. ```rust // examples/ex.rs fn main() { a_crate::a_func(); } ``` -------------------------------- ### CLI Usage Examples Source: https://docs.rs/clap/latest/clap/_cookbook/pacman/index.html Various command-line invocations for the pacman-like utility. ```bash $ pacman -S package Installing package... ``` ```bash $ pacman --sync package Installing package... ``` ```bash $ pacman -S --search name Searching for name... ``` ```bash $ pacman -S -s name Searching for name... ``` ```bash $ pacman -Ss name Searching for name... ``` ```bash $ pacman -h package manager utility Usage: pacman[EXE] Commands: query, -Q, --query Query the package database. ``` -------------------------------- ### View help output Source: https://docs.rs/clap/latest/clap/_tutorial/index.html Example of the auto-generated help message for the application. ```shell $ 01_quick --help A simple to use, efficient, and full-featured Command Line Argument Parser Usage: 01_quick[EXE] [OPTIONS] [name] [COMMAND] Commands: test does testing things help Print this message or the help of the given subcommand(s) Arguments: [name] Optional name to operate on Options: -c, --config Sets a custom config file -d, --debug... Turn debugging information on -h, --help Print help -V, --version Print version ``` -------------------------------- ### Multicall Busybox Example Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html Demonstrates how to create a multicall binary similar to busybox, where a single executable can act as multiple commands. This example defines subcommands for 'true' and 'false' and handles a 'busybox' subcommand with its own arguments. ```rust fn applet_commands() -> [Command; 2] { [ Command::new("true").about("does nothing successfully"), Command::new("false").about("does nothing unsuccessfully"), ] } fn main() { let cmd = Command::new(env!("CARGO_CRATE_NAME")) .multicall(true) .subcommand( Command::new("busybox") .arg_required_else_help(true) .subcommand_value_name("APPLET") .subcommand_help_heading("APPLETS") .arg( Arg::new("install") .long("install") .help("Install hardlinks for all subcommands in path") .exclusive(true) .action(ArgAction::Set) .default_missing_value("/usr/local/bin") .value_parser(value_parser!(PathBuf)), ) .subcommands(applet_commands()), ) .subcommands(applet_commands()); let matches = cmd.get_matches(); let mut subcommand = matches.subcommand(); if let Some(("busybox", cmd)) = subcommand { if cmd.contains_id("install") { unimplemented!("Make hardlinks to the executable here"); } subcommand = cmd.subcommand(); } match subcommand { Some(("false", _)) => exit(1), Some(("true", _)) => exit(0), _ => unreachable!("parser should ensure only valid subcommand names are used"), } } ``` -------------------------------- ### Configure the parser Source: https://docs.rs/clap/latest/src/clap/_tutorial.rs.html Initialize a Command object to start building your parser. ```rust #![doc = include_str!("../examples/tutorial_builder/02_apps.rs")] ``` -------------------------------- ### Command REPL (Builder API) Example Source: https://docs.rs/clap/latest/clap/_derive/_cookbook/repl/index.html Implement a Read-Eval-Print Loop (REPL) for command-line applications using clap's Builder API. This example demonstrates setting up subcommands like 'ping' and 'quit', parsing user input, and managing the interactive loop. Requires the `unstable-doc` feature. ```rust use std::io::Write; use clap::Command; fn main() -> Result<(), String> { loop { let line = readline()?; let line = line.trim(); if line.is_empty() { continue; } match respond(line) { Ok(quit) => { if quit { break; } } Err(err) => { write!(std::io::stdout(), "{err}").map_err(|e| e.to_string())?; std::io::stdout().flush().map_err(|e| e.to_string())?; } } } Ok(()) } fn respond(line: &str) -> Result { let args = shlex::split(line).ok_or("error: Invalid quoting")?; let matches = cli() .try_get_matches_from(args) .map_err(|e| e.to_string())?; match matches.subcommand() { Some(("ping", _matches)) => { write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?; std::io::stdout().flush().map_err(|e| e.to_string())?; } Some(("quit", _matches)) => { write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?; std::io::stdout().flush().map_err(|e| e.to_string())?; return Ok(true); } Some((name, _matches)) => unimplemented!("{name}"), None => unreachable!("subcommand required"), } Ok(false) } fn cli() -> Command { // strip out usage const PARSER_TEMPLATE: &str = " {all-args} "; // strip out name/version const APPLET_TEMPLATE: &str = " {about-with-newline}\n {usage-heading}\n {usage}\n {all-args}{after-help} "; Command::new("repl") .multicall(true) .arg_required_else_help(true) .subcommand_required(true) .subcommand_value_name("APPLET") .subcommand_help_heading("APPLETS") .help_template(PARSER_TEMPLATE) .subcommand( Command::new("ping") .about("Get a response") .help_template(APPLET_TEMPLATE), ) .subcommand( Command::new("quit") .alias("exit") .about("Quit the REPL") .help_template(APPLET_TEMPLATE), ) } fn readline() -> Result { write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?; std::io::stdout().flush().map_err(|e| e.to_string())?; let mut buffer = String::new(); std::io::stdin() .read_line(&mut buffer) .map_err(|e| e.to_string())?; Ok(buffer) } ``` -------------------------------- ### Example: PathBuf ValueParser Source: https://docs.rs/clap/latest/clap/builder/struct.ValueParser.html Demonstrates parsing a value into a PathBuf. ```APIDOC ## Example: PathBuf ValueParser ### Description Demonstrates parsing a value into a PathBuf. ### Example ```rust let mut cmd = clap::Command::new("raw") .arg( clap::Arg::new("output") .value_parser(clap::value_parser!(PathBuf)) .required(true) ); let m = cmd.try_get_matches_from_mut(["cmd", "hello.txt"]).unwrap(); let port: &PathBuf = m.get_one("output") .expect("required"); assert_eq!(port, Path::new("hello.txt")); assert!(cmd.try_get_matches_from_mut(["cmd", ""]).is_err()); ``` ``` -------------------------------- ### Basic Command with Arguments Source: https://docs.rs/clap/latest/clap/struct.ArgMatches.html Example of creating a simple command with required arguments. ```APIDOC ## POST /api/users ### Description Creates a new user in the system. ### Method POST ### Endpoint /api/users ### Parameters #### Query Parameters - **limit** (integer) - Optional - The maximum number of users to return. #### Request Body - **username** (string) - Required - The desired username for the new user. - **email** (string) - Required - The email address for the new user. ### Request Example ```json { "username": "johndoe", "email": "john.doe@example.com" } ``` ### Response #### Success Response (201) - **id** (integer) - The unique identifier for the newly created user. - **username** (string) - The username of the created user. - **email** (string) - The email address of the created user. #### Response Example ```json { "id": 123, "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### Rust substr_range Example Source: https://docs.rs/clap/latest/clap/builder/struct.Str.html This is a nightly-only experimental API example demonstrating the use of substr_range to get a range of a string slice. ```rust #![feature(substr_range)] use core::range::Range; let data = "a, b, b, a"; let mut iter = data.split(", ").map(|s| data.substr_range(s).unwrap()); assert_eq!(iter.next(), Some(Range { start: 0, end: 1 })); assert_eq!(iter.next(), Some(Range { start: 3, end: 4 })); assert_eq!(iter.next(), Some(Range { start: 6, end: 7 })); assert_eq!(iter.next(), Some(Range { start: 9, end: 10 })); ``` -------------------------------- ### Get length of OsStr Source: https://docs.rs/clap/latest/clap/builder/struct.OsStr.html Example of retrieving the length of the underlying storage for an OsStr. ```rust use std::ffi::OsStr; let os_str = OsStr::new(""); assert_eq!(os_str.len(), 0); let os_str = OsStr::new("foo"); assert_eq!(os_str.len(), 3); ``` -------------------------------- ### Configure Pacman-style CLI Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html Demonstrates basic command setup with short/long flags and argument conflict management. ```rust 3fn main() { 4 let matches = Command::new("pacman") 5 .about("package manager utility") 6 .version("5.2.1") 7 .subcommand_required(true) 8 .arg_required_else_help(true) 9 // Query subcommand 10 // 11 // Only a few of its arguments are implemented below. 12 .subcommand( 13 Command::new("query") 14 .short_flag('Q') 15 .long_flag("query") 16 .about("Query the package database.") 17 .arg( 18 Arg::new("search") 19 .short('s') 20 .long("search") 21 .help("search locally installed packages for matching strings") 22 .conflicts_with("info") 23 .action(ArgAction::Set) 24 .num_args(1..), 25 ) 26 .arg( 27 Arg::new("info") 28 .long("info") 29 .short('i') 30 .conflicts_with("search") 31 .help("view package information") 32 .action(ArgAction::Set) 33 .num_args(1..), 34 ), 35 ) 36 // Sync subcommand 37 // ``` -------------------------------- ### Multicall Hostname Example Source: https://docs.rs/clap/latest/clap/struct.ArgMatches.html Demonstrates a multicall application with 'hostname' and 'dnsdomainname' subcommands. This setup is useful for creating a single executable that can act as multiple distinct tools. ```rust fn main() { let cmd = Command::new(env!("CARGO_CRATE_NAME")) .multicall(true) .arg_required_else_help(true) .subcommand_value_name("APPLET") .subcommand_help_heading("APPLETS") .subcommand(Command::new("hostname").about("show hostname part of FQDN")) .subcommand(Command::new("dnsdomainname").about("show domain name part of FQDN")); match cmd.get_matches().subcommand_name() { Some("hostname") => println!("www"), Some("dnsdomainname") => println!("example.com"), _ => unreachable!("parser should ensure only valid subcommand names are used"), } } ``` -------------------------------- ### Pacman CLI Query Subcommand Example Source: https://docs.rs/clap/latest/clap/builder/struct.Arg.html Defines the 'query' subcommand for a pacman-like CLI tool. It includes arguments for searching installed packages or viewing package information. ```rust fn main() { let matches = Command::new("pacman") .about("package manager utility") .version("5.2.1") .subcommand_required(true) .arg_required_else_help(true) // Query subcommand // // Only a few of its arguments are implemented below. .subcommand( Command::new("query") .short_flag('Q') .long_flag("query") .about("Query the package database.") .arg( Arg::new("search") .short('s') .long("search") .help("search locally installed packages for matching strings") .conflicts_with("info") .action(ArgAction::Set) .num_args(1..), ) .arg( Arg::new("info") .long("info") .short('i') .conflicts_with("search") .help("view package information") .action(ArgAction::Set) .num_args(1..), ), ) // Sync subcommand // // Only a few of its arguments are implemented below. .subcommand( Command::new("sync") ``` -------------------------------- ### Subcommands Example (Git-like) Source: https://docs.rs/clap/latest/clap/struct.ArgMatches.html Demonstrates how to implement subcommands similar to Git, such as clone, diff, push, add, and stash. ```APIDOC ## GET /api/users/{id} ### Description Retrieves details for a specific user by their ID. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the user to retrieve. ### Response #### Success Response (200) - **id** (integer) - The unique identifier for the user. - **username** (string) - The username of the user. - **email** (string) - The email address of the user. #### Response Example ```json { "id": 123, "username": "johndoe", "email": "john.doe@example.com" } ``` ``` -------------------------------- ### Get Required Argument Value with ArgMatches::get_one Source: https://docs.rs/clap/latest/clap/struct.ArgMatches.html This example shows how to use `get_one` to retrieve a required argument's value, parsing it into a specific type like `usize`. It uses `expect` for safe unwrapping due to the argument being marked as required. ```rust let m = Command::new("myapp") .arg(Arg::new("port") .value_parser(value_parser!(usize)) .action(ArgAction::Set) .required(true)) .get_matches_from(vec!["myapp", "2020"]); let port: usize = *m .get_one("port") .expect("`port`is required"); assert_eq!(port, 2020); ``` -------------------------------- ### Implement Pacman-style CLI with Subcommands Source: https://docs.rs/clap/latest/clap/struct.Command.html A complete example showing how to structure a CLI with query and sync subcommands, including argument parsing and conflict management. ```rust 3fn main() { 4 let matches = Command::new("pacman") 5 .about("package manager utility") 6 .version("5.2.1") 7 .subcommand_required(true) 8 .arg_required_else_help(true) 9 // Query subcommand 10 // 11 // Only a few of its arguments are implemented below. 12 .subcommand( 13 Command::new("query") 14 .short_flag('Q') 15 .long_flag("query") 16 .about("Query the package database.") 17 .arg( 18 Arg::new("search") 19 .short('s') 20 .long("search") 21 .help("search locally installed packages for matching strings") 22 .conflicts_with("info") 23 .action(ArgAction::Set) 24 .num_args(1..), 25 ) 26 .arg( 27 Arg::new("info") 28 .long("info") 29 .short('i') 30 .conflicts_with("search") 31 .help("view package information") 32 .action(ArgAction::Set) 33 .num_args(1..), 34 ), 35 ) 36 // Sync subcommand 37 // 38 // Only a few of its arguments are implemented below. 39 .subcommand( 40 Command::new("sync") 41 .short_flag('S') 42 .long_flag("sync") 43 .about("Synchronize packages.") 44 .arg( 45 Arg::new("search") 46 .short('s') 47 .long("search") 48 .conflicts_with("info") 49 .action(ArgAction::Set) 50 .num_args(1..) 51 .help("search remote repositories for matching strings"), 52 ) 53 .arg( 54 Arg::new("info") 55 .long("info") 56 .conflicts_with("search") 57 .short('i') 58 .action(ArgAction::SetTrue) 59 .help("view package information"), 60 ) 61 .arg( 62 Arg::new("package") 63 .help("packages") 64 .required_unless_present("search") 65 .action(ArgAction::Set) 66 .num_args(1..), 67 ), 68 ) 69 .get_matches(); 70 71 match matches.subcommand() { 72 Some(("sync", sync_matches)) => { 73 if sync_matches.contains_id("search") { 74 let packages: Vec<_> = sync_matches 75 .get_many::("search") 76 .expect("contains_id") 77 .map(|s| s.as_str()) 78 .collect(); 79 let values = packages.join(", "); 80 println!("Searching for {values}..."); 81 return; 82 } 83 84 let packages: Vec<_> = sync_matches 85 .get_many::("package") 86 .expect("is present") 87 .map(|s| s.as_str()) 88 .collect(); 89 let values = packages.join(", "); 90 91 if sync_matches.get_flag("info") { 92 println!("Retrieving info for {values}..."); 93 } else { 94 println!("Installing {values}..."); 95 } 96 } 97 Some(("query", query_matches)) => { 98 if let Some(packages) = query_matches.get_many::("info") { 99 let comma_sep = packages.map(|s| s.as_str()).collect::>().join(", "); 100 println!("Retrieving info for {comma_sep}..."); ``` -------------------------------- ### Example: Cargo Example Derive Styling Source: https://docs.rs/clap/latest/clap/builder/struct.Styles.html Defines a constant `CLAP_STYLING` using `Styles::styled()` and custom styles imported from `clap_cargo::style`. This example shows a comprehensive application of various styling methods. ```rust pub const CLAP_STYLING: clap::builder::styling::Styles = clap::builder::styling::Styles::styled() .header(clap_cargo::style::HEADER) .usage(clap_cargo::style::USAGE) .literal(clap_cargo::style::LITERAL) .placeholder(clap_cargo::style::PLACEHOLDER) .error(clap_cargo::style::ERROR) .valid(clap_cargo::style::VALID) .invalid(clap_cargo::style::INVALID); ``` -------------------------------- ### Implement Builder API application Source: https://docs.rs/clap/latest/clap/_tutorial/index.html A complete example demonstrating argument definition, subcommand handling, and value retrieval. ```rust use std::path::PathBuf; use clap::{ArgAction, Command, arg, command, value_parser}; fn main() { let matches = command!() // requires `cargo` feature .arg(arg!([name] "Optional name to operate on")) .arg( arg!( -c --config "Sets a custom config file" ) // We don't have syntax yet for optional options, so manually calling `required` .required(false) .value_parser(value_parser!(PathBuf)), ) .arg(arg!( -d --debug ... "Turn debugging information on" )) .subcommand( Command::new("test") .about("does testing things") .arg(arg!(-l --list "lists test values").action(ArgAction::SetTrue)), ) .get_matches(); // You can check the value provided by positional arguments, or option arguments if let Some(name) = matches.get_one::("name") { println!("Value for name: {name}"); } if let Some(config_path) = matches.get_one::("config") { println!("Value for config: {}", config_path.display()); } // You can see how many times a particular flag or argument occurred // Note, only flags can have multiple occurrences match matches .get_one::("debug") .expect("Counts are defaulted") { 0 => println!("Debug mode is off"), 1 => println!("Debug mode is kind of on"), 2 => println!("Debug mode is on"), _ => println!("Don't be crazy"), } // You can check for the existence of subcommands, and if found use their // matches just as you would the top level cmd if let Some(matches) = matches.subcommand_matches("test") { // "$ myapp test" was run if matches.get_flag("list") { // "$ myapp test -l" was run println!("Printing testing lists..."); } else { println!("Not printing testing lists..."); } } // Continued program logic goes here... } ``` -------------------------------- ### TypedValueParser - Example Implementation Source: https://docs.rs/clap/latest/clap/builder/trait.TypedValueParser.html An example demonstrating how to implement the TypedValueParser trait for a custom value type. ```APIDOC ## §Example ```rust #[derive(Clone)] struct Custom(u32); #[derive(Clone)] struct CustomValueParser; impl clap::builder::TypedValueParser for CustomValueParser { type Value = Custom; fn parse_ref( &self, cmd: &clap::Command, arg: Option<&clap::Arg>, value: &std::ffi::OsStr, ) -> Result { let inner = clap::value_parser!(u32); let val = inner.parse_ref(cmd, arg, value)?; const INVALID_VALUE: u32 = 10; if val == INVALID_VALUE { let mut err = clap::Error::new(ErrorKind::ValueValidation) .with_cmd(cmd); if let Some(arg) = arg { err.insert(ContextKind::InvalidArg, ContextValue::String(arg.to_string())); } err.insert(ContextKind::InvalidValue, ContextValue::String(INVALID_VALUE.to_string())); return Err(err); } Ok(Custom(val)) } } ``` ``` -------------------------------- ### Initialize a Command with metadata and arguments Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html Configures a new command with author, version, description, and arguments before parsing. ```rust let m = Command::new("My Program") .author("Me, me@mail.com") .version("1.0.2") .about("Explains in brief what the program does") .arg( Arg::new("in_file") ) .after_help("Longer explanation to appear after the options when \ displaying the help information from --help or -h") .get_matches(); // Your program logic starts here... ``` -------------------------------- ### Build a Pacman-like CLI with clap Source: https://docs.rs/clap/latest/clap/builder/struct.Arg.html This example demonstrates building a complex CLI application with subcommands ('query', 'sync') and arguments using clap. It shows how to define subcommand-specific arguments and handle their parsing. ```rust fn main() { let matches = Command::new("pacman") .about("package manager utility") .version("5.2.1") .subcommand_required(true) .arg_required_else_help(true) // Query subcommand // // Only a few of its arguments are implemented below. .subcommand( Command::new("query") .short_flag('Q') .long_flag("query") .about("Query the package database.") .arg( Arg::new("search") .short('s') .long("search") .help("search locally installed packages for matching strings") .conflicts_with("info") .action(ArgAction::Set) .num_args(1..), ) .arg( Arg::new("info") .long("info") .short('i') .conflicts_with("search") .help("view package information") .action(ArgAction::Set) .num_args(1..), ), ) // Sync subcommand // // Only a few of its arguments are implemented below. .subcommand( Command::new("sync") .short_flag('S') .long_flag("sync") .about("Synchronize packages.") .arg( Arg::new("search") .short('s') .long("search") .conflicts_with("info") .action(ArgAction::Set) .num_args(1..) .help("search remote repositories for matching strings"), ) .arg( Arg::new("info") .long("info") .conflicts_with("search") .short('i') .action(ArgAction::SetTrue) .help("view package information"), ) .arg( Arg::new("package") .help("packages") .required_unless_present("search") .action(ArgAction::Set) .num_args(1..), ), ) .get_matches(); match matches.subcommand() { Some(("sync", sync_matches)) => { if sync_matches.contains_id("search") { let packages: Vec<_> = sync_matches .get_many::("search") .expect("contains_id") .map(|s| s.as_str()) .collect(); let values = packages.join(", "); println!("Searching for {values}..."); return; } let packages: Vec<_> = sync_matches .get_many::("package") .expect("is present") .map(|s| s.as_str()) .collect(); let values = packages.join(", "); if sync_matches.get_flag("info") { println!("Retrieving info for {values}..."); } else { println!("Installing {values}..."); } } Some(("query", query_matches)) => { ``` -------------------------------- ### Multicall Example: Busybox Source: https://docs.rs/clap/latest/clap/struct.Command.html Example demonstrating a multicall executable for 'busybox' with applets like 'true' and 'false'. ```APIDOC ## DELETE /api/users/{id} ### Description Deletes a specific user account. ### Method DELETE ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the user to delete. ### Response #### Success Response (200) - **message** (string) - A confirmation message indicating the user was deleted. #### Response Example ```json { "message": "User with id 123 deleted successfully." } ``` ``` -------------------------------- ### Define a Git-like CLI with Subcommands Source: https://docs.rs/clap/latest/clap/builder/struct.Command.html This example demonstrates how to build a complex CLI application with multiple subcommands, each having its own arguments and configurations. It uses `Command::new` and various subcommand and argument definition methods. ```rust 6fn cli() -> Command { Command::new("git") .about("A fictional versioning CLI") .subcommand_required(true) .arg_required_else_help(true) .allow_external_subcommands(true) .subcommand( Command::new("clone") .about("Clones repos") .arg(arg!( "The remote to clone")) .arg_required_else_help(true), ) .subcommand( Command::new("diff") .about("Compare two commits") .arg(arg!(base: [COMMIT])) .arg(arg!(head: [COMMIT])) .arg(arg!(path: [PATH]).last(true)) .arg( arg!(--color ) .value_parser(["always", "auto", "never"]) .num_args(0..=1) .require_equals(true) .default_value("auto") .default_missing_value("always"), ), ) .subcommand( Command::new("push") .about("pushes things") .arg(arg!( "The remote to target")) .arg_required_else_help(true), ) .subcommand( Command::new("add") .about("adds things") .arg_required_else_help(true) .arg(arg!( ... "Stuff to add").value_parser(clap::value_parser!(PathBuf))), ) .subcommand( Command::new("stash") .args_conflicts_with_subcommands(true) .flatten_help(true) .args(push_args()) .subcommand(Command::new("push").args(push_args())) .subcommand(Command::new("pop").arg(arg!([STASH]))) .subcommand(Command::new("apply").arg(arg!([STASH]))), ) } ```