1use crate::config::Config;
2use clap::{Parser, Subcommand};
3use std::path::PathBuf;
4
5#[derive(Debug, Default, Parser)]
7#[command(
8version,
9author,
10about,
11subcommand_negates_reqs = true,
12disable_help_subcommand = true,
13override_usage = format!("
14 {bin} [OPTIONS] <CMD>
15 {bin} [OPTIONS] <COMMAND> <CMD>", bin = env!("CARGO_PKG_NAME"))
16)]
17pub struct CliArgs {
18 #[arg(required = true)]
20 pub cmd: Option<String>,
21 #[arg(long = "check", value_name = "ARG", value_parser = CliArgs::parse_arg)]
23 pub check_args: Option<Vec<String>>,
24 #[arg(long)]
26 pub no_version: bool,
27 #[arg(long)]
29 pub no_help: bool,
30 #[arg(short, long, env = "HALP_CONFIG", value_name = "PATH")]
32 pub config: Option<PathBuf>,
33 #[arg(short, long, value_name = "S")]
35 pub timeout: Option<u64>,
36 #[arg(short, long)]
38 pub verbose: bool,
39 #[command(subcommand)]
41 pub subcommand: Option<CliCommands>,
42}
43
44#[derive(Debug, Subcommand)]
46pub enum CliCommands {
47 Plz {
49 cmd: String,
51 #[arg(short, long)]
53 man_cmd: Option<String>,
54 #[arg(long, env = "CHEAT_SH_URL", value_name = "URL")]
56 cheat_sh_url: Option<String>,
57 #[arg(long, env = "EG_PAGES_URL", value_name = "URL")]
59 eg_url: Option<String>,
60 #[arg(long, env = "CHEATSHEETS_URL", value_name = "URL")]
62 cheat_url: Option<String>,
63 #[arg(short, long)]
65 pager: Option<String>,
66 #[arg(long)]
68 no_pager: bool,
69 },
70}
71
72impl CliArgs {
73 fn parse_arg(arg: &str) -> Result<String, String> {
75 Ok(arg.replace("\\-", "-"))
76 }
77
78 pub fn update_config(&self, config: &mut Config) {
80 config.check_help = !self.no_help;
81 config.check_version = !self.no_version;
82 if let Some(ref args) = self.check_args {
83 config.check_args = Some(args.iter().map(|s| vec![s.to_string()]).collect());
84 }
85 if self.timeout.is_some() {
86 config.timeout = self.timeout;
87 }
88 if let Some(CliCommands::Plz {
89 ref man_cmd,
90 ref cheat_sh_url,
91 ref eg_url,
92 no_pager,
93 ref pager,
94 ..
95 }) = self.subcommand
96 {
97 if let Some(man_cmd) = man_cmd {
98 config.man_command.clone_from(man_cmd);
99 }
100 if let Some(cheat_sh_url) = cheat_sh_url {
101 config.cheat_sh_url = Some(cheat_sh_url.clone());
102 }
103 if let Some(eg_url) = eg_url {
104 config.eg_url = Some(eg_url.to_owned());
105 }
106 if no_pager {
107 config.pager_command = None;
108 } else if let Some(pager) = pager {
109 config.pager_command = Some(pager.clone());
110 }
111 }
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use clap::CommandFactory;
119 use pretty_assertions::assert_eq;
120
121 #[test]
122 fn test_cli_args() {
123 CliArgs::command().debug_assert();
124 assert_eq!(Ok("--help"), CliArgs::parse_arg("\\--help").as_deref());
125 }
126
127 #[test]
128 fn test_update_config() {
129 let mut config = Config::default();
130 let args = CliArgs {
131 subcommand: Some(CliCommands::Plz {
132 cmd: "ps".to_string(),
133 pager: Some("bat".to_string()),
134 cheat_sh_url: None,
135 cheat_url: None,
136 eg_url: None,
137 man_cmd: None,
138 no_pager: false,
139 }),
140 ..Default::default()
141 };
142 args.update_config(&mut config);
143 assert!(config.check_help);
144 assert_eq!(Some(String::from("bat")), config.pager_command);
145 }
146}