updated and repaired clap-basic.md

* Brought example code to clap version 4, noted in doc.
* Removed turbofishes from example code.
* Changed to use PathBuf for filenames; documented this.
This commit is contained in:
Bart Massey 2024-04-07 18:58:56 -07:00
parent 752b035c1a
commit bfb0fe31d9

View file

@ -6,39 +6,55 @@ This application describes the structure of its command-line interface using
`clap`'s builder style. The [documentation] gives two other possible ways to
instantiate an application.
In the builder style, `with_name` is the unique identifier that `value_of` will
use to retrieve the value passed. The `short` and `long` options control the
The code here requires `clap` version 4. Use `clap = "4"` in
your `Cargo.toml` to get the correct version.
In the builder style, each possible argument is described by an `Arg`
struct. The string given to `Arg::new()` is the internal
name of the argument. The `short` and `long` options control the
flag the user will be expected to type; short flags look like `-f` and long
flags look like `--file`.
The `get_one()` method is used to get an argument's value.
It returns `Some(&`value`)` if the argument was supplied by
the user, else `None`.
The use of `PathBuf` is to allow file paths which are legal
in Linux and MacOS, but not in Rust UTF-8 strings. This is
best practice: one encounters such paths quite rarely in
practice, but when it happens it is really frustrating
without this.
```rust,edition2018
use clap::{Arg, App};
use std::path::PathBuf;
use clap::{Arg, Command, builder::PathBufValueParser};
fn main() {
let matches = App::new("My Test Program")
let matches = Command::new("My Test Program")
.version("0.1.0")
.author("Hackerman Jones <hckrmnjones@hack.gov>")
.about("Teaches argument parsing")
.arg(Arg::with_name("file")
.short("f")
.arg(Arg::new("file")
.short('f')
.long("file")
.takes_value(true)
.help("A cool file"))
.arg(Arg::with_name("num")
.short("n")
.help("A cool file")
.value_parser(PathBufValueParser::default()))
.arg(Arg::new("num")
.short('n')
.long("number")
.takes_value(true)
.help("Five less than your favorite number"))
.get_matches();
let myfile = matches.value_of("file").unwrap_or("input.txt");
println!("The file passed is: {}", myfile);
let default_file = PathBuf::from("input.txt");
let myfile: &PathBuf = matches.get_one("file").unwrap_or(&default_file);
println!("The file passed is: {}", myfile.display());
let num_str = matches.value_of("num");
let num_str: Option<&String> = matches.get_one("num");
match num_str {
None => println!("No idea what your favorite number is."),
Some(s) => {
match s.parse::<i32>() {
let parsed: Result<i32, _> = s.parse();
match parsed {
Ok(n) => println!("Your favorite number must be {}.", n + 5),
Err(_) => println!("That's not a number! {}", s),
}
@ -47,24 +63,19 @@ fn main() {
}
```
Usage information is generated by `clap`. The usage for the example application
looks like this.
Usage information is generated by `clap -h`. The usage for
the example application looks like this.
```
My Test Program 0.1.0
Hackerman Jones <hckrmnjones@hack.gov>
Teaches argument parsing
USAGE:
testing [OPTIONS]
Usage: clap-cookbook [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-f, --file <file> A cool file
-n, --number <num> Five less than your favorite number
Options:
-f, --file <file> A cool file
-n, --number <num> Five less than your favorite number
-h, --help Print help
-V, --version Print version
```
We can test the application by running a command like the following.