use helixforge_core::{Item, Tab};
pub fn walkthrough(tabs: &[Tab]) -> String {
let mut text = String::from(
"<!-- Generated by helixforge docgen; do not edit by hand. -->\n# Walkthrough\n",
);
for tab in tabs {
text.push_str(&format!("\n## {}\n\n", tab.name));
items(&tab.items, 3, &mut text);
}
text
}
fn items(list: &[Item], level: usize, text: &mut String) {
for item in list {
if let Item::Entry(entry) = item
&& !entry.description.is_empty()
{
text.push_str(&format!("- **{}**: {}\n", entry.name, entry.description));
}
}
for item in list {
if let Item::Group(group) = item {
text.push_str(&format!(
"\n{} {}\n\n",
"#".repeat(level.min(6)),
group.name
));
if !group.description.is_empty() {
text.push_str(&format!("{}\n\n", group.description));
}
items(&group.items, level + 1, text);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use helixforge_core::{Action, Entry, Group};
#[test]
fn groups_become_headings_and_described_entries_bullets() {
let entry = |name: &str, description: &str| {
Item::Entry(Entry {
id: name.to_lowercase(),
name: name.into(),
description: description.into(),
flags: String::new(),
multi_select: true,
writes: Vec::new(),
action: Action::Command {
line: "true".into(),
},
detect: None,
needs: Default::default(),
effects: Default::default(),
})
};
let tab = Tab {
id: "apps".into(),
name: "Apps".into(),
items: vec![
Item::Group(Group {
id: "browsers".into(),
name: "Browsers".into(),
description: String::new(),
multi_select: true,
items: vec![
entry("Brave", "A browser."),
Item::Group(Group {
id: "nightly".into(),
name: "Nightly".into(),
description: String::new(),
multi_select: true,
items: vec![entry("Firefox", "Another.")],
}),
],
}),
entry("Quiet", ""),
entry("Loose", "Outside any group."),
],
};
let text = walkthrough(&[tab]);
assert!(text.contains("## Apps\n"));
assert!(text.contains("### Browsers\n"));
assert!(text.contains("- **Brave**: A browser.\n"));
assert!(!text.contains("Quiet"));
assert!(text.contains("#### Nightly\n\n- **Firefox**: Another.\n"));
let loose = text.find("- **Loose**").unwrap();
assert!(loose < text.find("### Browsers").unwrap(), "{text}");
}
}