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