xsd_parser/xml/
element.rs

1use std::borrow::Cow;
2use std::fmt::{Debug, Formatter, Result as FmtResult};
3use std::mem::replace;
4use std::slice::Iter;
5use std::str::from_utf8;
6
7use quick_xml::{
8    events::{attributes::Attribute, BytesEnd, BytesStart},
9    name::QName,
10};
11
12use crate::models::format_utf8_slice;
13use crate::quick_xml::{
14    Deserializer, DeserializerArtifact, DeserializerEvent, DeserializerOutput, DeserializerResult,
15    Error, Event, WithDeserializer, WithSerializer, XmlReader,
16};
17
18use super::{
19    attributes::{Key as AttribKey, Value as AttribValue},
20    Attributes, NamespacesShared, Value,
21};
22
23/// Represents a unstructured XML element.
24#[derive(Default, Clone, Eq, PartialEq)]
25pub struct Element<'a> {
26    /// Name of the element.
27    pub name: Cow<'a, [u8]>,
28
29    /// Child values of this element.
30    pub values: Vec<Value<'a>>,
31
32    /// Attributes of this element.
33    pub attributes: Attributes<'a>,
34
35    /// List of valid namespaces for this element.
36    pub namespaces: NamespacesShared<'a>,
37}
38
39/// Represents a list of unstructured XML elements.
40pub type Elements<'a> = Vec<Element<'a>>;
41
42/// Helper type for an element with static lifetime
43pub type AnyElement = Element<'static>;
44
45/// Helper type for elements with static lifetime
46pub type AnyElements = Elements<'static>;
47
48impl<'a> Element<'a> {
49    /// Create a new [`Element`] instance.
50    #[must_use]
51    pub fn new() -> Self {
52        Self::default()
53    }
54
55    /// Return the name of the element as [`QName`].
56    #[must_use]
57    pub fn qname(&self) -> QName<'_> {
58        QName(&self.name)
59    }
60
61    /// Set the name of the element.
62    #[must_use]
63    pub fn name<N>(mut self, name: N) -> Self
64    where
65        N: Into<Cow<'a, [u8]>>,
66    {
67        self.name = name.into();
68
69        self
70    }
71
72    /// Add an attribute to the element.
73    #[must_use]
74    pub fn attribute<K, V>(mut self, name: K, value: V) -> Self
75    where
76        K: Into<Cow<'a, [u8]>>,
77        V: Into<Cow<'a, [u8]>>,
78    {
79        self.attributes.insert(name, value);
80
81        self
82    }
83
84    /// Add a child value to the element.
85    #[must_use]
86    pub fn child(mut self, value: Value<'a>) -> Self {
87        self.values.push(value);
88
89        self
90    }
91}
92
93impl Debug for Element<'_> {
94    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
95        struct Name<'a>(&'a [u8]);
96
97        impl Debug for Name<'_> {
98            fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
99                write!(f, "\"")?;
100                format_utf8_slice(self.0, f)?;
101                write!(f, "\"")?;
102
103                Ok(())
104            }
105        }
106
107        f.debug_struct("Element")
108            .field("name", &Name(&self.name))
109            .field("values", &self.values)
110            .field("attributes", &self.attributes)
111            .field("namespaces", &self.namespaces)
112            .finish()
113    }
114}
115
116impl<'el> WithSerializer for Element<'el> {
117    type Serializer<'x>
118        = ElementSerializer<'x, 'el>
119    where
120        'el: 'x;
121
122    fn serializer<'ser>(
123        &'ser self,
124        name: Option<&'ser str>,
125        is_root: bool,
126    ) -> Result<Self::Serializer<'ser>, Error> {
127        let _name = name;
128        let _is_root = is_root;
129
130        Ok(ElementSerializer::new(self))
131    }
132}
133
134impl WithDeserializer for Element<'static> {
135    type Deserializer = ElementDeserializer;
136}
137
138#[derive(Debug)]
139pub enum ElementSerializer<'ser, 'el> {
140    Start {
141        element: &'ser Element<'el>,
142    },
143    End {
144        element: &'ser Element<'el>,
145    },
146    NextValue {
147        element: &'ser Element<'el>,
148        values: Iter<'ser, Value<'el>>,
149    },
150    SubElement {
151        element: &'ser Element<'el>,
152        values: Iter<'ser, Value<'el>>,
153        serializer: Box<ElementSerializer<'ser, 'el>>,
154    },
155    Done,
156}
157
158impl<'ser, 'el> ElementSerializer<'ser, 'el> {
159    fn new(element: &'ser Element<'el>) -> Self {
160        Self::Start { element }
161    }
162
163    fn next_item(&mut self) -> Result<Option<Event<'ser>>, Error> {
164        loop {
165            match replace(self, Self::Done) {
166                Self::Start { element } => {
167                    let name = from_utf8(&element.name)?;
168                    let attributes = element.attributes.iter().map(|(k, v)| Attribute {
169                        key: QName(k),
170                        value: Cow::Borrowed(&v.0),
171                    });
172
173                    let mut start = BytesStart::new(name);
174                    start.extend_attributes(attributes);
175
176                    let event = if element.values.is_empty() {
177                        Event::Empty(start)
178                    } else {
179                        let values = element.values.iter();
180
181                        *self = Self::NextValue { element, values };
182
183                        Event::Start(start)
184                    };
185
186                    return Ok(Some(event));
187                }
188                Self::End { element } => {
189                    let name = from_utf8(&element.name)?;
190                    let end = BytesEnd::new(name);
191                    let event = Event::End(end);
192
193                    return Ok(Some(event));
194                }
195                Self::NextValue {
196                    element,
197                    mut values,
198                } => match values.next() {
199                    None => *self = Self::End { element },
200                    Some(Value::Element(sub)) => {
201                        let serializer = Box::new(Self::new(sub));
202
203                        *self = Self::SubElement {
204                            element,
205                            values,
206                            serializer,
207                        };
208                    }
209                    Some(Value::Comment(comment)) => {
210                        *self = Self::NextValue { element, values };
211
212                        return Ok(Some(Event::Comment(comment.borrow())));
213                    }
214                    Some(Value::CData(cdata)) => {
215                        *self = Self::NextValue { element, values };
216
217                        return Ok(Some(Event::CData(cdata.borrow())));
218                    }
219                    Some(Value::Text(text)) => {
220                        *self = Self::NextValue { element, values };
221
222                        return Ok(Some(Event::Text(text.borrow())));
223                    }
224                },
225                Self::SubElement {
226                    element,
227                    values,
228                    mut serializer,
229                } => match serializer.next() {
230                    None => *self = Self::NextValue { element, values },
231                    Some(event) => {
232                        *self = Self::SubElement {
233                            element,
234                            values,
235                            serializer,
236                        };
237
238                        return event.map(Some);
239                    }
240                },
241                Self::Done => return Ok(None),
242            }
243        }
244    }
245}
246
247impl<'ser> Iterator for ElementSerializer<'ser, '_> {
248    type Item = Result<Event<'ser>, Error>;
249
250    fn next(&mut self) -> Option<Self::Item> {
251        self.next_item().transpose()
252    }
253}
254
255#[derive(Debug)]
256pub struct ElementDeserializer {
257    element: Element<'static>,
258    sub: Box<Option<ElementDeserializer>>,
259}
260
261impl ElementDeserializer {
262    fn new(element: Element<'static>) -> Self {
263        Self {
264            element,
265            sub: Box::new(None),
266        }
267    }
268
269    fn create_element(
270        start: &BytesStart<'_>,
271        namespaces: NamespacesShared<'static>,
272    ) -> Result<Element<'static>, Error> {
273        let name = Cow::Owned(start.name().0.to_owned());
274        let attributes = start
275            .attributes()
276            .map(|item| match item {
277                Ok(Attribute { key, value }) => {
278                    let key = Cow::Owned(key.0.to_owned());
279                    let value = Cow::Owned(value.into_owned());
280
281                    Ok((AttribKey(key), AttribValue(value)))
282                }
283                Err(error) => Err(error),
284            })
285            .collect::<Result<Attributes<'static>, _>>()?;
286
287        Ok(Element {
288            name,
289            attributes,
290            namespaces,
291            values: Vec::new(),
292        })
293    }
294}
295
296impl<'de> Deserializer<'de, Element<'static>> for ElementDeserializer {
297    fn init<R>(reader: &R, event: Event<'de>) -> DeserializerResult<'de, Element<'static>>
298    where
299        R: XmlReader,
300    {
301        match event {
302            Event::Start(start) => {
303                let namespaces = reader.namespaces();
304                let element = Self::create_element(&start, namespaces)?;
305                let deserializer = Self::new(element);
306
307                Ok(DeserializerOutput {
308                    artifact: DeserializerArtifact::Deserializer(deserializer),
309                    event: DeserializerEvent::None,
310                    allow_any: true,
311                })
312            }
313            Event::Empty(start) => {
314                let namespaces = reader.namespaces();
315                let element = Self::create_element(&start, namespaces)?;
316
317                Ok(DeserializerOutput {
318                    artifact: DeserializerArtifact::Data(element),
319                    event: DeserializerEvent::None,
320                    allow_any: true,
321                })
322            }
323            event => Ok(DeserializerOutput {
324                artifact: DeserializerArtifact::None,
325                event: DeserializerEvent::Continue(event),
326                allow_any: true,
327            }),
328        }
329    }
330
331    fn next<R>(mut self, reader: &R, event: Event<'de>) -> DeserializerResult<'de, Element<'static>>
332    where
333        R: XmlReader,
334    {
335        macro_rules! handle_output {
336            ($output:expr) => {{
337                let output = $output;
338
339                match output.artifact {
340                    DeserializerArtifact::None => (),
341                    DeserializerArtifact::Data(element) => {
342                        let value = Value::Element(element);
343
344                        self.element.values.push(value);
345                    }
346                    DeserializerArtifact::Deserializer(sub) => {
347                        *self.sub = Some(sub);
348                    }
349                }
350
351                match output.event {
352                    DeserializerEvent::None => None,
353                    DeserializerEvent::Break(event) => {
354                        return Ok(DeserializerOutput {
355                            artifact: DeserializerArtifact::Deserializer(self),
356                            event: DeserializerEvent::Break(event),
357                            allow_any: true,
358                        })
359                    }
360                    DeserializerEvent::Continue(event) => Some(event),
361                }
362            }};
363        }
364
365        let event = if let Some(sub) = self.sub.take() {
366            let output = sub.next(reader, event)?;
367
368            handle_output!(output)
369        } else {
370            Some(event)
371        };
372
373        let event = match event {
374            None => None,
375            Some(event @ (Event::Start(_) | Event::Empty(_))) => {
376                let output = Self::init(reader, event)?;
377
378                handle_output!(output)
379            }
380            Some(Event::End(_)) => {
381                return Ok(DeserializerOutput {
382                    artifact: DeserializerArtifact::Data(self.element),
383                    event: DeserializerEvent::None,
384                    allow_any: true,
385                })
386            }
387            Some(Event::Text(text)) => {
388                let value = Value::Text(text.into_owned());
389
390                self.element.values.push(value);
391
392                None
393            }
394            Some(Event::CData(cdata)) => {
395                let value = Value::CData(cdata.into_owned());
396
397                self.element.values.push(value);
398
399                None
400            }
401            Some(Event::Comment(comment)) => {
402                let value = Value::Comment(comment.into_owned());
403
404                self.element.values.push(value);
405
406                None
407            }
408            event => event,
409        };
410
411        Ok(DeserializerOutput {
412            artifact: DeserializerArtifact::Deserializer(self),
413            event: event.map_or(DeserializerEvent::None, DeserializerEvent::Break),
414            allow_any: true,
415        })
416    }
417
418    fn finish<R>(mut self, reader: &R) -> Result<Element<'static>, Error>
419    where
420        R: XmlReader,
421    {
422        if let Some(sub) = self.sub.take() {
423            let element = sub.finish(reader)?;
424            let value = Value::Element(element);
425
426            self.element.values.push(value);
427        }
428
429        Ok(self.element)
430    }
431}
432
433#[cfg(test)]
434mod tests {
435    use std::str::from_utf8;
436    use std::sync::Arc;
437
438    use quick_xml::{events::BytesText, Writer};
439
440    use crate::quick_xml::{DeserializeSync, SerializeSync, SliceReader};
441    use crate::xml::Value;
442
443    use super::Element;
444
445    macro_rules! assert_entry {
446        ($map:expr, $key:expr, $val:expr) => {
447            assert_eq!($map.get(&$key[..]).unwrap().as_ref(), $val);
448        };
449    }
450
451    macro_rules! assert_element {
452        ($value:expr) => {
453            if let Value::Element(element) = $value {
454                element
455            } else {
456                panic!("Unexpected value")
457            }
458        };
459    }
460
461    macro_rules! assert_text {
462        ($value:expr, $text:expr) => {
463            assert!(matches!($value, Value::Text(x) if &**x == $text));
464        };
465    }
466
467    #[test]
468    fn serialize() {
469        let mut root = Element::new();
470        root.name = b"names".into();
471
472        root.values.push(Value::Text(BytesText::new("\n    ")));
473
474        let mut element = Element::new();
475        element.name = b"name".into();
476        element.attributes.insert(b"xmlns:ns", b"test");
477        element.attributes.insert(b"ns:first", b"bob");
478        element.attributes.insert(b"last", b"jones");
479        root.values.push(Value::Element(element));
480
481        root.values.push(Value::Text(BytesText::new("\n    ")));
482
483        let mut element = Element::new();
484        element.name = b"name".into();
485        element.attributes.insert(b"first", b"elizabeth");
486        element.attributes.insert(b"last", b"smith");
487        root.values.push(Value::Element(element));
488
489        root.values.push(Value::Text(BytesText::new("\n")));
490
491        let mut buffer = Vec::new();
492        let mut writer = Writer::new(&mut buffer);
493        root.serialize("", &mut writer).unwrap();
494
495        let xml = from_utf8(&buffer).unwrap();
496        assert_eq!(xml, XML.trim());
497    }
498
499    #[test]
500    fn deserialize() {
501        let mut reader = SliceReader::new(XML.trim());
502        let root = Element::deserialize(&mut reader).unwrap();
503
504        dbg!(&root);
505
506        assert_eq!(root.name.as_ref(), b"names");
507        assert_eq!(root.values.len(), 5);
508        assert!(root.attributes.is_empty());
509        assert!(root.namespaces.is_empty());
510
511        let mut iter = root.values.iter();
512
513        let value = iter.next().unwrap();
514        assert_text!(value, b"\n    ");
515
516        let value = iter.next().unwrap();
517        let element = assert_element!(value);
518        assert_eq!(element.name.as_ref(), b"name");
519        assert!(element.values.is_empty());
520        assert_eq!(element.attributes.len(), 3);
521        assert_entry!(element.attributes, b"xmlns:ns", b"test");
522        assert_entry!(element.attributes, b"ns:first", b"bob");
523        assert_entry!(element.attributes, b"last", b"jones");
524        assert_eq!(element.namespaces.len(), 1);
525        assert_entry!(element.namespaces, b"ns", b"test");
526
527        let value = iter.next().unwrap();
528        assert_text!(value, b"\n    ");
529
530        let value = iter.next().unwrap();
531        let element = assert_element!(value);
532        assert_eq!(element.name.as_ref(), b"name");
533        assert!(element.values.is_empty());
534        assert_eq!(element.attributes.len(), 2);
535        assert_entry!(element.attributes, b"first", b"elizabeth");
536        assert_entry!(element.attributes, b"last", b"smith");
537        assert!(element.namespaces.is_empty());
538        assert!(Arc::ptr_eq(&root.namespaces.0, &element.namespaces.0));
539
540        let value = iter.next().unwrap();
541        assert_text!(value, b"\n");
542    }
543
544    const XML: &str = r#"
545<names>
546    <name xmlns:ns="test" ns:first="bob" last="jones"/>
547    <name first="elizabeth" last="smith"/>
548</names>
549"#;
550}