1use core::fmt;
2use core::str;
3#[cfg(feature = "std")]
4use std::error;
5
6
7#[allow(missing_docs)]
9#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
10pub enum Error {
11 InvalidDeclaration(StreamError, TextPos),
12 InvalidComment(StreamError, TextPos),
13 InvalidPI(StreamError, TextPos),
14 InvalidDoctype(StreamError, TextPos),
15 InvalidEntity(StreamError, TextPos),
16 InvalidElement(StreamError, TextPos),
17 InvalidAttribute(StreamError, TextPos),
18 InvalidCdata(StreamError, TextPos),
19 InvalidCharData(StreamError, TextPos),
20 UnknownToken(TextPos),
21}
22
23impl Error {
24 pub fn pos(&self) -> TextPos {
26 match *self {
27 Error::InvalidDeclaration(_, pos) => pos,
28 Error::InvalidComment(_, pos) => pos,
29 Error::InvalidPI(_, pos) => pos,
30 Error::InvalidDoctype(_, pos) => pos,
31 Error::InvalidEntity(_, pos) => pos,
32 Error::InvalidElement(_, pos) => pos,
33 Error::InvalidAttribute(_, pos) => pos,
34 Error::InvalidCdata(_, pos) => pos,
35 Error::InvalidCharData(_, pos) => pos,
36 Error::UnknownToken(pos) => pos,
37 }
38 }
39}
40
41impl fmt::Display for Error {
42 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
43 match *self {
44 Error::InvalidDeclaration(ref cause, pos) => {
45 write!(f, "invalid XML declaration at {} cause {}", pos, cause)
46 }
47 Error::InvalidComment(ref cause, pos) => {
48 write!(f, "invalid comment at {} cause {}", pos, cause)
49 }
50 Error::InvalidPI(ref cause, pos) => {
51 write!(f, "invalid processing instruction at {} cause {}", pos, cause)
52 }
53 Error::InvalidDoctype(ref cause, pos) => {
54 write!(f, "invalid DTD at {} cause {}", pos, cause)
55 }
56 Error::InvalidEntity(ref cause, pos) => {
57 write!(f, "invalid DTD entity at {} cause {}", pos, cause)
58 }
59 Error::InvalidElement(ref cause, pos) => {
60 write!(f, "invalid element at {} cause {}", pos, cause)
61 }
62 Error::InvalidAttribute(ref cause, pos) => {
63 write!(f, "invalid attribute at {} cause {}", pos, cause)
64 }
65 Error::InvalidCdata(ref cause, pos) => {
66 write!(f, "invalid CDATA at {} cause {}", pos, cause)
67 }
68 Error::InvalidCharData(ref cause, pos) => {
69 write!(f, "invalid character data at {} cause {}", pos, cause)
70 }
71 Error::UnknownToken(pos) => {
72 write!(f, "unknown token at {}", pos)
73 }
74 }
75 }
76}
77
78#[cfg(feature = "std")]
79impl error::Error for Error {
80 fn description(&self) -> &str {
81 "an XML parsing error"
82 }
83}
84
85
86#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
88pub enum StreamError {
89 UnexpectedEndOfStream,
94
95 InvalidName,
97
98 NonXmlChar(char, TextPos),
102
103 InvalidChar(u8, u8, TextPos),
109
110 InvalidCharMultiple(u8, &'static [u8], TextPos),
114
115 InvalidQuote(u8, TextPos),
117
118 InvalidSpace(u8, TextPos),
122
123 InvalidString(&'static str, TextPos),
127
128 InvalidReference,
130
131 InvalidExternalID,
133
134 InvalidCommentData,
136
137 InvalidCommentEnd,
139
140 InvalidCharacterData,
144}
145
146impl fmt::Display for StreamError {
147 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
148 match *self {
149 StreamError::UnexpectedEndOfStream => {
150 write!(f, "unexpected end of stream")
151 }
152 StreamError::InvalidName => {
153 write!(f, "invalid name token")
154 }
155 StreamError::NonXmlChar(c, pos) => {
156 write!(f, "a non-XML character {:?} found at {}", c, pos)
157 }
158 StreamError::InvalidChar(actual, expected, pos) => {
159 write!(f, "expected '{}' not '{}' at {}",
160 expected as char, actual as char, pos)
161 }
162 StreamError::InvalidCharMultiple(actual, ref expected, pos) => {
163 let mut expected_iter = expected.iter().peekable();
164
165 write!(f, "expected ")?;
166 while let Some(&c) = expected_iter.next() {
167 write!(f, "'{}'", c as char)?;
168 if expected_iter.peek().is_some() {
169 write!(f, ", ")?;
170 }
171 }
172 write!(f, " not '{}' at {}", actual as char, pos)
173 }
174 StreamError::InvalidQuote(c, pos) => {
175 write!(f, "expected quote mark not '{}' at {}", c as char, pos)
176 }
177 StreamError::InvalidSpace(c, pos) => {
178 write!(f, "expected space not '{}' at {}", c as char, pos)
179 }
180 StreamError::InvalidString(expected, pos) => {
181 write!(f, "expected '{}' at {}", expected, pos)
182 }
183 StreamError::InvalidReference => {
184 write!(f, "invalid reference")
185 }
186 StreamError::InvalidExternalID => {
187 write!(f, "invalid ExternalID")
188 }
189 StreamError::InvalidCommentData => {
190 write!(f, "'--' is not allowed in comments")
191 }
192 StreamError::InvalidCommentEnd => {
193 write!(f, "comment cannot end with '-'")
194 }
195 StreamError::InvalidCharacterData => {
196 write!(f, "']]>' is not allowed inside a character data")
197 }
198 }
199 }
200}
201
202#[cfg(feature = "std")]
203impl error::Error for StreamError {
204 fn description(&self) -> &str {
205 "an XML stream parsing error"
206 }
207}
208
209
210#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
214#[allow(missing_docs)]
215pub struct TextPos {
216 pub row: u32,
217 pub col: u32,
218}
219
220impl TextPos {
221 pub fn new(row: u32, col: u32) -> TextPos {
225 TextPos { row, col }
226 }
227}
228
229impl fmt::Display for TextPos {
230 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
231 write!(f, "{}:{}", self.row, self.col)
232 }
233}