use markdown_ppp::ast::convert::{StripData, WithData};
use markdown_ppp::ast::generic;
use markdown_ppp::ast::map_data_visitor::map_user_data;
use markdown_ppp::ast::*;
fn main() {
println!("=== Generic AST Example ===\n");
let doc = Document {
blocks: vec![
Block::Heading(Heading {
kind: HeadingKind::Atx(1),
content: vec![
Inline::Text("Welcome to".to_string()),
Inline::Strong(vec![Inline::Text("Generic AST".to_string())]),
],
}),
Block::Paragraph(vec![
Inline::Text("This example shows basic ".to_string()),
Inline::Emphasis(vec![Inline::Text("generic".to_string())]),
Inline::Text(" functionality.".to_string()),
]),
],
};
println!("Original document has {} blocks", doc.blocks.len());
println!("\n1. Adding Unit Type Data:");
let doc_with_unit: generic::Document<()> = doc.clone().with_default_data();
println!(
"Document with unit data: {} blocks",
doc_with_unit.blocks.len()
);
println!("\n2. Adding String Metadata:");
let doc_with_strings: generic::Document<String> =
doc.clone().with_data("main_document".to_string());
println!("Document metadata: '{}'", doc_with_strings.user_data);
println!("\n3. Transform String to Numbers:");
let doc_with_numbers = map_user_data(doc_with_strings, |s| s.len() as u32);
println!("Document metadata length: {}", doc_with_numbers.user_data);
println!("\n4. Custom Metadata:");
let doc_with_custom = create_document_with_custom_metadata();
println!("Custom metadata: {:?}", doc_with_custom.user_data);
println!("\n5. Converting Back to Regular AST:");
let back_to_regular = doc_with_numbers.strip_data();
println!("Converted back, blocks: {}", back_to_regular.blocks.len());
println!("\n6. Chain Transformations:");
let result = doc
.with_data(42u32) .map_data(|n| format!("value_{n}")) .map_data(|s| s.chars().count()) .map_data(|n| n as f64 * std::f64::consts::PI);
println!("Final transformed value: {}", result.user_data);
println!("\n✓ Generic AST functionality works without specialized types!");
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
struct CustomMeta {
name: String,
priority: u8,
created_at: u64,
}
fn create_document_with_custom_metadata() -> generic::Document<CustomMeta> {
generic::Document {
blocks: vec![generic::Block::Paragraph {
content: vec![generic::Inline::Text {
content: "Example with custom metadata".to_string(),
user_data: CustomMeta {
name: "text_element".to_string(),
priority: 5,
created_at: 1234567891,
},
}],
user_data: CustomMeta {
name: "paragraph_element".to_string(),
priority: 7,
created_at: 1234567892,
},
}],
user_data: CustomMeta {
name: "main_document".to_string(),
priority: 10,
created_at: 1234567890,
},
}
}
trait MapDataChain<T>: Sized {
fn map_data<U, F>(self, f: F) -> generic::Document<U>
where
F: FnMut(T) -> U;
}
impl<T> MapDataChain<T> for generic::Document<T> {
fn map_data<U, F>(self, f: F) -> generic::Document<U>
where
F: FnMut(T) -> U,
{
map_user_data(self, f)
}
}