ddex_builder/
ast.rs

1//! Abstract Syntax Tree for DDEX XML generation
2
3use indexmap::IndexMap;
4use ddex_core::models::{Comment, CommentPosition};
5// Remove unused serde imports since we're not serializing AST
6
7/// Abstract Syntax Tree root
8#[derive(Debug, Clone)]
9pub struct AST {
10    pub root: Element,
11    pub namespaces: IndexMap<String, String>,
12    pub schema_location: Option<String>,
13}
14
15/// XML Element
16#[derive(Debug, Clone)]
17pub struct Element {
18    pub name: String,
19    pub namespace: Option<String>,
20    pub attributes: IndexMap<String, String>,
21    pub children: Vec<Node>,
22}
23
24/// XML Node types
25#[derive(Debug, Clone)]
26pub enum Node {
27    Element(Element),
28    Text(String),
29    Comment(Comment),
30    /// Legacy comment support for backward compatibility
31    SimpleComment(String),
32}
33
34impl Element {
35    pub fn new(name: impl Into<String>) -> Self {
36        Self {
37            name: name.into(),
38            namespace: None,
39            attributes: IndexMap::new(),
40            children: Vec::new(),
41        }
42    }
43    
44    pub fn with_namespace(mut self, ns: impl Into<String>) -> Self {
45        self.namespace = Some(ns.into());
46        self
47    }
48    
49    pub fn with_attr(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
50        self.attributes.insert(key.into(), value.into());
51        self
52    }
53    
54    pub fn with_text(mut self, text: impl Into<String>) -> Self {
55        self.children.push(Node::Text(text.into()));
56        self
57    }
58    
59    pub fn add_child(&mut self, child: Element) {
60        self.children.push(Node::Element(child));
61    }
62    
63    pub fn add_text(&mut self, text: impl Into<String>) {
64        self.children.push(Node::Text(text.into()));
65    }
66    
67    /// Add a structured comment to this element
68    pub fn add_comment(&mut self, comment: Comment) {
69        self.children.push(Node::Comment(comment));
70    }
71    
72    /// Add a simple comment (for backward compatibility)
73    pub fn add_simple_comment(&mut self, comment: impl Into<String>) {
74        self.children.push(Node::SimpleComment(comment.into()));
75    }
76    
77    /// Add a comment with a specific position
78    pub fn with_comment(mut self, content: String, position: CommentPosition) -> Self {
79        let comment = Comment::new(content, position);
80        self.children.push(Node::Comment(comment));
81        self
82    }
83}