configure_me_codegen/
gen_man.rs

1use ::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(&param.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) = &param.doc {
83                opt.help(&doc)
84            } else {
85                opt
86            };
87            let opt = if let ::config::Optionality::DefaultValue(default) = &param.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, &param.name.as_upper_case().to_string()].join(""));
126            let env = if let Some(doc) = &param.doc {
127                env.help(&doc)
128            } else {
129                env
130            };
131            let env = if let ::config::Optionality::DefaultValue(default) = &param.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}