mithril_doc/
extract_clap_info.rs1use clap::{Arg, Command, builder::StyledStr};
2
3use super::{FieldDoc, StructDoc};
4
5fn extract_arg(arg: &Arg) -> FieldDoc {
7 let parameter = arg.get_id().to_string();
8 let short_option = arg.get_short().map_or("".into(), |c| format!("-{c}"));
9 let long_option = arg.get_long().map_or("".into(), |c| format!("--{c}"));
10 let env_variable = arg.get_env().map(|s| format!("{}", s.to_string_lossy()));
11 let description = arg.get_help().map_or("-".into(), StyledStr::to_string);
12 let default_value = if arg.get_default_values().iter().count() == 0 {
13 None
14 } else {
15 Some(
16 arg.get_default_values()
17 .iter()
18 .map(|s| format!("{}", s.to_string_lossy()))
19 .collect::<Vec<String>>()
20 .join(","),
21 )
22 };
23 let example = None;
24
25 FieldDoc {
26 parameter,
27 command_line_long: long_option,
28 command_line_short: short_option,
29 environment_variable: env_variable,
30 description,
31 default_value,
32 example,
33 is_mandatory: arg.is_required_set(),
34 }
35}
36
37pub fn extract_parameters(cmd: &Command) -> StructDoc {
38 let fields = cmd.get_arguments().map(extract_arg).collect();
39 StructDoc::new(fields)
40}
41
42#[cfg(test)]
43mod tests {
44
45 use super::*;
46 use clap::{CommandFactory, Parser};
47
48 #[derive(Parser, Debug, Clone)]
49 #[command(version)]
50 pub struct MyCommand {
51 #[clap(short, long, default_value = "dev")]
53 run_mode: String,
54
55 #[clap()]
56 param_without_default: String,
57 }
58
59 #[test]
60 fn test_extract_arg_info() {
61 let command = MyCommand::command();
62 let arg = command.get_arguments().next().unwrap();
63 let parameter: FieldDoc = extract_arg(arg);
64
65 assert_eq!("run_mode", parameter.parameter);
66 assert_eq!("-r".to_string(), parameter.command_line_short);
67 assert_eq!("--run-mode".to_string(), parameter.command_line_long);
68 assert_eq!(Some("dev".to_string()), parameter.default_value);
69 assert_eq!("Run Mode".to_string(), parameter.description);
70 assert!(parameter.example.is_none());
71 assert!(!parameter.is_mandatory);
72 }
73
74 #[test]
75 fn test_extract_required_arg() {
76 let command = MyCommand::command();
77 let arg = command
78 .get_arguments()
79 .find(|arg| arg.get_id() == "param_without_default")
80 .unwrap();
81 let parameter: FieldDoc = extract_arg(arg);
82
83 assert!(parameter.is_mandatory);
84 }
85
86 #[test]
87 fn test_extract_command_info() {
88 let command = MyCommand::command();
89 let command_parameters: StructDoc = extract_parameters(&command);
90
91 assert_eq!(
93 "run_mode",
94 command_parameters.get_ordered_data().first().unwrap().parameter
95 );
96 for arg in command.get_arguments() {
97 println!("{} {}", arg.get_id(), arg.is_required_set());
98 }
99 }
100}