1use super::SvgElement;
21
22#[derive(Debug)]
25pub enum XmlEvent<'a> {
26 StartDocument,
27 EndDocument,
28 StartElement(&'a SvgElement),
29 EndElement(&'a SvgElement),
30 Characters(&'a SvgElement),
31}
32
33impl<'a> XmlEvent<'a> {
35 pub fn as_xml(&self) -> String {
36 use XmlEvent::*;
37 match self {
38 StartDocument => r#"<?xml version="1.0" encoding="utf8"?>"#.into(),
39 EndDocument => "".into(),
40 StartElement(e) => {
41 let mut r = format!("<{}", e.name());
42 for (n, _op, v) in e.attributes() {
43 r.push_str(&format!(r#" {}="{}""#, n, v));
44 }
45 r.push('>');
46 r
47 }
48 Characters(e) => e.characters().into(),
49 EndElement(e) => {
50 format!("</{}>", e.name())
51 }
52 }
53 }
54}
55
56#[derive(Debug)]
59enum IterState {
60 PreDocument,
61 PreElement,
62 PreString,
63 PreContent,
64 PostContent,
65 FindNextElement,
66 DocumentEnd,
67 Completed,
68}
69
70pub struct ElementIter<'a> {
73 state: IterState,
74 elements: Vec<(&'a SvgElement, usize)>,
75}
76
77impl<'a> ElementIter<'a> {
79 pub fn new(e: &'a SvgElement) -> Self {
82 let elements = vec![(e, 0)];
83 Self {
84 state: IterState::PreDocument,
85 elements,
86 }
87 }
88}
89
90impl<'a> Iterator for ElementIter<'a> {
92 type Item = XmlEvent<'a>;
93 fn next(&mut self) -> Option<Self::Item> {
94 match self.state {
95 IterState::PreDocument => {
96 self.state = IterState::PreElement;
97 Some(XmlEvent::StartDocument)
98 }
99 IterState::PreElement => {
100 let (ele, n) = self.elements.pop().unwrap();
101 self.state = IterState::PreString;
102 self.elements.push((ele, n));
103 Some(XmlEvent::StartElement(ele))
104 }
105 IterState::PreString => {
106 let (ele, n) = self.elements.pop().unwrap();
107 self.state = IterState::PreContent;
108 if ele.characters() != "" {
109 self.elements.push((ele, n));
110 Some(XmlEvent::Characters(ele))
111 } else {
112 self.elements.push((ele, n));
113 self.next()
114 }
115 }
116 IterState::PreContent => {
117 let (ele, n) = self.elements.pop().unwrap();
118 if n < ele.contents().len() {
119 let next_ele = &ele.contents()[n];
120 self.elements.push((ele, n));
121 self.elements.push((next_ele, 0));
122 self.state = IterState::PreElement;
123 } else {
124 self.state = IterState::PostContent;
125 self.elements.push((ele, n));
126 }
127 self.next()
128 }
129 IterState::PostContent => {
130 let (ele, n) = self.elements.pop().unwrap();
131 self.state = IterState::FindNextElement;
132 self.elements.push((ele, n));
133 Some(XmlEvent::EndElement(ele))
134 }
135 IterState::FindNextElement => {
136 if self.elements.len() > 1 {
137 let (_ele, _n) = self.elements.pop().unwrap();
138 let (ele, n) = self.elements.pop().unwrap();
139 if n + 1 < ele.contents().len() {
140 let next_ele = &ele.contents()[n + 1];
141 self.elements.push((ele, n + 1));
142 self.elements.push((next_ele, 0));
143 self.state = IterState::PreElement;
144 } else {
145 self.elements.push((ele, n + 1));
146 self.state = IterState::PostContent;
147 }
148 } else {
149 self.state = IterState::DocumentEnd;
150 }
151 self.next()
152 }
153 IterState::DocumentEnd => {
154 self.state = IterState::Completed;
155 Some(XmlEvent::EndDocument)
156 }
157 IterState::Completed => None,
158 }
159 }
160}