cargo add structopt
structopt allows us to derive argument parsing functionality from our structs. The name is a play on struct Opt {}
. To do this we need to derive(StructOpt)
on our struct. In this case we have a subcommand, so we'll set up one of the fields on the Opt
struct to be a structopt(subcommand)
. This subcommand value will be an enum, indicating that only one subcommand can be used at a time.
structopt also gives us tools to specify one of three argument types:
- positional
- short
- long
By default every argument is a positional argument, which means that in this case if we left it as-is, the CLI would function as
garden write my-title
We want to use a flag, so we'll use structopt to generate short and long flags for the title argument with structopt(short, long)
. That gives the use the option of -t
and --title
to specify a title.
structopt also contains some type processing, so all we need to do is specify that title is an optional string and the flags will become optional. That is: a user can specify or not specify a title.
struct Opt {
#[structopt(subcommand)]
cmd: Command,
}
enum Command {
Write {
#[structopt(short, long)]
title: Option<String>,
},
}
After setting up struct Opt
, we can parse the args and use the dbg!() macro to print them to the console so we can see what they look like.
let opt = Opt::from_args();
dbg!(opt);
To do that we also need to derive(Debug)
in addition to
structopt on both the enum and the struct.
Given input like
garden write
We will see the following output.
[src/main.rs:21] opt = Opt {
cmd: Write {
title: None,
},
}
We can choose to cargo build
and then ./target/debug/garden write
or we can use cargo run -- write
. The --
ensures that our arguments get passed to the CLI we're building and not cargo run
. This is especially relevant when passing something like --help
.