1use crate::prefixes::{Prefix, Prefixes};
6use crate::{Element, Error};
7use rxml::RawEvent;
8use std::collections::BTreeMap;
9
10pub struct TreeBuilder {
12 next_tag: Option<(Prefix, String, Prefixes, BTreeMap<String, String>)>,
13 stack: Vec<Element>,
15 prefixes_stack: Vec<Prefixes>,
17 pub root: Option<Element>,
19}
20
21impl Default for TreeBuilder {
22 fn default() -> Self {
23 Self::new()
24 }
25}
26
27impl TreeBuilder {
28 pub fn new() -> Self {
30 TreeBuilder {
31 next_tag: None,
32 stack: vec![],
33 prefixes_stack: vec![],
34 root: None,
35 }
36 }
37
38 pub fn with_prefixes_stack(mut self, prefixes_stack: Vec<Prefixes>) -> Self {
43 self.prefixes_stack = prefixes_stack;
44 self
45 }
46
47 pub fn depth(&self) -> usize {
49 self.stack.len()
50 }
51
52 pub fn top(&mut self) -> Option<&Element> {
54 self.stack.last()
55 }
56
57 fn pop(&mut self) -> Option<Element> {
59 self.prefixes_stack.pop();
60 self.stack.pop()
61 }
62
63 pub fn unshift_child(&mut self) -> Option<Element> {
65 let depth = self.stack.len();
66 if depth > 0 {
67 self.stack[depth - 1].unshift_child()
68 } else {
69 None
70 }
71 }
72
73 fn lookup_prefix(&self, prefix: &Option<String>) -> Option<&str> {
75 for nss in self.prefixes_stack.iter().rev() {
76 if let Some(ns) = nss.get(prefix) {
77 return Some(ns);
78 }
79 }
80
81 None
82 }
83
84 fn process_end_tag(&mut self) -> Result<(), Error> {
85 if let Some(el) = self.pop() {
86 if self.depth() > 0 {
87 let top = self.stack.len() - 1;
88 self.stack[top].append_child(el);
89 } else {
90 self.root = Some(el);
91 }
92 }
93
94 Ok(())
95 }
96
97 fn process_text(&mut self, text: String) {
98 if self.depth() > 0 {
99 let top = self.stack.len() - 1;
100 self.stack[top].append_text(text);
101 }
102 }
103
104 pub fn process_event(&mut self, event: RawEvent) -> Result<(), Error> {
106 match event {
107 RawEvent::XmlDeclaration(_, _) => {}
108
109 RawEvent::ElementHeadOpen(_, (prefix, name)) => {
110 self.next_tag = Some((
111 prefix.map(|prefix| prefix.as_str().to_owned()),
112 name.as_str().to_owned(),
113 Prefixes::default(),
114 BTreeMap::new(),
115 ))
116 }
117
118 RawEvent::Attribute(_, (prefix, name), value) => {
119 if let Some((_, _, ref mut prefixes, ref mut attrs)) = self.next_tag.as_mut() {
120 match (prefix, name) {
121 (None, xmlns) if xmlns == "xmlns" => prefixes.insert(None, value),
122 (Some(xmlns), prefix) if xmlns.as_str() == "xmlns" => {
123 prefixes.insert(Some(prefix.as_str().to_owned()), value);
124 }
125 (Some(prefix), name) => {
126 attrs.insert(format!("{}:{}", prefix, name), value.as_str().to_owned());
127 }
128 (None, name) => {
129 attrs.insert(name.as_str().to_owned(), value.as_str().to_owned());
130 }
131 }
132 }
133 }
134
135 RawEvent::ElementHeadClose(_) => {
136 if let Some((prefix, name, prefixes, attrs)) = self.next_tag.take() {
137 self.prefixes_stack.push(prefixes.clone());
138
139 let namespace = self
140 .lookup_prefix(&prefix.clone().map(|prefix| prefix.as_str().to_owned()))
141 .ok_or(Error::MissingNamespace)?
142 .to_owned();
143 let el =
144 Element::new(name.as_str().to_owned(), namespace, prefixes, attrs, vec![]);
145 self.stack.push(el);
146 }
147 }
148
149 RawEvent::ElementFoot(_) => self.process_end_tag()?,
150
151 RawEvent::Text(_, text) => self.process_text(text.as_str().to_owned()),
152 }
153
154 Ok(())
155 }
156}