mod catalog;
mod markdown;
pub use catalog::{generate_catalog, generate_category_index, generate_tags_index, CatalogEntry};
pub use markdown::{generate_component_doc, generate_variant_doc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DocOptions {
#[serde(default)]
pub include_source: bool,
#[serde(default = "default_true")]
pub include_templates: bool,
#[serde(default = "default_true")]
pub include_metadata: bool,
#[serde(default = "default_true")]
pub include_toc: bool,
#[serde(default = "default_toc_threshold")]
pub toc_threshold: usize,
#[serde(default)]
pub base_path: String,
#[serde(default)]
pub title: Option<String>,
#[serde(default)]
pub include_timestamp: bool,
}
fn default_true() -> bool {
true
}
fn default_toc_threshold() -> usize {
5
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DocOutput {
pub markdown: String,
pub filename: String,
pub title: String,
pub category: Option<String>,
pub variant_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CatalogOutput {
pub markdown: String,
pub filename: String,
pub component_count: usize,
pub categories: Vec<String>,
pub tags: Vec<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{parse_art, ArtParseOptions};
use vize_carton::Bump;
#[test]
fn test_generate_component_doc() {
let allocator = Bump::new();
let source = r#"
<art title="Button" description="A versatile button" category="atoms" tags="ui,input">
<variant name="Primary" default>
<Button variant="primary">Click</Button>
</variant>
<variant name="Secondary">
<Button variant="secondary">Click</Button>
</variant>
</art>
"#;
let art = parse_art(&allocator, source, ArtParseOptions::default()).unwrap();
let output = generate_component_doc(&art, &DocOptions::default());
assert!(output.markdown.contains("# Button"));
assert!(output.markdown.contains("A versatile button"));
assert!(output.markdown.contains("Primary"));
assert!(output.markdown.contains("Secondary"));
assert_eq!(output.variant_count, 2);
}
#[test]
fn test_generate_catalog() {
let allocator = Bump::new();
let sources = [
r#"<art title="Button" category="atoms"><variant name="Default"><div></div></variant></art>"#,
r#"<art title="Card" category="molecules"><variant name="Default"><div></div></variant></art>"#,
];
let entries: Vec<_> = sources
.iter()
.map(|s| {
let art = parse_art(&allocator, s, ArtParseOptions::default()).unwrap();
CatalogEntry::from_descriptor(&art, "")
})
.collect();
let output = generate_catalog(&entries, &DocOptions::default());
assert!(output.markdown.contains("# Component Catalog"));
assert!(output.markdown.contains("Button"));
assert!(output.markdown.contains("Card"));
assert_eq!(output.component_count, 2);
}
}