use super::document::{JobArgType, JobArgumentDeclaration, JobHelpInfo};
pub(crate) fn render_job_help(stem: &str, description: Option<&str>, info: &JobHelpInfo) -> String {
let mut out = String::new();
out.push_str(stem);
out.push_str("\n\n");
match description {
Some(description) => out.push_str(&flatten_line_breaks(description)),
None => out.push_str("(no description)"),
}
out.push_str("\n\n");
out.push_str("Mode: ");
out.push_str(&info.mode);
out.push('\n');
out.push_str("Sends to: ");
out.push_str(&info.send_to);
out.push_str("\n\n");
out.push_str("Arguments:");
match &info.args {
Some(declarations) if !declarations.entries.is_empty() => {
let name_width = declarations
.entries
.keys()
.map(String::len)
.max()
.unwrap_or_default();
let type_width = declarations
.entries
.values()
.map(|declaration| JobArgType::render(&declaration.arg_type).len())
.max()
.unwrap_or_default();
for (name, declaration) in &declarations.entries {
out.push('\n');
out.push_str(&render_argument_row(
name,
name_width,
type_width,
declaration,
));
}
}
_ => out.push_str("\n (no arguments)"),
}
out
}
fn render_argument_row(
name: &str,
name_width: usize,
type_width: usize,
declaration: &JobArgumentDeclaration,
) -> String {
let mut row = String::new();
row.push_str(" ");
row.push_str(name);
row.push_str(&" ".repeat(name_width - name.len()));
row.push_str(" ");
let rendered_type = declaration.arg_type.render();
row.push_str(&rendered_type);
row.push_str(&" ".repeat(type_width - rendered_type.len()));
row.push_str(" ");
row.push_str(if declaration.required {
"required"
} else {
"optional"
});
if let Some(default) = &declaration.default {
row.push_str(" default=");
row.push_str(&flatten_line_breaks(default));
}
if let Some(description) = &declaration.description {
row.push_str(" ");
row.push_str(&flatten_line_breaks(description));
}
row
}
fn flatten_line_breaks(text: &str) -> String {
let mut flat = String::with_capacity(text.len());
let mut in_break = false;
for ch in text.chars() {
if ch == '\r' || ch == '\n' {
if !in_break {
flat.push(' ');
in_break = true;
}
} else {
flat.push(ch);
in_break = false;
}
}
flat
}