Skip to main content

Subcommands

Trait Subcommands 

Source
pub trait Subcommands: Sized {
    type Partial: Default;

    const COMMANDS: &'static [&'static Command<'static>];
    const METAS: &'static [&'static CommandMeta<'static>];
    const HAS_EXTERNAL: bool = false;
    const EXTERNAL: Option<usize> = None;
    const VARIANT_OF: &'static [usize] = _;
    const SETTINGS_BINDINGS: &'static [(&'static str, &'static str)] = _;
Show 15 methods // Required methods fn apply( partial: &mut Self::Partial, selected: Option<usize>, event: &Event<'_, '_, '_>, ) -> bool; fn check<'t, 'v>( partial: &mut Self::Partial, selected: usize, ) -> Result<(), Error<'t, 'v>>; fn select<'t, 'v>( partial: Self::Partial, selected: usize, ) -> Result<Option<Self>, Error<'t, 'v>>; // Provided methods fn begin(partial: &mut Self::Partial, selected: usize) { ... } fn settings_given( partial: &Self::Partial, selected: Option<usize>, ) -> Vec<(&'static str, SettingGiven)> { ... } fn any_given( partial: &Self::Partial, selected: Option<usize>, ) -> Option<&'static str> { ... } fn exclusive_given( partial: &Self::Partial, selected: Option<usize>, ) -> Option<&'static str> { ... } fn deprecations( partial: &Self::Partial, selected: Option<usize>, out: &mut Vec<Warning<'static>>, ) { ... } fn deprecations_for_view_path( partial: &Self::Partial, selected: Option<usize>, remaining_commands: usize, out: &mut Vec<Warning<'static>>, ) { ... } fn apply_env(partial: &mut Self::Partial, selected: Option<usize>) { ... } fn apply_env_for_view_path( partial: &mut Self::Partial, selected: Option<usize>, remaining_commands: usize, ) { ... } fn check_for_view_path<'t, 'v>( partial: &mut Self::Partial, selected: usize, remaining_commands: usize, ) -> Result<(), Error<'t, 'v>> { ... } fn apply_env_update( partial: &mut Self::Partial, selected: Option<usize>, standing: &Self, ) { ... } fn check_update<'t, 'v>( partial: &mut Self::Partial, selected: usize, standing: &Self, ) -> Result<(), Error<'t, 'v>> { ... } fn merge_into<'t, 'v>( partial: Self::Partial, selected: usize, standing: &mut Self, ) -> Result<(), Error<'t, 'v>> { ... }
}
Expand description

An enum whose variants are a command’s subcommands.

Implemented by the derive on the enum a subcommand field holds.

Required Associated Constants§

Source

const COMMANDS: &'static [&'static Command<'static>]

The parse tables for the variants, to splice into the parent command’s static tables — hence a const. See CommandArgs::COMMAND.

Source

const METAS: &'static [&'static CommandMeta<'static>]

The metadata for the variants, in the same order.

Provided Associated Constants§

Source

const HAS_EXTERNAL: bool = false

Whether one of these variants is an external_subcommand.

Source

const EXTERNAL: Option<usize> = None

The variant index of the catch-all, if any. Not a position in [COMMANDS]: an external variant is not a named command.

Source

const VARIANT_OF: &'static [usize] = _

Maps a position in [COMMANDS] to a variant index.

Identity when there is no catch-all. When [HAS_EXTERNAL] is set, the named commands sit in COMMANDS without the external variant, so a table position is not a variant index and this is how the two are tied together.

Source

const SETTINGS_BINDINGS: &'static [(&'static str, &'static str)] = _

Every flag any of these commands reads into a setting, and the setting it sets.

Every variant’s, not the selected one’s: a binding table says what the CLI can do, and is compared against a spec that documents all of them.

Required Associated Types§

Source

type Partial: Default

Values collected for whichever variant is being filled.

Required Methods§

Source

