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