1use indexmap::IndexMap;
4use ddex_core::models::{Comment, CommentPosition};
5#[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#[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#[derive(Debug, Clone)]
26pub enum Node {
27 Element(Element),
28 Text(String),
29 Comment(Comment),
30 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 pub fn add_comment(&mut self, comment: Comment) {
69 self.children.push(Node::Comment(comment));
70 }
71
72 pub fn add_simple_comment(&mut self, comment: impl Into<String>) {
74 self.children.push(Node::SimpleComment(comment.into()));
75 }
76
77 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}