Expand description

A command-map pattern for easily configuring and dispatching modular subcommands using the Clap argument parser.

The first part is the ActionCommand trait, which is implemented to associate a behavior with a clap::Command.

static NAME_ARG: &str = "name";

struct HelloWorldCommand {}

impl ActionCommand for HelloWorldCommand {
    // This specifies the name of the ActionCommand, so hello-world
    // here would be invokable as my-program hello-world if it were
    // to be run from a binary called my-program.
    fn name(&self) -> &'static str {
        "hello-world"
    }

    // This is the command builder. The command itself is configured
    // with the name given previously, and here it may be configured
    // with additional args or aliases.
    fn command(&self, command: Command) -> Command {
        command
            .about("Say hello to the world")
            .alias("h")
            .arg(
                Arg::new(NAME_ARG)
                    .short('n')
                    .value_name("NAME")
                    .required(false)
                    .value_parser(NonEmptyStringValueParser::new())
            )
    }

    // The action to take when the ActionCommand is matched, given
    // a list of all (sub)commands for argument/flag retrieval.
    fn action(
        &self, matches: Vec1<&ArgMatches>
    ) -> Result<(), Box<dyn std::error::Error>> {
        if let Some(name_arg) =
                get_one::<String>(&matches, NAME_ARG) {
            println!("Hello, {}!", name_arg);
        } else {
            println!("Hello, world!");
        }

        Ok(())
    }
}

The second part is the CommandMap type, which aggregates one or more ActionCommands and handles dispatching to them based on a clap::ArgMatches.

// Add commands to the map by pushing ActionCommand trait objects
// onto the map
let command_map = CommandMap::builder()
    .push(HelloWorldCommand {})
    .build();
// Tell the relevant Clap Command about all the subcommands
let command = Command::new("my-program")
    .subcommands(command_map.commands());
let matches = command.get_matches_from(
    ["my-program", "hello-world"]
);
// Dispatch to the relevant subcommand, saving some if/else-if
// chains
command_map.dispatch(vec1![&matches]);

Re-exports

pub use vec1;

Structs

A type which has a set of ActionCommands and can provide the Clap Command for command line arg parsing, as well as map a matched Command back to its ActionCommand for dispatch to its action function.
An ActionCommand that only composes a CommandMap’s subcommands. Any customization of the clap::Command or the behavior of CommandMapActionCommand::action will require a custom type.
Used to fluently construct CommandMaps.

Enums

Traits

A type that encapsulates the Clap Command and associated behavior of that command when it is matched.

Functions

Helper function for dealing with chains of ArgMatches while working in ActionCommand::action to find arguments which may have been spcified anywhere in the subcommand tree.
Helper function for dealing with chains of ArgMatches while working in ActionCommand::action to find arguments which may have been specified anywhere in the subcommand tree.
Helper function for dealing with chains of ArgMatches while working in ActionCommand::action to find arguments which may have been specified anywhere in the subcommand tree.