interop_hand_subcommand/
hand_subcommand.rs1#![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}