1 use clap::{Arg, ArgAction, Command};
2 
main()3 fn main() {
4     let matches = Command::new("pacman")
5         .about("package manager utility")
6         .version("5.2.1")
7         .subcommand_required(true)
8         .arg_required_else_help(true)
9         // Query subcommand
10         //
11         // Only a few of its arguments are implemented below.
12         .subcommand(
13             Command::new("query")
14                 .short_flag('Q')
15                 .long_flag("query")
16                 .about("Query the package database.")
17                 .arg(
18                     Arg::new("search")
19                         .short('s')
20                         .long("search")
21                         .help("search locally installed packages for matching strings")
22                         .conflicts_with("info")
23                         .action(ArgAction::Set)
24                         .num_args(1..),
25                 )
26                 .arg(
27                     Arg::new("info")
28                         .long("info")
29                         .short('i')
30                         .conflicts_with("search")
31                         .help("view package information")
32                         .action(ArgAction::Set)
33                         .num_args(1..),
34                 ),
35         )
36         // Sync subcommand
37         //
38         // Only a few of its arguments are implemented below.
39         .subcommand(
40             Command::new("sync")
41                 .short_flag('S')
42                 .long_flag("sync")
43                 .about("Synchronize packages.")
44                 .arg(
45                     Arg::new("search")
46                         .short('s')
47                         .long("search")
48                         .conflicts_with("info")
49                         .action(ArgAction::Set)
50                         .num_args(1..)
51                         .help("search remote repositories for matching strings"),
52                 )
53                 .arg(
54                     Arg::new("info")
55                         .long("info")
56                         .conflicts_with("search")
57                         .short('i')
58                         .action(ArgAction::SetTrue)
59                         .help("view package information"),
60                 )
61                 .arg(
62                     Arg::new("package")
63                         .help("packages")
64                         .required_unless_present("search")
65                         .action(ArgAction::Set)
66                         .num_args(1..),
67                 ),
68         )
69         .get_matches();
70 
71     match matches.subcommand() {
72         Some(("sync", sync_matches)) => {
73             if sync_matches.contains_id("search") {
74                 let packages: Vec<_> = sync_matches
75                     .get_many::<String>("search")
76                     .expect("contains_id")
77                     .map(|s| s.as_str())
78                     .collect();
79                 let values = packages.join(", ");
80                 println!("Searching for {values}...");
81                 return;
82             }
83 
84             let packages: Vec<_> = sync_matches
85                 .get_many::<String>("package")
86                 .expect("is present")
87                 .map(|s| s.as_str())
88                 .collect();
89             let values = packages.join(", ");
90 
91             if sync_matches.get_flag("info") {
92                 println!("Retrieving info for {values}...");
93             } else {
94                 println!("Installing {values}...");
95             }
96         }
97         Some(("query", query_matches)) => {
98             if let Some(packages) = query_matches.get_many::<String>("info") {
99                 let comma_sep = packages.map(|s| s.as_str()).collect::<Vec<_>>().join(", ");
100                 println!("Retrieving info for {comma_sep}...");
101             } else if let Some(queries) = query_matches.get_many::<String>("search") {
102                 let comma_sep = queries.map(|s| s.as_str()).collect::<Vec<_>>().join(", ");
103                 println!("Searching Locally for {comma_sep}...");
104             } else {
105                 println!("Displaying all locally installed packages...");
106             }
107         }
108         _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable
109     }
110 }
111