No description
Find a file
2018-02-03 16:55:43 +01:00
examples structopt reexport structopt_derive 2018-02-03 16:55:43 +01:00
src structopt reexport structopt_derive 2018-02-03 16:55:43 +01:00
structopt-derive As the dummy const trick never worked as there was a bug, just remove it 2018-02-03 16:55:43 +01:00
tests structopt reexport structopt_derive 2018-02-03 16:55:43 +01:00
.gitignore Init project 2017-02-03 01:17:31 +01:00
.travis.yml Init project 2017-02-03 01:17:31 +01:00
Cargo.toml structopt reexport structopt_derive 2018-02-03 16:55:43 +01:00
CHANGELOG.md Update CHANGELOG.md 2018-02-03 16:53:31 +01:00
COPYING Init project 2017-02-03 01:17:31 +01:00
README.md structopt reexport structopt_derive 2018-02-03 16:55:43 +01:00

StructOpt Build status

Parse command line argument by defining a struct. It combines clap with custom derive.

Documentation

Find it on Docs.rs: structopt-derive and structopt.

Example

Add structopt and structopt-derive to your dependencies of your Cargo.toml:

[dependencies]
structopt = "0.1.0"
structopt-derive = "0.1.0"

And then, in your rust file:

#[macro_use]
extern crate structopt;

use structopt::StructOpt;

#[derive(StructOpt, Debug)]
#[structopt(name = "example", about = "An example of StructOpt usage.")]
struct Opt {
    /// A flag, true if used in the command line.
    #[structopt(short = "d", long = "debug", help = "Activate debug mode")]
    debug: bool,

    /// An argument of type float, with a default value.
    #[structopt(short = "s", long = "speed", help = "Set speed", default_value = "42")]
    speed: f64,

    /// Needed parameter, the first on the command line.
    #[structopt(help = "Input file")]
    input: String,

    /// An optional parameter, will be `None` if not present on the
    /// command line.
    #[structopt(help = "Output file, stdout if not present")]
    output: Option<String>,
}

fn main() {
    let opt = Opt::from_args();
    println!("{:?}", opt);
}

Using this example:

$ ./example
error: The following required arguments were not provided:
    <input>

USAGE:
    example [FLAGS] [OPTIONS] <input> [ARGS]

For more information try --help
$ ./example --help
example 0.0.0
Guillaume Pinot <texitoi@texitoi.eu>
An example of StructOpt usage.

USAGE:
    example [FLAGS] [OPTIONS] <input> [ARGS]

FLAGS:
    -d, --debug      Activate debug mode
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -s, --speed <speed>    Set speed [default: 42]

ARGS:
    <input>     Input file
    <output>    Output file, stdout if not present
$ ./example foo
Opt { debug: false, speed: 42, input: "foo", output: None }
$ ./example -ds 1337 foo bar
Opt { debug: true, speed: 1337, input: "foo", output: Some("bar") }

Why

I use docopt since a long time (pre rust 1.0). I really like the fact that you have a structure with the parsed argument: no need to convert String to f64, no useless unwrap. But on the other hand, I don't like to write by hand the usage string. That's like going back to the golden age of WYSIWYG editors. Field naming is also a bit artificial.

Today, the new standard to read command line arguments in Rust is clap. This library is so feature full! But I think there is one downside: even if you can validate argument and expressing that an argument is required, you still need to transform something looking like a hashmap of string vectors to something useful for your application.

Now, there is stable custom derive. Thus I can add to clap the automatic conversion that I miss. Here is the result.