1use crate::{Cli, CliCommand};
2
3impl Cli {
4 pub fn show_help(&self, command_name: String) {
5 let cmd_def = self.commands.iter().find(|cmd| cmd.name == command_name);
7
8 let mut cmds_info = Vec::new();
9 let mut args_info = Vec::new();
10 let mut opts_info = Vec::new();
11
12 match cmd_def {
13 Some(cmd_def) => {
14 args_info = cmd_def.args_info();
15 opts_info = cmd_def.opts_info();
16 }
17 None => {}
18 }
19
20 if command_name == "cli" {
21 cmds_info = self
22 .commands
23 .iter()
24 .map(|cmd| cmd.info())
25 .collect::<Vec<(String, String)>>();
26 cmds_info.push((
27 String::from("help [command]"),
28 String::from("Show help for a command"),
29 ));
30 }
31
32 let args_max_width = args_info
33 .iter()
34 .map(|(name, _)| name.len())
35 .max()
36 .unwrap_or(0);
37 let opts_max_width = opts_info
38 .iter()
39 .map(|(name, _)| name.len())
40 .max()
41 .unwrap_or(0);
42 let cmds_max_width = cmds_info
43 .iter()
44 .map(|(name, _)| name.len())
45 .max()
46 .unwrap_or(0);
47 let max_width = args_max_width.max(opts_max_width).max(cmds_max_width) + 2;
48
49 match cmd_def {
51 Some(cmd_def) => {
52 println!();
53 let mut usage_string = String::new();
54
55 usage_string.push_str(&self.executable_name);
56
57 if command_name != "cli" {
58 usage_string.push_str(" ");
59 usage_string.push_str(&command_name);
60 }
61
62 if !args_info.is_empty() {
63 let args_string = " ".to_owned()
64 + &args_info
65 .iter()
66 .map(|(name, _)| name.as_str())
67 .collect::<Vec<&str>>()
68 .join(" ");
69 usage_string.push_str(&args_string);
70 }
71
72 if !opts_info.is_empty() {
73 usage_string.push_str(" [options]");
74 }
75
76 println!("Usage: {}", usage_string);
77 }
78 None => {}
79 }
80 match cmd_def {
82 Some(cmd_def) => {
83 let description = &cmd_def.description;
84
85 if let Some(description) = description {
86 println!("{}", description)
87 } else {
88 println!("No description available")
89 }
90 }
91 None => {}
92 }
93 if !args_info.is_empty() {
95 println!("\nArguments:");
96 for (name, description) in args_info {
97 let width = name.len();
98 let padding = " ".repeat(max_width - width);
99 println!(" {}{}{}", name, padding, description);
100 }
101 }
102 if !opts_info.is_empty() {
104 println!("\nOptions:");
105 for (name, description) in opts_info {
106 let width = name.len();
107 let padding = " ".repeat(max_width - width);
108 println!(" {}{}{}", name, padding, description);
109 }
110 }
111 if !cmds_info.is_empty() {
113 println!("\nCommands:");
114 for (name, description) in cmds_info {
115 let width = name.len();
116 let padding = " ".repeat(max_width - width);
117 println!(" {}{}{}", name, padding, description);
118 }
119 }
120 println!();
121 }
122}