Structopt: Adding subcommands to a pre-existing structopt

Created on 14 Jan 2020  路  10Comments  路  Source: TeXitoi/structopt

@CreepySkeleton I think that's the missing feature: we would like to be able to extend an enum of subcommands from another crate.

To be clear it doesn't have to use flatten in this fashion. But it would be nice if there would be a way to add a subcommand to an existing list of subcommands. Unfortunately Rust won't allow adding variants in the enum, the usual way to deal with this is this: https://stackoverflow.com/questions/25214064/can-i-extend-an-enum-with-additional-values#25214677 so there should be a way to tell structopt that the subcommands in the variant (BaseCli::Command1) should be at the same level than the subcommands in the parent enum (ExtendedCli::Command2).

This issue relates to #20 but is different as this is importing a StructOpt from a different crate.

This issue relates to #307

Code

use structopt::StructOpt;

// This come from another crate
#[derive(Debug, StructOpt)]
enum BaseCli {
    Command1(Command1),
}

#[derive(Debug, StructOpt)]
struct Command1 {
    argument1: String,
}

// This is the structopt for this crate
#[derive(Debug, StructOpt)]
enum ExtendedCli {
    #[structopt(flatten)]
    BaseCli(BaseCli),
    Command2(Command2),
}

#[derive(Debug, StructOpt)]
struct Command2 {
    argument2: String,
}

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

Expected Result

test-struct-opt 0.1.0

USAGE:
    test-struct-opt <SUBCOMMAND>

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    command1
    command2
    help        Prints this message or the help of the given subcommand(s)

Actual Result

error: flatten is only allowed on fields
  --> src/main.rs:15:17
   |
15 |     #[structopt(flatten)]
   |                 ^^^^^^^

All 10 comments

I would go for subcommand here instead of flatten, but... don't know, both names are good enough.

Also, I would like it to be a part of clap_derive, I'm not going to work on this personally because... come on, let's get clap_derive working already!

Can't we do this kind of thing with #314 and reparsing the Vec into your extended opt using from_iter?

Actually this ticket seems totally related to #130

130 is already implemented in #314 . And no, this is different.

That's not the asked syntax, but it might resolve the needed feature.

I'm afraid it won't because I can't just import an instantiated Vec from one crate to another...

Not really. What he's asking for is "flatten subcommands in the same manner we're flattening structs", he's not asking to "accept every possible subcommand".

*she

But yes this is very different

@cecton sorry, I don't really look at avatars...

The feature needed is "allow to have an Enum for extended subcommand". While maybe less ergonomic, it would be possible with something like that:

let opt = BaseOpt::from_args();
let extended = match &opt.cmd {
    Some(Extended(v)) => Some(ExtendedOpt::from_iter(v)),
    _ => None,
};
Was this page helpful?
0 / 5 - 0 ratings

Related issues

tathanhdinh picture tathanhdinh  路  3Comments

jackjen picture jackjen  路  7Comments

bb010g picture bb010g  路  9Comments

rask picture rask  路  8Comments

polarathene picture polarathene  路  6Comments