2024-05-08 12:18:03 +00:00
|
|
|
use indexmap::IndexMap;
|
2024-05-08 09:52:34 +00:00
|
|
|
use req::*;
|
2024-05-08 12:18:03 +00:00
|
|
|
use stringlit::s;
|
|
|
|
|
|
2024-05-08 12:43:29 +00:00
|
|
|
pub const WORD_DESCRIPTION: &str = //
|
|
|
|
|
r#"The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED",
|
|
|
|
|
"MAY", and "OPTIONAL" in this document are to be interpreted as described in
|
|
|
|
|
[RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119).
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
pub const HIGHLIGHTED_WORDS: [&str; 10] = [
|
|
|
|
|
"must not",
|
|
|
|
|
"must",
|
|
|
|
|
"required",
|
|
|
|
|
"shall not",
|
|
|
|
|
"shall",
|
|
|
|
|
"should not",
|
|
|
|
|
"should",
|
|
|
|
|
"recommended",
|
|
|
|
|
"may",
|
|
|
|
|
"optional",
|
|
|
|
|
];
|
|
|
|
|
|
2024-05-08 12:18:03 +00:00
|
|
|
fn nl() -> String {
|
|
|
|
|
s!("")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn add_requirements(output: &mut Vec<String>, requirements: &IndexMap<String, Requirement>) {
|
|
|
|
|
for (id, requirement) in requirements {
|
|
|
|
|
output.push(format!(
|
2024-05-08 12:44:43 +00:00
|
|
|
"- **_{id}_ - {}:** {}",
|
2024-05-08 12:18:03 +00:00
|
|
|
requirement.name, requirement.description
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn add_topics(output: &mut Vec<String>, topics: &IndexMap<String, Topic>, level: usize) {
|
|
|
|
|
for (id, topic) in topics {
|
2024-05-08 12:44:43 +00:00
|
|
|
output.push(format!("{} _{id}_ - {}", "#".repeat(level), topic.name));
|
2024-05-08 12:18:03 +00:00
|
|
|
if !topic.requirements.is_empty() {
|
|
|
|
|
add_requirements(output, &topic.requirements);
|
|
|
|
|
output.push(nl());
|
|
|
|
|
}
|
|
|
|
|
if !topic.subtopics.is_empty() {
|
|
|
|
|
add_topics(output, &topic.subtopics, level + 1);
|
|
|
|
|
output.push(nl());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-08 09:52:34 +00:00
|
|
|
|
|
|
|
|
fn main() -> anyhow::Result<()> {
|
2024-05-08 12:18:03 +00:00
|
|
|
// std::fs::write("req.yml", serde_yaml::to_string(&project)?)?;
|
|
|
|
|
let project: Project = serde_yaml::from_str(&std::fs::read_to_string("req.yml")?)?;
|
|
|
|
|
|
|
|
|
|
let mut output = vec![
|
|
|
|
|
format!("# Requirements for {}", project.name),
|
|
|
|
|
nl(),
|
|
|
|
|
s!("[[_TOC_]]"),
|
|
|
|
|
nl(),
|
|
|
|
|
WORD_DESCRIPTION.to_string(),
|
|
|
|
|
nl(),
|
|
|
|
|
s!("## Description"),
|
|
|
|
|
project.description,
|
|
|
|
|
nl(),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
if !project.topics.is_empty() {
|
|
|
|
|
output.push(s!("## Requirements"));
|
|
|
|
|
add_topics(&mut output, &project.topics, 3);
|
|
|
|
|
output.push(nl());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !project.definitions.is_empty() {
|
|
|
|
|
output.push(s!("## Definitions"));
|
|
|
|
|
for definition in project.definitions {
|
|
|
|
|
output.push(format!("- {}: {}", definition.name, definition.value));
|
|
|
|
|
for info in definition.additional_info {
|
|
|
|
|
output.push(format!(" - {info}"))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
output.push(nl());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !project.config_defaults.is_empty() {
|
|
|
|
|
output.push(s!("## Config Defaults"));
|
|
|
|
|
for default in project.config_defaults {
|
|
|
|
|
output.push(format!("- **{}**", default.name));
|
|
|
|
|
output.push(format!(" - Type: {}", default.typ));
|
|
|
|
|
if let Some(unit) = default.unit {
|
|
|
|
|
output.push(format!(" - Unit: {unit}"));
|
|
|
|
|
}
|
|
|
|
|
if let Some(valid_values) = default.valid_values {
|
|
|
|
|
output.push(format!(" - Valid Values: _{}_", valid_values.join(", ")));
|
|
|
|
|
}
|
|
|
|
|
if let Some(default_value) = default.default_value {
|
|
|
|
|
output.push(format!(
|
|
|
|
|
" - Default Value: _{}_{}",
|
|
|
|
|
default_value,
|
|
|
|
|
default.hint.map(|h| format!(" {h}")).unwrap_or_default()
|
|
|
|
|
));
|
|
|
|
|
} else {
|
|
|
|
|
output.push(format!(
|
|
|
|
|
" - **Required**: This value **_MUST_** be provided as a start parameter.{}",
|
|
|
|
|
default.hint.map(|h| format!(" {h}")).unwrap_or_default()
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
output.push(nl());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 12:43:29 +00:00
|
|
|
let mut output = output.join("\n");
|
|
|
|
|
for word in HIGHLIGHTED_WORDS {
|
|
|
|
|
output = output.replace(word, &format!("**_{}_**", word.to_uppercase()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
println!("{output}");
|
2024-05-08 09:52:34 +00:00
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|