support subcommand?
hh9527 opened this issue · comments
Something like this perhaps:
#[derive(Debug, Default, Options)]
struct MyOptions {
// Contains "free" arguments -- those that are not options.
// If no `free` field is declared, free arguments will result in an error.
#[options(free)]
free: Vec<String>,
// Common to all subcommands
common_string: String,
// Subcommand specifier
#[options(subcommand)]
subcommand: MyOptionsSubcommand,
}
#[derive(Options)]
#[options(subcommand)] // Or just infer that this is a subcommand since it's an enum, not a struct
enum MyOptionsSubcommand {
// foo subcommand
Foo {
// foo-specific arg
baz: String,
},
// bar subcommand
Bar {
// bar-specific arg
quux: String,
},
}
I was thinking something like this:
#[derive(Debug, Default, Options)]
struct MyOptions {
// Some common options could go here...
#[options(command)]
sub: Option<Command>,
}
#[derive(Debug, Options)]
enum Command {
Foo(FooOpts),
}
#[derive(Debug, Default, Options)]
struct FooOpts {
opt: String,
}
I think maybe I could support both the options-as-struct method (which would be useful for passing FooOpts
to a function that implements the chosen command) and the options-as-enum-variant-fields option, which may be more convenient for quick stuff.
I'm going to do some tinkering and see what I can come up with.
Okay, I decided against supporting the struct-variant-as-options alternative. I think it would make a mess of the codegen to duplicate the option parsing code on each variant. Using the options-as-struct alternative, subcommand options are simply another derive(Options)
struct, even able to contain sub-subcommands, if your heart desires. You can see an example of its usage in the crate docs, as well as examples/commands.rs
in the repo.
I've published the new feature to crates.io. Let me know if there are any issues with it.