mod parse;
mod render;
pub use parse::parse_md;
pub use render::render_md;
pub(crate) struct SectionShape {
pub list_field: Option<&'static str>,
pub key_field: &'static str,
}
pub(crate) fn section_shape(section: &str) -> Option<SectionShape> {
let (list_field, key_field) = match section {
"information" => (None, "key"),
"pre_execution" => (None, "step"),
"goals" => (None, "name"),
"validations" => (None, "name"),
"success" => (None, "name"),
"schedules" => (None, "type"),
"execution_guidelines" => (Some("items"), "name"),
"default_skills" => (None, "name"),
"graph" => (Some("nodes"), "id"),
"providers" => (Some("providers"), "id"),
_ => return None,
};
Some(SectionShape {
list_field,
key_field,
})
}
pub(crate) fn heading_to_key(heading: &str) -> String {
let h = heading.trim();
let h = match h.find(['.', ')', '-']) {
Some(i) if i <= 2 && h[..i].chars().all(|c| c.is_ascii_alphanumeric()) => &h[i + 1..],
_ => h,
};
h.trim()
.to_lowercase()
.split_whitespace()
.collect::<Vec<_>>()
.join("_")
.replace('-', "_")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn headings_normalise_to_config_keys() {
for (heading, key) in [
("A. Information", "information"),
("B. Pre-execution", "pre_execution"),
("F. Stop gates", "stop_gates"),
("I. Execution guidelines", "execution_guidelines"),
("J. Default skills", "default_skills"),
("Providers", "providers"),
("stop_gates", "stop_gates"),
(" Graph ", "graph"),
] {
assert_eq!(heading_to_key(heading), key, "for heading `{heading}`");
}
}
#[test]
fn a_hyphenated_word_is_not_mistaken_for_a_section_letter() {
assert_eq!(heading_to_key("Pre-execution"), "pre_execution");
}
}