Skip to main content

Subcommand

Derive Macro Subcommand 

Source
#[derive(Subcommand)]
{
    // Attributes available to this derive:
    #[arg]
    #[winnow_args]
}
Expand description

Derive Subcommand (and Args, so the enum can be the whole command line) for an enum of subcommands.

A variant is a unit, or holds one Args type, which may be Boxed; a parent struct holds the enum in a subcommand field. The doc comments are the help text. As a whole command line the enum has no name, version or about: wrap it in a struct for those, and for completion scripts.

ⓘ
use winnow_args::{Args, Subcommand};

#[derive(Args, Debug, PartialEq)]
struct Add {
    #[arg(positional)]
    paths: Vec<String>,
}

#[derive(Subcommand, Debug, PartialEq)]
enum Command {
    /// Stage files.
    Add(Add),
    /// Show what changed.
    #[arg(alias = "st")]
    Status,
}

#[derive(Args, Debug)]
struct Git {
    /// Say less.
    #[arg(short, long, global)]
    quiet: bool,
    #[arg(subcommand)]
    command: Command,
}

let git = Git::parse_from(["add", "-q", "a", "b"])?;
assert!(git.quiet);
assert_eq!(git.command, Command::Add(Add { paths: vec!["a".into(), "b".into()] }));
assert_eq!(Git::parse_from(["st"])?.command, Command::Status);

match git.command {
    Command::Add(Add { paths }) => println!("staging {paths:?}"),
    Command::Status => println!("on branch main"),
}
  • Enum: rename_all = "…": the case of variant names, one of "kebab-case" (default), "lowercase", "UPPERCASE", "snake_case" and "verbatim".
  • Variant: name = "…": the word that selects it.
  • Variant: alias = "…", alias("…", …): other words, shown in help; alias_hidden is the same, not shown.
  • Variant: hide: leave it out of the list in help and completion.
  • Variant: help = "…": the one-line description; long_help = "…" is accepted and unused in the list.