murarth / gumdrop

Rust option parser with custom derive support

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.