Support subcommand #1

Open
TeXitoi opened this Issue Feb 7, 2017 · 4 comments

Projects

None yet

2 participants

@TeXitoi
Owner
TeXitoi commented Feb 7, 2017

The idea would be to create StructOpt struct for each subcommand, and then dispatching on an enum on the principal StructOpt.

@ErichDonGubler

So, something like this?

#[derive(StructOpt, Debug)]
#[structopt(name = "git", about = "Because git is great!")]
enum GitCommand {
    #[structopt(name = "fetch")]
    Fetch {
        #[structopt(help = "Remote to fetch from", default_value = "None")]
        remote: Option<&str>, // Ignoring lifetime here
        #[structopt(help = "Branch to fetch from", default_value = "None")]
        branch: Option<&str> // Ignoring lifetime here
    },
    #[structopt(name = "commit")]
    Commit {
        #[structopt(short = "a", long = "all", help = "Adds all tracked files to the index before commit", default_value = "false")]
        all: bool,
        #[structopt(short = "p", long = "patch", help = "Use interactive patching interface for staging", default_value = "false")]
        patch: bool,
        #[structopt(short = "m", long = "message", help = "Add a commit message via CLI args instead of using $EDITOR", default_value = "None")]
        message: Option<&str> // Ignoring lifetime here
    }
}

fn main () {
    match Opt::from_args() {
        Fetch { remote, branch } => {
            //...
        },
        Commit { all, patch, message } => {
            //...
        }
    }
}
@TeXitoi
Owner
TeXitoi commented Feb 16, 2017

The idea was:

#[derive(StructOpt)]
#[structopt(name = "git", about = "Because git is great!")]
struct App {
    #[structopt(subcommand)]
    subcommand: SubCommand,
}
#[derive(StructOptSubCommand)]
enum SubCommand {
     #[structopt(name = "fetch")]
    Fetch(Fetch),
    #[structopt(name = "commit")]
    Commit(Commit),
}
#[derive(StructOpt)]
struct Fetch {
    #[structopt(help = "Remote to fetch from")]
    remote: Option<String>,
    #[structopt(help = "Branch to fetch from")]
    branch: Option<String>,
}
#[derive(StructOpt)]
struct Commit {
    #[structopt(short = "a", long = "all", help = "Adds all tracked files to the index before commit")]
    all: bool,
    #[structopt(short = "p", long = "patch", help = "Use interactive patching interface for staging")]
    patch: bool,
    #[structopt(short = "m", long = "message", help = "Add a commit message via CLI args instead of using $EDITOR")]
    message: Option<String>,
}

But I like your idea a lot. My solution is more flexible, but yours is much more compact for simpler use case.

Some comments on your proposition:

  • we can't have &str in the struct, but just using String do the trick
  • you don't want default_value for bool and Option, it will not do what you want (nothing for bool, you'll get Some("None") for Option
@ErichDonGubler

How do you get a None for Options?

@TeXitoi
Owner
TeXitoi commented Feb 17, 2017

By omitting an optional argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment