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