Clap
is a very powerful command line parser, written in Rust.
You can find its documentation here.
To better understand how it works, let’s create a simple CLI program that takes a string as input and, depending on the command, reverse or inspect it.
Here you can find the full code: Github!
Clone the repo and try it your self to see how it works in practice.
Note: it’s not wrong, just not recommended since it is much more verbose and difficult to understand. Still it’s very useful to study because it shows the real generated code.
let matches = command!()
.about("stringer - a simple CLI to transform and inspect strings")
.long_about(
"stringer is a super fancy CLI (kidding)
One can use stringer to modify or inspect strings straight from the terminal",
)
.subcommand(
Command::new("reverse")
.about("Reverses a string")
.arg(arg!([STRING] "The string to reverse")),
)
.subcommand(
Command::new("inspect")
.about("Inspects a string")
.arg(arg!([STRING] "The string to inspect"))
.arg(arg!(-d --digits "only digits")),
)
.get_matches();
Let’s break it down step-by-step:
command!
: it’s a macro (you need the cargo
feature in clap
crate) that builds a Command
from the Cargo.toml
file. This is important for things like author and version.
about
: sets the program's description for the short help (-h
).
long_about
: Sets the program's description for the long help (--help
).
subcommand
: adds a subcommand to the list of valid possibilities. Subcommands are effectively sub-Command
s, because they can contain their own arguments, subcommands, version, usage, etc. They also function just like Command
s, in that they get their own auto generated help, version, and usage.
Command
: builds a command-line interface. This includes defining arguments, subcommands, parser behaviour, and help output.
arg
: adds an [argument] to the list of valid possibilities.
Note that every argument is not required by default. To do that you have to add .required(true)
, like this:
.arg(arg!([STRING] "The string to reverse").required(true))
To understand it better take these two examples:
In this example we add an argument using the Command.arg(…)
method. Then we use the arg! macro to create an argument through a usage string.
In this particular case we add an argument that is something passed by the user and is called “STRING”.
.arg(arg!([STRING] "The string to reverse"))
In this example we add an argument using the Command.arg(…)
method. Then we use the arg! macro to create an argument through a usage string.
In this particular case we add an argument that is a flag called “digits” that is set to false by default while it’s true if the flag is present.
arg(arg!(-d --digits "only digits"))
get_matches()
: parse env::args_os
(arguments passed by command line), exiting on failure.