I really like Rust’s StructOpt crate
April 30th, 2019
I’ve been playing around with Rust for a while now and recently wrote a little tool that I wanted to run via the CLI. The Command Line Applications in Rust book written by the Rust CLI Working Group pointed me towards StructOpt which I liked using so I thought I’d put a little overview here.
What is it
StructOpt
is a set of macros that wraps the clap crate to make configuring and parsing a CLI interface into a configuration struct easy.
So far I’ve found it nice to use and I like how the resulting code looks. I usually try and avoid “magic” macros that aren’t essential but in this case I think they make something readable and are worth the extra level of indirection.
It’s not that plain clap
is bad, it isn’t, but I prefer the more declarative style of StructOpt
in this case.
An example
Here’s a trivial example that show just some of what I like about the crate.
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(name = "Some CLI tool")]
struct Options {
// normal comments are just comments
/// doc comments get turned into help
#[structopt(short = "e", long = "example")]
: bool,
example
// The number of occurrences of the `v/verbose` flag
/// Verbose mode (-v, -vv, -vvv, etc.)
#[structopt(short = "v", long = "verbose", parse(from_occurrences))]
: u8,
verbose}
fn main() {
let options = Options::from_args();
println!("{:?}", options);
}
Building and running this shows how StructOpt
makes a good help screen:
./target/debug/sopt --help
Some CLI tool 0.1.0
Chris McGrath <chris@chrismcg.com>
USAGE:
sopt [FLAGS]
FLAGS:
-e, --example doc comments get turned into help
-h, --help Prints help information
-V, --version Prints version information -v, --verbose Verbose mode (-v, -vv, -vvv, etc.)
It picks up author and version information from the Cargo.toml
file but allows for overriding via the attributes.
Running with the actual options:
./target/debug/sopt -vvvv -e Options { example: true, verbose: 4 }
You can see that the Options
struct is populated without having to write very much code yourself.
Summary
This post just scratches the surface of what’s possible with StructOpt
and clap. I’ve not showing parsing number, paths, handling sub commands etc. which are all possible.
It’s also worth pointing out that the in progress version 3.0 of clap intends to incorporate StructOpt so in the future you won’t need two separate crates.