use gumdrop::Options; // Define options for the program. #[derive(Debug, Options)] struct MyOptions { // Options here can be accepted with any command (or none at all), // but they must come before the command name. #[options(help = "print help message")] help: bool, #[options(help = "be verbose")] verbose: bool, // The `command` option will delegate option parsing to the command type, // starting at the first free argument. #[options(command)] command: Option, } // The set of commands and the options each one accepts. // // Each variant of a command enum should be a unary tuple variant with only // one field. This field must implement `Options` and is used to parse arguments // that are given after the command name. #[derive(Debug, Options)] enum Command { // Command names are generated from variant names. // By default, a CamelCase name will be converted into a lowercase, // hyphen-separated name; e.g. `FooBar` becomes `foo-bar`. // // Names can be explicitly specified using `#[options(name = "...")]` #[options(help = "make stuff")] Make(MakeOpts), #[options(help = "install stuff")] Install(InstallOpts), } // Options accepted for the `make` command #[derive(Debug, Options)] struct MakeOpts { #[options(help = "print help message")] help: bool, #[options(free)] free: Vec, #[options(help = "number of jobs", meta = "N")] jobs: Option, } // Options accepted for the `install` command #[derive(Debug, Options)] struct InstallOpts { #[options(help = "print help message")] help: bool, #[options(help = "target directory")] dir: Option, } fn main() { // Parse options from the environment. // If there's an error or the user requests help, // the process will exit after giving the appropriate response. let opts = MyOptions::parse_args_default_or_exit(); println!("{:#?}", opts); }