configure_me_codegen/
gen_man.rs1use ::config::Config;
2use super::manifest::{self, Manifest};
3use ::man::prelude::*;
4
5fn generate_meta(config: &Config, manifest: &Manifest) -> Result<Manual, manifest::Error> {
6 let package = manifest.package.as_ref().ok_or(manifest::Error::MissingPackage)?;
7 let man = if let Some(name) = &config.general.name {
8 Manual::new(name)
9 } else {
10 Manual::new(&package.name)
11 };
12
13 let man = if let Some(summary) = &config.general.summary {
14 man.about(&**summary)
15 } else if let Some(summary) = &package.description() {
16 man.about(&**summary)
17 } else {
18 man
19 };
20
21 let authors = &package.authors();
22 Ok(authors.iter().fold(man, |man, author| {
23 let mut name_email = author.split('<');
24 if let Some(name) = name_email.next() {
25 let author = Author::new(name.trim());
26
27 let author = if let Some(email) = name_email.next() {
28 let email = email.trim().trim_matches('>');
29 author.email(email)
30 } else {
31 author
32 };
33
34 man.author(author)
35 } else {
36 man
37 }
38 }))
39}
40
41fn generate_conf_file_param(man: Manual, config: &Config) -> Manual {
42 if let Some(conf_file_param) = &config.general.conf_file_param {
43 let opt = Opt::new("CONFIG_FILE").long(&::codegen::param_long_raw(conf_file_param.as_snake_case()));
44 let opt = opt.help("Loads configuration from the specified CONFIG_FILE.");
45 man.option(opt)
46 } else {
47 man
48 }
49}
50
51fn generate_conf_dir_param(man: Manual, config: &Config) -> Manual {
52 if let Some(conf_dir_param) = &config.general.conf_dir_param {
53 let opt = Opt::new("CONFIG_DIR").long(&::codegen::param_long_raw(conf_dir_param.as_snake_case()));
54 let opt = opt.help("Loads configuration from all files in the directory CONFIG_DIR.");
55 man.option(opt)
56 } else {
57 man
58 }
59}
60
61fn generate_skip_default_conf_files_switch(man: Manual, config: &Config) -> Manual {
62 if let Some(switch) = &config.general.skip_default_conf_files_switch {
63 let opt = Flag::new().long(&::codegen::param_long_raw(switch.as_snake_case()));
64 let opt = opt.help("Skip loading default configuration files.");
65 man.flag(opt)
66 } else {
67 man
68 }
69}
70
71fn generate_params(man: Manual, config: &Config) -> Manual {
72 config
73 .params
74 .iter()
75 .filter(|param| param.argument).map(|param| {
76 let opt = Opt::new(¶m.name.as_upper_case().to_string()).long(&::codegen::param_long(param));
77 let opt = if let Some(short) = ::codegen::param_short(param) {
78 opt.short(&short)
79 } else {
80 opt
81 };
82 let opt = if let Some(doc) = ¶m.doc {
83 opt.help(&doc)
84 } else {
85 opt
86 };
87 let opt = if let ::config::Optionality::DefaultValue(default) = ¶m.optionality {
88 opt.default_value(&default)
89 } else {
90 opt
91 };
92 opt
93 })
94 .fold(man, |man, opt| man.option(opt))
95}
96
97fn generate_switches(man: Manual, config: &Config) -> Manual {
98 config
99 .switches
100 .iter()
101 .map(|switch| {
102 let flag = Flag::new()
103 .long(&::codegen::switch_long(switch));
104 let flag = if let Some(short) = ::codegen::switch_short(switch) {
105 flag.short(&short)
106 } else {
107 flag
108 };
109 let flag = if let Some(doc) = &switch.doc {
110 flag.help(&doc)
111 } else {
112 flag
113 };
114 flag
115 })
116 .fold(man, |man, flag| man.flag(flag))
117}
118
119fn generate_param_env_vars(man: Manual, config: &Config) -> Manual {
120 let prefix = config.general.env_prefix.as_ref().map_or_else(String::new, |prefix| [&prefix, "_"].join(""));
121 config
122 .params
123 .iter()
124 .filter(|param| param.env_var).map(|param| {
125 let env = Env::new(&[&prefix as &str, ¶m.name.as_upper_case().to_string()].join(""));
126 let env = if let Some(doc) = ¶m.doc {
127 env.help(&doc)
128 } else {
129 env
130 };
131 let env = if let ::config::Optionality::DefaultValue(default) = ¶m.optionality {
132 env.default_value(&default)
133 } else {
134 env
135 };
136 env
137 })
138 .fold(man, |man, env| man.env(env))
139}
140
141fn generate_switch_env_vars(man: Manual, config: &Config) -> Manual {
142 let prefix = config.general.env_prefix.as_ref().map_or_else(String::new, |prefix| [&prefix, "_"].join(""));
143 config
144 .switches
145 .iter()
146 .filter(|switch| switch.env_var).map(|switch| {
147 let env = Env::new(&[&prefix as &str, &switch.name.as_upper_case().to_string()].join(""));
148 let env = if let Some(doc) = &switch.doc {
149 env.help(&doc)
150 } else {
151 env
152 };
153 let env = if switch.is_inverted() {
154 env.default_value("true")
155 } else {
156 env.default_value("false")
157 };
158 env
159 })
160 .fold(man, |man, env| man.env(env))
161}
162
163pub fn generate_man_page(config: &Config, manifest: &Manifest) -> Result<String, manifest::Error> {
164 let man = generate_meta(config, manifest)?;
165 let man = if let Some(doc) = &config.general.doc {
166 man.description(doc.to_owned())
167 } else {
168 man
169 };
170 let man = generate_conf_file_param(man, config);
171 let man = generate_conf_dir_param(man, config);
172 let man = generate_skip_default_conf_files_switch(man, config);
173 let man = generate_params(man, config);
174 let man = generate_switches(man, config);
175 let man = generate_param_env_vars(man, config);
176 let man = generate_switch_env_vars(man, config);
177
178 Ok(man.render())
179}