1use std::borrow::Cow;
4use std::fmt;
5
6use facet_dom::{DomDeserializer, DomEvent, DomParser, DomSerializer, WriteScalar};
7
8use crate::{Content, Element};
9
10#[derive(Debug)]
11pub struct ElementParseError;
12
13impl fmt::Display for ElementParseError {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 write!(f, "element parse error")
16 }
17}
18
19impl std::error::Error for ElementParseError {}
20
21pub fn from_element<T>(
23 element: &Element,
24) -> Result<T, facet_dom::DomDeserializeError<ElementParseError>>
25where
26 T: facet_core::Facet<'static>,
27{
28 let parser = ElementParser::new(element);
29 let mut de = DomDeserializer::new_owned(parser);
30 de.deserialize()
31}
32
33pub struct ElementParser<'a> {
35 stack: Vec<Frame<'a>>,
37 peeked: Option<DomEvent<'static>>,
39 depth: usize,
41}
42
43struct Frame<'a> {
44 element: &'a Element,
45 state: FrameState,
46 attr_iter: std::collections::hash_map::Iter<'a, String, String>,
47 child_idx: usize,
48}
49
50#[derive(Clone, Copy, PartialEq)]
51enum FrameState {
52 Start,
53 Attrs,
54 ChildrenStart,
55 Children,
56 ChildrenEnd,
57 NodeEnd,
58 Done,
59}
60
61impl<'a> ElementParser<'a> {
62 pub fn new(root: &'a Element) -> Self {
63 Self {
64 stack: vec![Frame {
65 element: root,
66 state: FrameState::Start,
67 attr_iter: root.attrs.iter(),
68 child_idx: 0,
69 }],
70 peeked: None,
71 depth: 0,
72 }
73 }
74
75 fn read_next(&mut self) -> Result<Option<DomEvent<'static>>, ElementParseError> {
76 loop {
77 let frame = match self.stack.last_mut() {
78 Some(f) => f,
79 None => return Ok(None),
80 };
81
82 match frame.state {
83 FrameState::Start => {
84 self.depth += 1;
85 frame.state = FrameState::Attrs;
86 return Ok(Some(DomEvent::NodeStart {
87 tag: Cow::Owned(frame.element.tag.clone()),
88 namespace: None,
89 }));
90 }
91 FrameState::Attrs => {
92 if let Some((name, value)) = frame.attr_iter.next() {
93 return Ok(Some(DomEvent::Attribute {
94 name: Cow::Owned(name.clone()),
95 value: Cow::Owned(value.clone()),
96 namespace: None,
97 }));
98 }
99 frame.state = FrameState::ChildrenStart;
100 }
101 FrameState::ChildrenStart => {
102 frame.state = FrameState::Children;
103 return Ok(Some(DomEvent::ChildrenStart));
104 }
105 FrameState::Children => {
106 if frame.child_idx < frame.element.children.len() {
107 let child = &frame.element.children[frame.child_idx];
108 frame.child_idx += 1;
109
110 match child {
111 Content::Text(t) => {
112 return Ok(Some(DomEvent::Text(Cow::Owned(t.clone()))));
113 }
114 Content::Element(e) => {
115 self.stack.push(Frame {
117 element: e,
118 state: FrameState::Start,
119 attr_iter: e.attrs.iter(),
120 child_idx: 0,
121 });
122 }
124 }
125 } else {
126 frame.state = FrameState::ChildrenEnd;
127 }
128 }
129 FrameState::ChildrenEnd => {
130 frame.state = FrameState::NodeEnd;
131 return Ok(Some(DomEvent::ChildrenEnd));
132 }
133 FrameState::NodeEnd => {
134 frame.state = FrameState::Done;
135 self.depth -= 1;
136 return Ok(Some(DomEvent::NodeEnd));
137 }
138 FrameState::Done => {
139 self.stack.pop();
140 }
141 }
142 }
143 }
144}
145
146impl<'a> DomParser<'static> for ElementParser<'a> {
147 type Error = ElementParseError;
148
149 fn next_event(&mut self) -> Result<Option<DomEvent<'static>>, Self::Error> {
150 if let Some(event) = self.peeked.take() {
151 return Ok(Some(event));
152 }
153 self.read_next()
154 }
155
156 fn peek_event(&mut self) -> Result<Option<&DomEvent<'static>>, Self::Error> {
157 if self.peeked.is_none() {
158 self.peeked = self.read_next()?;
159 }
160 Ok(self.peeked.as_ref())
161 }
162
163 fn skip_node(&mut self) -> Result<(), Self::Error> {
164 let start_depth = self.depth;
165 loop {
166 match self.next_event()? {
167 Some(DomEvent::NodeEnd) if self.depth < start_depth => break,
168 None => break,
169 _ => {}
170 }
171 }
172 Ok(())
173 }
174
175 fn format_namespace(&self) -> Option<&'static str> {
176 Some("xml")
177 }
178}
179
180#[derive(Debug)]
181pub struct ElementSerializeError;
182
183impl fmt::Display for ElementSerializeError {
184 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
185 write!(f, "element serialize error")
186 }
187}
188
189impl std::error::Error for ElementSerializeError {}
190
191pub fn to_element<T>(
193 value: &T,
194) -> Result<Element, facet_dom::DomSerializeError<ElementSerializeError>>
195where
196 T: facet_core::Facet<'static>,
197{
198 let mut serializer = ElementSerializer::default();
199 let peek = facet_reflect::Peek::new(value);
200 facet_dom::serialize(&mut serializer, peek)?;
201 serializer.finish()
202}
203
204#[derive(Default)]
206pub struct ElementSerializer {
207 stack: Vec<Element>,
209 root: Option<Element>,
211 is_attribute: bool,
213 is_text: bool,
215 is_elements: bool,
217 is_tag: bool,
219 is_doctype: bool,
221}
222
223impl ElementSerializer {
224 fn finish(mut self) -> Result<Element, facet_dom::DomSerializeError<ElementSerializeError>> {
226 if let Some(root) = self.root.take() {
228 return Ok(root);
229 }
230
231 if self.stack.len() == 1 {
233 Ok(self.stack.pop().unwrap())
234 } else {
235 Err(facet_dom::DomSerializeError::Backend(ElementSerializeError))
236 }
237 }
238}
239
240impl DomSerializer for ElementSerializer {
241 type Error = ElementSerializeError;
242
243 fn element_start(&mut self, tag: &str, _namespace: Option<&str>) -> Result<(), Self::Error> {
244 self.stack.push(Element::new(tag));
245 Ok(())
246 }
247
248 fn attribute(
249 &mut self,
250 name: &str,
251 value: facet_reflect::Peek<'_, '_>,
252 _namespace: Option<&str>,
253 ) -> Result<(), Self::Error> {
254 if let Some(value_str) = self.format_scalar(value) {
256 let elem = self.stack.last_mut().ok_or(ElementSerializeError)?;
257 elem.attrs.insert(name.to_string(), value_str);
258 }
259 Ok(())
260 }
261
262 fn children_start(&mut self) -> Result<(), Self::Error> {
263 Ok(())
264 }
265
266 fn children_end(&mut self) -> Result<(), Self::Error> {
267 Ok(())
268 }
269
270 fn element_end(&mut self, _tag: &str) -> Result<(), Self::Error> {
271 let elem = self.stack.pop().ok_or(ElementSerializeError)?;
272
273 if let Some(parent) = self.stack.last_mut() {
274 parent.children.push(Content::Element(elem));
275 } else {
276 self.root = Some(elem);
277 }
278 Ok(())
279 }
280
281 fn text(&mut self, content: &str) -> Result<(), Self::Error> {
282 if let Some(elem) = self.stack.last_mut() {
283 elem.children.push(Content::Text(content.to_string()));
284 } else {
285 return Err(ElementSerializeError);
286 }
287 Ok(())
288 }
289
290 fn format_namespace(&self) -> Option<&'static str> {
291 Some("xml")
292 }
293
294 fn field_metadata(&mut self, field: &facet_reflect::FieldItem) -> Result<(), Self::Error> {
295 let Some(field_def) = field.field else {
296 self.is_attribute = true;
298 self.is_text = false;
299 self.is_elements = false;
300 self.is_tag = false;
301 self.is_doctype = false;
302 return Ok(());
303 };
304
305 self.is_attribute = field_def.get_attr(Some("xml"), "attribute").is_some();
307 self.is_text = field_def.get_attr(Some("xml"), "text").is_some();
308 self.is_elements = field_def.get_attr(Some("xml"), "elements").is_some();
309 self.is_tag = field_def.get_attr(Some("xml"), "tag").is_some();
310 self.is_doctype = field_def.get_attr(Some("xml"), "doctype").is_some();
311 Ok(())
312 }
313
314 fn is_attribute_field(&self) -> bool {
315 self.is_attribute
316 }
317
318 fn is_text_field(&self) -> bool {
319 self.is_text
320 }
321
322 fn is_elements_field(&self) -> bool {
323 self.is_elements
324 }
325
326 fn is_tag_field(&self) -> bool {
327 self.is_tag
328 }
329
330 fn is_doctype_field(&self) -> bool {
331 self.is_doctype
332 }
333
334 fn clear_field_state(&mut self) {
335 self.is_attribute = false;
336 self.is_text = false;
337 self.is_elements = false;
338 self.is_tag = false;
339 self.is_doctype = false;
340 }
341}