Skip to main content

ArgGroup

Derive Macro ArgGroup 

Source
#[derive(ArgGroup)]
{
    // Attributes available to this derive:
    #[usage]
    #[command]
    #[arg]
    #[value]
    #[group]
}
Expand description

Compile an enum into a set of related flags.

Exclusive or ordered flags as enum variants, so the code that reads them matches on a type rather than on which of several fields is set. Each variant is one switch, named by its own name in kebab-case:

#[derive(usage::ArgGroup)]
#[usage(name = "format")]
enum Format {
    /// Print JSON
    Json,
    /// Print YAML
    Yaml,
    #[usage(short = 'p', long = "plain")]
    PlainText,
}

Only a variant’s doc comment becomes that switch’s help; the enum’s own docs are not read, because a group has no help of its own — the members do.

A field holds one and says arg_group. Option<Format> is a group that may be left alone and a bare Format is one that has to be given — the same rule every other field’s type is read by, and the only spelling of required-ness a group has, since there is no default variant:

#[derive(usage::Cli)]
#[usage(bin = "ex")]
struct Ex {
    #[usage(arg_group)]
    format: Option<Format>,
}

Nothing new reaches the spec: the enum lowers to the group node and the flags it names, so --json --yaml is the same Error::ConflictingFlags a hand-written group produces, and a missing member of a required one is the same Error::MissingGroup. A tuple variant with one field is a value-taking member such as Migrate(Source); value_name and value_enum describe that payload exactly as they do on an ordinary flag.

#[usage(multiple)] changes the group into an ordered instruction stream. Hold it as Vec<Mode> and every occurrence is returned in argv order, including interleaved variants.

A variant’s doc comment becomes its help. help = "...", long_help = "...", hide, and short = 'x' are the rest of what a member has; cfg and cfg_attr are copied to the variant’s entries in the static tables, as ValueEnum copies them.