Skip to main content

anyxml/stax/
events.rs

1//! Provide StAX parser events.
2
3use crate::{XMLVersion, sax::Attributes};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
6pub(crate) enum XMLEventType {
7    #[default]
8    StartDocument,
9    EndDocument,
10    StartElement,
11    EndElement,
12    StartEmptyTag,
13    EndEmptyTag,
14    Declaration,
15    DocumentType,
16    Characters,
17    CDATASection,
18    Space,
19    Comment,
20    ProcessingInstruction,
21    StartEntity,
22    EndEntity,
23    FatalError,
24    Finished,
25}
26
27/// Parser event from StAX parser.
28pub enum XMLEvent<'a> {
29    StartDocument,
30    EndDocument,
31    StartElement(StartElement<'a>),
32    EndElement(EndElement<'a>),
33    Declaration(Declaration<'a>),
34    DocumentType,
35    Characters(&'a str),
36    CDATASection(&'a str),
37    Space(&'a str),
38    Comment(&'a str),
39    ProcessingInstruction(ProcessingInstruction<'a>),
40    StartEntity(&'a str),
41    EndEntity,
42    FatalError,
43    Finished,
44}
45
46impl std::fmt::Debug for XMLEvent<'_> {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        match self {
49            XMLEvent::StartDocument => write!(f, "startDocument()"),
50            XMLEvent::EndDocument => write!(f, "endDocument()"),
51            XMLEvent::StartElement(start) => {
52                write!(
53                    f,
54                    "startElement({}, {}, {}, {}",
55                    start.namespace_name().unwrap_or("None"),
56                    start.prefix().unwrap_or("None"),
57                    start.local_name().unwrap_or("None"),
58                    start.name()
59                )?;
60
61                for att in start.attributes() {
62                    write!(f, ", ")?;
63                    if let Some(local_name) = att.local_name.as_deref() {
64                        if let Some(uri) = att.namespace_name.as_deref() {
65                            write!(f, "{{{uri}}}")?;
66                        }
67                        write!(f, "{local_name}='{}'", att.value)?;
68                    } else {
69                        write!(f, "{}='{}'", att.qname, att.value)?;
70                    }
71                }
72                write!(f, ")")
73            }
74            XMLEvent::EndElement(end) => {
75                write!(
76                    f,
77                    "endElement({}, {}, {}, {})",
78                    end.namespace_name().unwrap_or("None"),
79                    end.prefix().unwrap_or("None"),
80                    end.local_name().unwrap_or("None"),
81                    end.name()
82                )
83            }
84            XMLEvent::Declaration(declaration) => {
85                write!(
86                    f,
87                    "declaration({}, {}, ",
88                    declaration.version(),
89                    declaration.encoding().unwrap_or("None")
90                )?;
91                if let Some(standalone) = declaration.standalone() {
92                    if standalone {
93                        write!(f, "yes)")
94                    } else {
95                        write!(f, "no)")
96                    }
97                } else {
98                    write!(f, "None)")
99                }
100            }
101            XMLEvent::DocumentType => write!(f, "documentType()"),
102            XMLEvent::Characters(characters) => {
103                write!(f, "characters({characters})")
104            }
105            XMLEvent::CDATASection(cdata) => write!(f, "cdataSection({cdata})"),
106            XMLEvent::Space(space) => write!(f, "space({space})"),
107            XMLEvent::Comment(comment) => write!(f, "comment({comment})"),
108            XMLEvent::ProcessingInstruction(pi) => write!(
109                f,
110                "processingInstruction({}, '{}')",
111                pi.target(),
112                pi.data().unwrap_or("None")
113            ),
114            XMLEvent::StartEntity(entity) => write!(f, "startEntity({entity})"),
115            XMLEvent::EndEntity => write!(f, "endEntity()"),
116            XMLEvent::FatalError => write!(f, "fatalError()"),
117            XMLEvent::Finished => write!(f, "finished()"),
118        }
119    }
120}
121
122/// Start element event.
123pub struct StartElement<'a> {
124    pub(super) namespace_name: Option<&'a str>,
125    pub(super) local_name: Option<&'a str>,
126    pub(super) qname: &'a str,
127    pub(super) atts: &'a Attributes,
128}
129
130impl StartElement<'_> {
131    /// QName of this element.
132    pub fn name(&self) -> &str {
133        self.qname
134    }
135
136    /// Local part of QName of this element.
137    pub fn local_name(&self) -> Option<&str> {
138        self.local_name
139    }
140
141    /// Prefix of QName of this element.
142    pub fn prefix(&self) -> Option<&str> {
143        let local_name = self.local_name?;
144        let prefix_len = self.qname.len() - local_name.len();
145        (prefix_len > 0).then(|| &self.qname[..prefix_len - 1])
146    }
147
148    /// Namespace name of this element.
149    pub fn namespace_name(&self) -> Option<&str> {
150        self.namespace_name
151    }
152
153    /// Attributes of this element.
154    pub fn attributes(&self) -> &Attributes {
155        self.atts
156    }
157}
158
159/// End element event.
160pub struct EndElement<'a> {
161    pub(super) namespace_name: Option<&'a str>,
162    pub(super) local_name: Option<&'a str>,
163    pub(super) qname: &'a str,
164}
165
166impl EndElement<'_> {
167    /// QName of this element.
168    pub fn name(&self) -> &str {
169        self.qname
170    }
171
172    /// Local part of QName of this element.
173    pub fn local_name(&self) -> Option<&str> {
174        self.local_name
175    }
176
177    /// Prefix of QName of this element.
178    pub fn prefix(&self) -> Option<&str> {
179        let local_name = self.local_name?;
180        let prefix_len = self.qname.len() - local_name.len();
181        (prefix_len > 0).then(|| &self.qname[..prefix_len - 1])
182    }
183
184    /// Namespace name of this element.
185    pub fn namespace_name(&self) -> Option<&str> {
186        self.namespace_name
187    }
188}
189
190/// Declaration event.
191pub struct Declaration<'a> {
192    pub(super) version: XMLVersion,
193    pub(super) encoding: Option<&'a str>,
194    pub(super) standalone: Option<bool>,
195}
196
197impl Declaration<'_> {
198    /// XML version.
199    pub fn version(&self) -> XMLVersion {
200        self.version
201    }
202
203    /// Encoding name specified at this declaration.
204    pub fn encoding(&self) -> Option<&str> {
205        self.encoding
206    }
207
208    /// If explicitly set to `standalone='yes'`, returns `true`.  \
209    /// If `standalone='no'` or no standalone declaration exists, returns `false`.
210    pub fn is_standalone(&self) -> bool {
211        self.standalone == Some(true)
212    }
213
214    /// If the standalone declaration exists, return a `Some` wrapping a Boolean value corresponding
215    /// to that declaration.  \
216    /// If no standalone declaration exists, return `None`.
217    pub fn standalone(&self) -> Option<bool> {
218        self.standalone
219    }
220}
221
222/// Processing instruction event.
223pub struct ProcessingInstruction<'a> {
224    pub(super) target: &'a str,
225    pub(super) data: Option<&'a str>,
226}
227
228impl ProcessingInstruction<'_> {
229    /// Target name of this processing instruction.
230    pub fn target(&self) -> &str {
231        self.target
232    }
233
234    /// Data of this processing instruction.
235    pub fn data(&self) -> Option<&str> {
236        self.data
237    }
238}