fn apply( partial: &mut Self::Partial, selected: Option<usize>, event: &Event<'_, '_, '_>, ) -> bool

Take one event, and say whether it belonged to the selected command.

selected is a variant index, or None before any of them has been reached — in which case the event cannot be theirs and nothing is asked.

Only the selected one is asked, which is both cheaper and necessary. Cheaper because a CLI with a hundred subcommands would otherwise offer every event to all hundred. Necessary because two commands can legitimately hold the same declaration once #[usage(flatten)] exists: mise gives one ConfigLs to both config and config ls, so the same key is in both tables, and whichever was asked first would claim the event — including a command the user never named.

Source

fn check<'t, 'v>( partial: &mut Self::Partial, selected: usize, ) -> Result<(), Error<'t, 'v>>

Check the selected command’s requirements, and nothing else’s.

A flag that install requires says nothing about an invocation that ran run, so only the command that was actually reached is judged.

selected is a variant index, the same value [apply] is given — mapped through [VARIANT_OF] when [HAS_EXTERNAL] is set, so it is not a position in [COMMANDS]. Two commands whose keys happen to collide still cannot be confused for one another: the index names the variant, not a table slot.

Source

fn select<'t, 'v>( partial: Self::Partial, selected: usize, ) -> Result<Option<Self>, Error<'t, 'v>>

Build the variant at selected, a variant index.

The same index [apply] and [check] take — mapped through [VARIANT_OF] when [HAS_EXTERNAL] is set, so it is not a position in [COMMANDS]. An external variant is not in that table, and a caller that indexed COMMANDS by this value would read the wrong command or go out of bounds.

None when no variant was selected, which a caller reads as “no subcommand was given”. An Err comes from building the variant that was selected.

Provided Methods§

Source

fn begin(partial: &mut Self::Partial, selected: usize)

Make room for the variant at selected, if it is not already the one being filled.

Called when a command word selects a variant, before any event reaches it. Subcommands::Partial holds one command’s values rather than every command’s, so the storage for a variant comes into being here instead of at the start of the parse: an invocation that reached mise use never materialises the other 209.

Idempotent by contract. A second call naming the variant already being filled must leave what has been collected alone — a restart token can re-announce the command that is already selected, and re-starting it there would discard the parse so far.

The default does nothing, which is correct for a Partial that has room for every variant from the start.

Source

fn settings_given( partial: &Self::Partial, selected: Option<usize>, ) -> Vec<(&'static str, SettingGiven)>

The settings the selected command was given values for, and no other command’s.

None selected is nothing given, which is also what a CLI that reached no subcommand contributed. Unlike the bindings, this is about one invocation.

Source

fn any_given( partial: &Self::Partial, selected: Option<usize>, ) -> Option<&'static str>

One declaration in the selected command that was given, if any.

Source

fn exclusive_given( partial: &Self::Partial, selected: Option<usize>, ) -> Option<&'static str>

One exclusive flag in the selected command that was given, if any.

This lets the parent compare its own fields with the selected child’s without exposing the child’s generated partial type.

Source

fn deprecations( partial: &Self::Partial, selected: Option<usize>, out: &mut Vec<Warning<'static>>, )

The deprecated declarations the selected command used, and the command itself if its own declaration is deprecated.

Every deprecated command on the selected path reports, not only the last one: a deprecated group whose child is fine was still the way in. See CommandArgs::deprecations for when this is asked and why the milestone gate is not applied here.

Source

fn deprecations_for_view_path( partial: &Self::Partial, selected: Option<usize>, remaining_commands: usize, out: &mut Vec<Warning<'static>>, )

Report the selected command’s deprecations, traversing a view’s injected parents.

Under an executable view the words the view injected are the program’s own identity — aubr is aube run — so neither the promoted command nor anything routing to it is reported, for the same reason the root never is. Whatever the user selected below it is.

The default treats the promoted command as an ordinary selection, which is the most a hand-written implementation can do without knowing its own variants; a derived one knows which commands the view injected and leaves them out.

Source

fn apply_env(partial: &mut Self::Partial, selected: Option<usize>)

Fill fields in the selected command from their declared environment variables.

A parent calls this before relationships that cross the subcommand boundary, just as CommandArgs::apply_env prepares a flattened argument group.

Source

fn apply_env_for_view_path( partial: &mut Self::Partial, selected: Option<usize>, remaining_commands: usize, )

Fill environment fallbacks on the promoted command, traversing injected parents.

Source

fn check_for_view_path<'t, 'v>( partial: &mut Self::Partial, selected: usize, remaining_commands: usize, ) -> Result<(), Error<'t, 'v>>

Check the promoted command, traversing injected parents without validating them.

Source

fn apply_env_update( partial: &mut Self::Partial, selected: Option<usize>, standing: &Self, )

Subcommands::apply_env on an update, filling only what the caller lacks.

Source

fn check_update<'t, 'v>( partial: &mut Self::Partial, selected: usize, standing: &Self, ) -> Result<(), Error<'t, 'v>>

Subcommands::check against the union of this argv and what the caller had.

Only when the selected variant is the one standing already holds. Selecting a different command is a routing decision rather than a value to merge, so the old variant’s fields say nothing about the new one’s requirements.

Source

fn merge_into<'t, 'v>( partial: Self::Partial, selected: usize, standing: &mut Self, ) -> Result<(), Error<'t, 'v>>

Merge the selected variant into the one the caller already has.

The same variant merges field-wise; a different one replaces it wholesale, discarding the old variant’s fields. The default always replaces, which is what a hand-written implementation can promise without seeing its own variants.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§