parco_xml/dexml/tag_end.rs
1use std::borrow::Cow;
2
3use crate::{
4 DeXmlError,
5 de::Reader,
6 dexml::{
7 lex::{CloseAngle, Slash},
8 parse::Action,
9 },
10};
11
12/// the ending tag of an element i.e "\>" in "\<Element\>"
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub enum TagEnd {
15 /// A self closing tag ending with \/\>. No children
16 SelfClosing,
17 /// A normal closing tag \>. Potential children
18 Normal,
19}
20
21impl<'a> Reader<'a> {
22 /// parse the ending of a tag, if there are attributes it will consume them and then the end of the element
23 pub fn tag_end(&mut self) -> Result<TagEnd, DeXmlError> {
24 loop {
25 if self.lexer.peek('/') {
26 self.parse::<Slash>(Action::TagEnd)?;
27 self.parse::<CloseAngle>(Action::TagEnd)?;
28 return Ok(TagEnd::SelfClosing);
29 }
30 if self.lexer.peek('>') {
31 self.parse::<CloseAngle>(Action::TagEnd)?;
32 return Ok(TagEnd::Normal);
33 }
34 self.attr()?;
35 }
36 }
37
38 /// assert this element IS NOT a [`TagEnd::SelfClosing`]
39 pub fn assert_children(&mut self) -> Result<(), DeXmlError> {
40 match self.tag_end()? {
41 TagEnd::Normal => Ok(()),
42 TagEnd::SelfClosing => Err(self.err(Cow::Borrowed(DeXmlError::EXPECTED_CHILDREN))),
43 }
44 }
45
46 /// if the element has a [`TagEnd::SelfClosing`] does nothing
47 /// if the element has a [`TagEnd::Normal`] attempts to parse the closing "\<\/Element\>"
48 ///
49 /// some elements end in self closing tags such as: "\<Element \/\>"
50 /// while others look like: "\<Element\>\<\/Element\>"
51 /// [`Reader::tag_close_infer`] can be used in combination with the output of [`Reader::tag_end`]
52 /// to parse these correctly
53 ///
54 /// e.x:
55 ///
56 /// ```rust,ignore
57 /// let tag_end = reader.tag_end()?;
58 /// // if the element was self closing it does nothing, else parse the closing tag
59 /// reader.tag_close_infer(tag_end)?;
60 /// ```
61 pub fn tag_close_infer(&mut self, tag_end: TagEnd) -> Result<(), DeXmlError> {
62 match tag_end {
63 TagEnd::SelfClosing => Ok(()),
64 TagEnd::Normal => self.close_tag(),
65 }
66 }
67}