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}