mithril_doc/
extract_clap_info.rs1use clap::{builder::StyledStr, Arg, Command};
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 StructDoc {
39 data: cmd
40 .get_arguments()
41 .map(extract_arg)
42 .collect::<Vec<FieldDoc>>(),
43 }
44}
45
46#[cfg(test)]
47mod tests {
48
49 use super::*;
50 use clap::{CommandFactory, Parser};
51
52 #[derive(Parser, Debug, Clone)]
53 #[command(version)]
54 pub struct MyCommand {
55 #[clap(short, long, default_value = "dev")]
57 run_mode: String,
58
59 #[clap()]
60 param_without_default: String,
61 }
62
63 #[test]
64 fn test_extract_arg_info() {
65 let command = MyCommand::command();
66 let arg = command.get_arguments().next().unwrap();
67 let parameter: FieldDoc = extract_arg(arg);
68
69 assert_eq!("run_mode", parameter.parameter);
70 assert_eq!("-r".to_string(), parameter.command_line_short);
71 assert_eq!("--run-mode".to_string(), parameter.command_line_long);
72 assert_eq!(Some("dev".to_string()), parameter.default_value);
73 assert_eq!("Run Mode".to_string(), parameter.description);
74 assert!(parameter.example.is_none());
75 assert!(!parameter.is_mandatory);
76 }
77
78 #[test]
79 fn test_extract_required_arg() {
80 let command = MyCommand::command();
81 let arg = command
82 .get_arguments()
83 .find(|arg| arg.get_id() == "param_without_default")
84 .unwrap();
85 let parameter: FieldDoc = extract_arg(arg);
86
87 assert!(parameter.is_mandatory);
88 }
89
90 #[test]
91 fn test_extract_command_info() {
92 let command = MyCommand::command();
93 let command_parameters: StructDoc = extract_parameters(&command);
94
95 assert_eq!(
97 "run_mode",
98 command_parameters.data.first().unwrap().parameter
99 );
100 for arg in command.get_arguments() {
101 println!("{} {}", arg.get_id(), arg.is_required_set());
102 }
103 }
104}