Skip to main content

#
interop_hand_subcommand/
hand_subcommand.rs

    1#![allow(dead_code)]
    2use clap::error::{Error, ErrorKind};
    3use clap::{ArgMatches, Args as _, Command, FromArgMatches, Parser, Subcommand};
    4
    5#[derive(Parser, Debug)]
    6struct AddArgs {
    7    name: Vec<String>,
    8}
    9#[derive(Parser, Debug)]
    10struct RemoveArgs {
    11    #[arg(short, long)]
    12    force: bool,
    13    name: Vec<String>,
    14}
    15
    16#[derive(Debug)]
    17enum CliSub {
    18    Add(AddArgs),
    19    Remove(RemoveArgs),
    20}
    21
    22impl FromArgMatches for CliSub {
    23    fn from_arg_matches(matches: &ArgMatches) -> Result<Self, Error> {
    24        match matches.subcommand() {
    25            Some(("add", args)) => Ok(Self::Add(AddArgs::from_arg_matches(args)?)),
    26            Some(("remove", args)) => Ok(Self::Remove(RemoveArgs::from_arg_matches(args)?)),
    27            Some((_, _)) => Err(Error::raw(
    28                ErrorKind::InvalidSubcommand,
    29                "Valid subcommands are `add` and `remove`",
    30            )),
    31            None => Err(Error::raw(
    32                ErrorKind::MissingSubcommand,
    33                "Valid subcommands are `add` and `remove`",
    34            )),
    35        }
    36    }
    37    fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> {
    38        match matches.subcommand() {
    39            Some(("add", args)) => *self = Self::Add(AddArgs::from_arg_matches(args)?),
    40            Some(("remove", args)) => *self = Self::Remove(RemoveArgs::from_arg_matches(args)?),
    41            Some((_, _)) => {
    42                return Err(Error::raw(
    43                    ErrorKind::InvalidSubcommand,
    44                    "Valid subcommands are `add` and `remove`",
    45                ));
    46            }
    47            None => (),
    48        };
    49        Ok(())
    50    }
    51}
    52
    53impl Subcommand for CliSub {
    54    fn augment_subcommands(cmd: Command) -> Command {
    55        cmd.subcommand(AddArgs::augment_args(Command::new("add")))
    56            .subcommand(RemoveArgs::augment_args(Command::new("remove")))
    57            .subcommand_required(true)
    58    }
    59    fn augment_subcommands_for_update(cmd: Command) -> Command {
    60        cmd.subcommand(AddArgs::augment_args(Command::new("add")))
    61            .subcommand(RemoveArgs::augment_args(Command::new("remove")))
    62            .subcommand_required(true)
    63    }
    64    fn has_subcommand(name: &str) -> bool {
    65        matches!(name, "add" | "remove")
    66    }
    67}
    68
    69#[derive(Parser, Debug)]
    70struct Cli {
    71    #[arg(short, long)]
    72    top_level: bool,
    73    #[command(subcommand)]
    74    subcommand: CliSub,
    75}
    76
    77fn main() {
    78    let args = Cli::parse();
    79    println!("{args:#?}");
    80}