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-Commands, because they can contain their own arguments, subcommands, version, usage, etc. They also function just like Commands, 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.