sxd_document/
parser.rs

1//! Converts XML strings into a DOM structure
2//!
3//! ### Example
4//!
5//! ```
6//! use sxd_document::parser;
7//! let xml = r#"<?xml version="1.0"?>
8//! <!-- Awesome data incoming -->
9//! <data awesome="true">
10//!   <datum>Science</datum>
11//!   <datum><![CDATA[Literature]]></datum>
12//!   <datum>Math &gt; others</datum>
13//! </data>"#;
14//! let doc = parser::parse(xml).expect("Failed to parse");
15//! ```
16
17#[allow(unused, deprecated)] // rust-lang/rust#46510
18use std::ascii::AsciiExt;
19use std::collections::{BTreeSet, HashMap};
20use std::mem::replace;
21use std::ops::Deref;
22use std::{char, error, fmt, iter};
23
24use peresil::{self,StringPoint,ParseMaster,Recoverable};
25
26use self::Reference::*;
27
28use super::{PrefixedName,QName};
29use super::dom;
30use super::str::XmlStr;
31
32#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
33enum SpecificError {
34    Expected(&'static str),
35
36    ExpectedAttribute,
37    ExpectedAttributeValue,
38
39    ExpectedCData,
40
41    ExpectedCharacterData,
42
43    ExpectedComment,
44    ExpectedCommentBody,
45
46    ExpectedElement,
47    ExpectedElementName,
48    ExpectedElementEnd,
49    ExpectedElementSelfClosed,
50
51    ExpectedProcessingInstruction,
52    ExpectedProcessingInstructionTarget,
53    ExpectedProcessingInstructionValue,
54
55    ExpectedVersionNumber,
56    ExpectedEncoding,
57    ExpectedYesNo,
58    ExpectedWhitespace,
59
60    ExpectedDocumentTypeName,
61    ExpectedIntSubset,
62    ExpectedSystemLiteral,
63
64    ExpectedClosingQuote(&'static str),
65    ExpectedOpeningQuote(&'static str),
66
67    ExpectedDecimalReferenceValue,
68    ExpectedHexReferenceValue,
69    ExpectedNamedReferenceValue,
70
71    ExpectedDecimalReference,
72    ExpectedHexReference,
73    ExpectedNamedReference,
74
75    InvalidProcessingInstructionTarget,
76    MismatchedElementEndName,
77
78    InvalidDecimalReference,
79    InvalidHexReference,
80    UnknownNamedReference,
81
82    DuplicateAttribute,
83    RedefinedNamespace,
84    RedefinedDefaultNamespace,
85    EmptyNamespace,
86    UnknownNamespacePrefix,
87    UnclosedElement,
88}
89
90impl Recoverable for SpecificError {
91    fn recoverable(&self) -> bool {
92        use self::SpecificError::*;
93
94        match *self {
95            ExpectedEncoding                   |
96            ExpectedYesNo                      |
97            InvalidProcessingInstructionTarget |
98            MismatchedElementEndName           |
99            InvalidDecimalReference            |
100            InvalidHexReference                |
101            UnknownNamedReference              |
102            DuplicateAttribute                 |
103            RedefinedNamespace                 |
104            RedefinedDefaultNamespace          |
105            EmptyNamespace                     |
106            UnknownNamespacePrefix             |
107            UnclosedElement                    => {
108                false
109            },
110            _ => true
111        }
112    }
113}
114
115impl fmt::Display for SpecificError {
116    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117        use self::error::Error;
118        use self::SpecificError::*;
119
120        match *self {
121            Expected(s)             |
122            ExpectedClosingQuote(s) |
123            ExpectedOpeningQuote(s) => {
124                write!(f, "Parser error: {} {}", self.description(), s)
125            },
126            _ => write!(f, "Parser error: {}", self.description())
127        }
128    }
129}
130
131impl error::Error for SpecificError {
132    fn description(&self) -> &str {
133        use self::SpecificError::*;
134
135        match *self {
136            Expected(_) => "expected",
137            ExpectedAttribute => "expected attribute",
138            ExpectedAttributeValue => "expected attribute value",
139            ExpectedCData => "expected CDATA",
140            ExpectedCharacterData => "expected character data",
141            ExpectedComment => "expected comment",
142            ExpectedCommentBody => "expected comment body",
143            ExpectedElement => "expected element",
144            ExpectedElementName => "expected element name",
145            ExpectedElementEnd => "expected element end",
146            ExpectedElementSelfClosed => "expected element self closed",
147            ExpectedProcessingInstruction => "expected processing instruction",
148            ExpectedProcessingInstructionTarget => "expected processing instruction target",
149            ExpectedProcessingInstructionValue => "expected processing instruction value",
150            ExpectedVersionNumber => "expected version number",
151            ExpectedEncoding => "expected encoding",
152            ExpectedYesNo => "expected yes or no",
153            ExpectedWhitespace => "expected whitespace",
154            ExpectedDocumentTypeName => "expected document type name",
155            ExpectedIntSubset => "expected int subset",
156            ExpectedSystemLiteral => "expected system literal",
157            ExpectedClosingQuote(_) => "expected closing quote",
158            ExpectedOpeningQuote(_) => "expected opening quote",
159            ExpectedDecimalReferenceValue => "expected decimal reference value",
160            ExpectedHexReferenceValue => "expected hex reference value",
161            ExpectedNamedReferenceValue => "expected named reference value",
162            ExpectedDecimalReference => "expected decimal reference",
163            ExpectedHexReference => "expected hex reference",
164            ExpectedNamedReference => "expected named reference",
165            InvalidProcessingInstructionTarget => "invalid processing instruction target",
166            MismatchedElementEndName => "mismatched element end name",
167            InvalidDecimalReference => "invalid decimal reference",
168            InvalidHexReference => "invalid hex reference",
169            UnknownNamedReference => "unknown named reference",
170            DuplicateAttribute => "duplicate attribute",
171            RedefinedNamespace => "redefined namespace",
172            RedefinedDefaultNamespace => "redefined default namespace",
173            EmptyNamespace => "empty namespace",
174            UnknownNamespacePrefix => "unknown namespace prefix",
175            UnclosedElement => "unclosed element",
176        }
177    }
178}
179
180type XmlMaster<'a> = peresil::ParseMaster<StringPoint<'a>, SpecificError>;
181type XmlProgress<'a, T> = peresil::Progress<StringPoint<'a>, T, SpecificError>;
182
183fn success<T>(data: T, point: StringPoint) -> XmlProgress<T> {
184    peresil::Progress { point: point, status: peresil::Status::Success(data) }
185}
186
187/// A truncated point; the string ends before the end of input
188#[derive(Debug,Copy,Clone)]
189struct Span<T> {
190    offset: usize,
191    value: T,
192}
193
194impl<T> Span<T> {
195    // Should this just be the return type of the parser methods?
196    fn parse<'a, F>(pt: StringPoint<'a>, f: F) -> XmlProgress<'a, Span<T>>
197        where F: Fn(StringPoint<'a>) -> XmlProgress<'a, T>
198    {
199        let (after, v) = try_parse!(f(pt));
200        let span = Span { value: v, offset: pt.offset };
201        peresil::Progress { status: peresil::Status::Success(span), point: after }
202    }
203
204    fn map<F, U>(self, f: F) -> Span<U>
205        where F: FnOnce(T) -> U
206    {
207        Span { value: f(self.value), offset: self.offset }
208    }
209}
210
211#[derive(Debug,Copy,Clone)]
212enum Reference<'a> {
213    EntityReference(Span<&'a str>),
214    DecimalCharReference(Span<&'a str>),
215    HexCharReference(Span<&'a str>),
216}
217
218/// Common reusable XML parsing methods
219pub trait XmlParseExt<'a> {
220    /// Parse XML whitespace
221    fn consume_space(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
222    /// Parse XML decimal characters
223    fn consume_decimal_chars(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
224    /// Parse an XML [NCName](http://www.w3.org/TR/REC-xml-names/#NT-NCName)
225    fn consume_ncname(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
226    /// Parse an XML [prefixed name](http://www.w3.org/TR/REC-xml-names/#NT-QName)
227    fn consume_prefixed_name(&self) -> peresil::Progress<StringPoint<'a>, PrefixedName<'a>, ()>;
228}
229
230impl<'a> XmlParseExt<'a> for StringPoint<'a> {
231    fn consume_space(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
232        self.consume_to(self.s.end_of_space())
233    }
234
235    fn consume_decimal_chars(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
236        self.consume_to(self.s.end_of_decimal_chars())
237    }
238
239    fn consume_ncname(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
240        self.consume_to(self.s.end_of_ncname())
241    }
242
243    fn consume_prefixed_name(&self) -> peresil::Progress<StringPoint<'a>, PrefixedName<'a>, ()> {
244        fn parse_local(xml: StringPoint) -> peresil::Progress<StringPoint, &str, ()> {
245            let (xml, _) = try_parse!(xml.consume_literal(":"));
246            xml.consume_ncname()
247        }
248
249        let (xml, prefix) = try_parse!(self.consume_ncname());
250        let (xml, local)  = parse_local(xml).optional(xml);
251
252        let name = match local {
253            Some(local) => PrefixedName::with_prefix(Some(prefix),local),
254            None        => PrefixedName::new(prefix),
255        };
256
257        peresil::Progress { point: xml, status: peresil::Status::Success(name) }
258    }
259}
260
261trait PrivateXmlParseExt<'a> {
262    fn consume_attribute_value(&self, quote: &str) -> XmlProgress<'a, &'a str>;
263    fn consume_name(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()>;
264    fn consume_hex_chars(&self) -> XmlProgress<'a, &'a str>;
265    fn consume_char_data(&self) -> XmlProgress<'a, &'a str>;
266    fn consume_cdata(&self) -> XmlProgress<'a, &'a str>;
267    fn consume_int_subset(&self) -> XmlProgress<'a, &'a str>;
268    fn consume_comment(&self) -> XmlProgress<'a, &'a str>;
269    fn consume_pi_value(&self) -> XmlProgress<'a, &'a str>;
270    fn consume_start_tag(&self) -> XmlProgress<'a, &'a str>;
271    fn consume_encoding(&self) -> XmlProgress<'a, &'a str>;
272}
273
274impl<'a> PrivateXmlParseExt<'a> for StringPoint<'a> {
275    fn consume_attribute_value(&self, quote: &str) -> XmlProgress<'a, &'a str> {
276        self.consume_to(self.s.end_of_attribute(quote)).map_err(|_| SpecificError::ExpectedAttributeValue)
277    }
278
279    fn consume_name(&self) -> peresil::Progress<StringPoint<'a>, &'a str, ()> {
280        self.consume_to(self.s.end_of_name())
281    }
282
283    fn consume_hex_chars(&self) -> XmlProgress<'a, &'a str> {
284        self.consume_to(self.s.end_of_hex_chars()).map_err(|_| SpecificError::ExpectedHexReferenceValue)
285    }
286
287    fn consume_char_data(&self) -> XmlProgress<'a, &'a str> {
288        self.consume_to(self.s.end_of_char_data()).map_err(|_| SpecificError::ExpectedCharacterData)
289    }
290
291    fn consume_cdata(&self) -> XmlProgress<'a, &'a str> {
292        self.consume_to(self.s.end_of_cdata()).map_err(|_| SpecificError::ExpectedCData)
293    }
294
295    fn consume_int_subset(&self) -> XmlProgress<'a, &'a str> {
296        self.consume_to(self.s.end_of_int_subset()).map_err(|_| SpecificError::ExpectedIntSubset)
297    }
298
299    fn consume_comment(&self) -> XmlProgress<'a, &'a str> {
300        self.consume_to(self.s.end_of_comment()).map_err(|_| SpecificError::ExpectedCommentBody)
301    }
302
303    fn consume_pi_value(&self) -> XmlProgress<'a, &'a str> {
304        self.consume_to(self.s.end_of_pi_value()).map_err(|_| SpecificError::ExpectedProcessingInstructionValue)
305    }
306
307    fn consume_start_tag(&self) -> XmlProgress<'a, &'a str> {
308        self.consume_to(self.s.end_of_start_tag()).map_err(|_| SpecificError::ExpectedElement)
309    }
310
311    fn consume_encoding(&self) -> XmlProgress<'a, &'a str> {
312        self.consume_to(self.s.end_of_encoding()).map_err(|_| SpecificError::ExpectedEncoding)
313    }
314}
315
316trait X<'a> {
317    fn expect_space(&self) -> XmlProgress<'a, &'a str>;
318    fn expect_literal(&self, s: &'static str) -> XmlProgress<'a, &'a str>;
319}
320
321impl<'a> X<'a> for StringPoint<'a> {
322    fn expect_space(&self) -> XmlProgress<'a, &'a str> {
323        self.consume_space().map_err(|_| SpecificError::ExpectedWhitespace)
324    }
325
326    fn expect_literal(&self, s: &'static str) -> XmlProgress<'a, &'a str> {
327        self.consume_literal(s).map_err(|_| SpecificError::Expected(s))
328    }
329}
330
331#[derive(Debug, Copy, Clone)]
332enum Token<'a> {
333    XmlDeclaration,
334    DocumentTypeDeclaration,
335    Comment(&'a str),
336    ProcessingInstruction(&'a str, Option<&'a str>),
337    Whitespace(&'a str),
338    ElementStart(Span<PrefixedName<'a>>),
339    ElementStartClose,
340    ElementSelfClose,
341    ElementClose(Span<PrefixedName<'a>>),
342    AttributeStart(Span<PrefixedName<'a>>, &'static str),
343    AttributeEnd,
344    LiteralAttributeValue(&'a str),
345    ReferenceAttributeValue(Reference<'a>),
346    CharData(&'a str),
347    CData(&'a str),
348    ContentReference(Reference<'a>),
349}
350
351#[derive(Debug, Copy, Clone)]
352enum State {
353    AtBeginning,
354    AfterDeclaration,
355    AfterElementStart(usize),
356    AfterAttributeStart(usize, &'static str),
357    Content(usize),
358    AfterMainElement,
359}
360
361#[derive(Debug)]
362struct PullParser<'a> {
363    pm: XmlMaster<'a>,
364    xml: StringPoint<'a>,
365    state: State,
366}
367
368impl<'a> PullParser<'a> {
369    fn new(xml: &str) -> PullParser {
370        PullParser {
371            pm: ParseMaster::new(),
372            xml: StringPoint::new(xml),
373            state: State::AtBeginning,
374        }
375    }
376}
377
378fn parse_comment<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
379    let (xml, _) = try_parse!(xml.consume_literal("<!--").map_err(|_| SpecificError::ExpectedComment));
380    let (xml, text) = try_parse!(xml.consume_comment());
381    let (xml, _) = try_parse!(xml.expect_literal("-->"));
382
383    success(Token::Comment(text), xml)
384}
385
386fn parse_one_quoted_value<'a, T, F>(xml: StringPoint<'a>, quote: &'static str, f: F)
387                                    -> XmlProgress<'a, T>
388    where F: FnMut(StringPoint<'a>) -> XmlProgress<'a, T>
389{
390    let mut f = f;
391    let (xml, _) = try_parse!(xml.consume_literal(quote).map_err(|_| SpecificError::ExpectedOpeningQuote(quote)));
392    let (xml, value) = try_parse!(f(xml));
393    let (xml, _) = try_parse!(xml.consume_literal(quote).map_err(|_| SpecificError::ExpectedClosingQuote(quote)));
394
395    success(value, xml)
396}
397
398fn parse_quoted_value<'a, T, F>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>, f: F) -> XmlProgress<'a, T>
399    where F: FnMut(&mut XmlMaster<'a>, StringPoint<'a>, &str) -> XmlProgress<'a, T>
400{
401    let mut f = f;
402    pm.alternate()
403        .one(|pm| parse_one_quoted_value(xml, "'",  |xml| f(pm, xml, "'")))
404        .one(|pm| parse_one_quoted_value(xml, "\"", |xml| f(pm, xml, "\"")))
405        .finish()
406}
407
408fn parse_eq(xml: StringPoint) -> XmlProgress<()> {
409    let (xml, _) = xml.consume_space().optional(xml);
410    let (xml, _) = try_parse!(xml.expect_literal("="));
411    let (xml, _) = xml.consume_space().optional(xml);
412
413    success((), xml)
414}
415
416fn parse_version_info<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, &'a str> {
417    fn version_num(xml: StringPoint) -> peresil::Progress<StringPoint, &str, ()> {
418        let start_point = xml;
419
420        let (xml, _) = try_parse!(xml.consume_literal("1."));
421        let (xml, _) = try_parse!(xml.consume_decimal_chars());
422
423        peresil::Progress::success(xml, start_point.to(xml))
424    }
425
426    let (xml, _) = try_parse!(xml.expect_space());
427    let (xml, _) = try_parse!(xml.expect_literal("version"));
428    let (xml, _) = try_parse!(parse_eq(xml));
429    let (xml, version) = try_parse!(
430        parse_quoted_value(pm, xml, |_, xml, _| version_num(xml).map_err(|_| SpecificError::ExpectedVersionNumber))
431            );
432
433    success(version, xml)
434}
435
436fn parse_encoding_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
437                                  -> XmlProgress<'a, &'a str>
438{
439    let (xml, _) = try_parse!(xml.expect_space());
440    let (xml, _) = try_parse!(xml.expect_literal("encoding"));
441    let (xml, _) = try_parse!(parse_eq(xml));
442    let (xml, encoding) = try_parse!(
443        parse_quoted_value(pm, xml, |_, xml, _| xml.consume_encoding())
444            );
445
446    success(encoding, xml)
447}
448
449fn parse_standalone_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
450                                    -> XmlProgress<'a, &'a str>
451{
452    let (xml, _) = try_parse!(xml.expect_space());
453    let (xml, _) = try_parse!(xml.expect_literal("standalone"));
454    let (xml, _) = try_parse!(parse_eq(xml));
455    let (xml, standalone) = try_parse!(
456        parse_quoted_value(pm, xml, |pm, xml, _| {
457            pm.alternate()
458                .one(|_| xml.expect_literal("yes"))
459                .one(|_| xml.expect_literal("no"))
460                .finish()
461                .map_err(|_| SpecificError::ExpectedYesNo)
462        })
463            );
464
465    success(standalone, xml)
466}
467
468fn parse_xml_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
469    let (xml, _) = try_parse!(xml.expect_literal("<?xml"));
470    let (xml, _version) = try_parse!(parse_version_info(pm, xml));
471    let (xml, _encoding) = try_parse!(pm.optional(xml, |pm, xml| {
472        parse_encoding_declaration(pm, xml)
473    }));
474    let (xml, _standalone) = try_parse!(pm.optional(xml, |pm, xml| {
475        parse_standalone_declaration(pm, xml)
476    }));
477    let (xml, _) = xml.consume_space().optional(xml);
478    let (xml, _) = try_parse!(xml.expect_literal("?>"));
479
480    success(Token::XmlDeclaration, xml)
481}
482
483/* only the SYSTEM variant */
484fn parse_external_id<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
485                         -> XmlProgress<'a, &'a str>
486{
487    let (xml, _) = try_parse!(xml.expect_space());
488    let (xml, _) = try_parse!(xml.expect_literal("SYSTEM"));
489    let (xml, _) = try_parse!(xml.expect_space());
490    let (xml, external_id) = try_parse!(
491        parse_quoted_value(pm, xml, |_, xml, quote|
492            xml.consume_attribute_value(quote).map_err(|_| SpecificError::ExpectedSystemLiteral)
493        )
494    );
495
496    success(external_id, xml)
497}
498
499fn parse_int_subset<'a>(_pm: &mut XmlMaster<'a>, xml: StringPoint<'a>)
500                          -> XmlProgress<'a, &'a str>
501{
502    let (xml, _) = try_parse!(xml.expect_literal("["));
503    let (xml, _) = xml.consume_space().optional(xml);
504    let (xml, elements) = try_parse!(
505        xml.consume_int_subset().map_err(|_| SpecificError::ExpectedIntSubset)
506    );
507    let (xml, _) = xml.consume_space().optional(xml);
508    let (xml, _) = try_parse!(xml.expect_literal("]"));
509    let (xml, _) = xml.consume_space().optional(xml);
510
511    success(elements, xml)
512}
513
514fn parse_document_type_declaration<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
515    let (xml, _) = try_parse!(xml.expect_literal("<!DOCTYPE"));
516    let (xml, _) = try_parse!(xml.expect_space());
517    let (xml, _type_name) = try_parse!(
518        xml.consume_name().map_err(|_| SpecificError::ExpectedDocumentTypeName)
519    );
520    let (xml, _id) = try_parse!(pm.optional(xml, |p, x| parse_external_id(p, x)));
521    let (xml, _) = xml.consume_space().optional(xml);
522    let (xml, _int_subset) = try_parse!(pm.optional(xml, |p, x| parse_int_subset(p, x)));
523    let (xml, _) = try_parse!(xml.expect_literal(">"));
524
525    success(Token::DocumentTypeDeclaration, xml)
526}
527
528fn parse_pi_value(xml: StringPoint) -> XmlProgress<&str> {
529    let (xml, _) = try_parse!(xml.expect_space());
530    xml.consume_pi_value()
531}
532
533fn parse_pi<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
534    let (xml, _) = try_parse!(xml.consume_literal("<?").map_err(|_| SpecificError::ExpectedProcessingInstruction));
535    let target_xml = xml;
536    let (xml, target) = try_parse!(xml.consume_name().map_err(|_| SpecificError::ExpectedProcessingInstructionTarget));
537    let (xml, value) = parse_pi_value(xml).optional(xml);
538    let (xml, _) = try_parse!(xml.expect_literal("?>"));
539
540    if target.eq_ignore_ascii_case("xml") {
541        return peresil::Progress::failure(target_xml, SpecificError::InvalidProcessingInstructionTarget);
542    }
543
544    success(Token::ProcessingInstruction(target, value), xml)
545}
546
547fn parse_element_start(xml: StringPoint) -> XmlProgress<Token> {
548    let (xml, _) = try_parse!(xml.consume_start_tag());
549    let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_prefixed_name().map_err(|_| SpecificError::ExpectedElementName)));
550
551    success(Token::ElementStart(name), xml)
552}
553
554fn parse_element_start_close(xml: StringPoint) -> XmlProgress<Token> {
555    let (xml, _) = xml.expect_space().optional(xml);
556
557    xml.consume_literal(">")
558        .map(|_| Token::ElementStartClose)
559        .map_err(|_| SpecificError::ExpectedElementEnd)
560}
561
562fn parse_element_self_close(xml: StringPoint) -> XmlProgress<Token> {
563    let (xml, _) = xml.expect_space().optional(xml);
564
565    xml.consume_literal("/>")
566        .map(|_| Token::ElementSelfClose)
567        .map_err(|_| SpecificError::ExpectedElementSelfClosed)
568}
569
570fn parse_element_close(xml: StringPoint) -> XmlProgress<Token> {
571    let (xml, _) = try_parse!(xml.expect_literal("</"));
572
573    let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_prefixed_name().map_err(|_| SpecificError::ExpectedElementName)));
574
575    let (xml, _) = xml.consume_space().optional(xml);
576    let (xml, _) = try_parse!(xml.expect_literal(">"));
577
578    success(Token::ElementClose(name), xml)
579}
580
581const QUOT: &'static str = r#"""#;
582const APOS: &'static str = r#"'"#;
583
584fn parse_attribute_start<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
585    let (xml, _) = try_parse!(xml.expect_space());
586
587    let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_prefixed_name().map_err(|_| SpecificError::ExpectedAttribute)));
588
589    let (xml, _) = try_parse!(parse_eq(xml));
590
591    let (xml, q) = try_parse!(
592        pm.alternate()
593            .one(|_| xml.expect_literal(QUOT).map_err(|_| SpecificError::ExpectedOpeningQuote(QUOT)))
594            .one(|_| xml.expect_literal(APOS).map_err(|_| SpecificError::ExpectedOpeningQuote(APOS)))
595            .finish());
596
597    let q = if q == QUOT { QUOT } else { APOS };
598
599    success(Token::AttributeStart(name, q), xml)
600}
601
602fn parse_attribute_end<'a>(xml: StringPoint<'a>, quote: &'static str) -> XmlProgress<'a, Token<'a>> {
603    xml.consume_literal(quote)
604        .map(|_| Token::AttributeEnd)
605        .map_err(|_| SpecificError::ExpectedClosingQuote(quote))
606}
607
608fn parse_attribute_literal<'a>(xml: StringPoint<'a>, quote: &str) -> XmlProgress<'a, Token<'a>> {
609    let (xml, val) = try_parse!(xml.consume_attribute_value(quote));
610
611    success(Token::LiteralAttributeValue(val), xml)
612}
613
614fn parse_entity_ref(xml: StringPoint) -> XmlProgress<Reference> {
615    let (xml, _) = try_parse!(xml.consume_literal("&").map_err(|_| SpecificError::ExpectedNamedReference));
616    let (xml, name) = try_parse!(Span::parse(xml, |xml| xml.consume_name().map_err(|_| SpecificError::ExpectedNamedReferenceValue)));
617    let (xml, _) = try_parse!(xml.expect_literal(";"));
618
619    success(EntityReference(name), xml)
620}
621
622fn parse_decimal_char_ref(xml: StringPoint) -> XmlProgress<Reference> {
623    let (xml, _) = try_parse!(xml.consume_literal("&#").map_err(|_| SpecificError::ExpectedDecimalReference));
624    let (xml, dec) = try_parse!(Span::parse(xml, |xml| xml.consume_decimal_chars().map_err(|_| SpecificError::ExpectedDecimalReferenceValue)));
625    let (xml, _) = try_parse!(xml.expect_literal(";"));
626
627    success(DecimalCharReference(dec), xml)
628}
629
630fn parse_hex_char_ref(xml: StringPoint) -> XmlProgress<Reference> {
631    let (xml, _) = try_parse!(xml.consume_literal("&#x").map_err(|_| SpecificError::ExpectedHexReference));
632    let (xml, hex) = try_parse!(Span::parse(xml, |xml| xml.consume_hex_chars()));
633    let (xml, _) = try_parse!(xml.expect_literal(";"));
634
635    success(HexCharReference(hex), xml)
636}
637
638fn parse_reference<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Reference<'a>> {
639    pm.alternate()
640        .one(|_| parse_entity_ref(xml))
641        .one(|_| parse_decimal_char_ref(xml))
642        .one(|_| parse_hex_char_ref(xml))
643        .finish()
644}
645
646fn parse_attribute_reference<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
647    let (xml, val) = try_parse!(parse_reference(pm, xml));
648
649    success(Token::ReferenceAttributeValue(val), xml)
650}
651
652fn parse_char_data<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
653    xml.consume_char_data()
654        .map(Token::CharData)
655}
656
657fn parse_cdata<'a>(xml: StringPoint<'a>) -> XmlProgress<'a, Token> {
658    let (xml, _) = try_parse!(xml.expect_literal("<![CDATA["));
659    let (xml, text) = try_parse!(xml.consume_cdata());
660    let (xml, _) = try_parse!(xml.expect_literal("]]>"));
661
662    success(Token::CData(text), xml)
663}
664
665fn parse_content_reference<'a>(pm: &mut XmlMaster<'a>, xml: StringPoint<'a>) -> XmlProgress<'a, Token<'a>> {
666    let (xml, r) = try_parse!(parse_reference(pm, xml));
667    success(Token::ContentReference(r), xml)
668}
669
670impl<'a> Iterator for PullParser<'a> {
671    type Item = Result<Token<'a>, (usize, Vec<SpecificError>)>;
672
673    fn next(&mut self) -> Option<Self::Item> {
674        let pm = &mut self.pm;
675        let xml = self.xml;
676
677        let r = match self.state {
678            State::AtBeginning => {
679                pm.alternate()
680                    .one(|pm| parse_xml_declaration(pm, xml))
681                    .one(|_| parse_element_start(xml))
682                    .one(|_| xml.expect_space().map(Token::Whitespace))
683                    .one(|_| parse_comment(xml))
684                    .one(|_| parse_pi(xml))
685                    .finish()
686            },
687
688            State::AfterDeclaration => {
689                pm.alternate()
690                    .one(|pm| parse_document_type_declaration(pm, xml))
691                    .one(|_| parse_element_start(xml))
692                    .one(|_| xml.expect_space().map(Token::Whitespace))
693                    .one(|_| parse_comment(xml))
694                    .one(|_| parse_pi(xml))
695                    .finish()
696            },
697
698            State::AfterElementStart(..) => {
699                pm.alternate()
700                    .one(|pm| parse_attribute_start(pm, xml))
701                    .one(|_| parse_element_start_close(xml))
702                    .one(|_| parse_element_self_close(xml))
703                    .finish()
704            },
705
706            State::AfterAttributeStart(_, quote) => {
707                pm.alternate()
708                    .one(|_| parse_attribute_literal(xml, quote))
709                    .one(|pm| parse_attribute_reference(pm, xml))
710                    .one(|_| parse_attribute_end(xml, quote))
711                    .finish()
712            },
713
714            State::Content(..) => {
715                pm.alternate()
716                    .one(|_| parse_element_start(xml))
717                    .one(|_| parse_element_close(xml))
718                    .one(|_| parse_char_data(xml))
719                    .one(|_| parse_cdata(xml))
720                    .one(|pm| parse_content_reference(pm, xml))
721                    .one(|_| parse_comment(xml))
722                    .one(|_| parse_pi(xml))
723                    .finish()
724            },
725
726            State::AfterMainElement => {
727                if xml.is_empty() {
728                    return None;
729                }
730
731                pm.alternate()
732                    .one(|_| parse_comment(xml))
733                    .one(|_| parse_pi(xml))
734                    .one(|_| xml.expect_space().map(Token::Whitespace))
735                    .finish()
736            },
737        };
738
739        let (r, pt) = match pm.finish(r) {
740            peresil::Progress { status: peresil::Status::Success(t), point } => (t, point),
741            peresil::Progress { status: peresil::Status::Failure(e), point } => {
742                return Some(Err((point.offset, e)));
743            },
744        };
745
746        if pt == xml {
747            return None;
748        }
749
750        let next_state = match (self.state, r) {
751            (State::AtBeginning, Token::XmlDeclaration) |
752            (State::AtBeginning, Token::ProcessingInstruction(..)) |
753            (State::AtBeginning, Token::Comment(..)) |
754            (State::AtBeginning, Token::Whitespace(..)) => {
755                State::AfterDeclaration
756            },
757            (State::AtBeginning, Token::ElementStart(..)) => {
758                State::AfterElementStart(0)
759            },
760
761            (State::AfterDeclaration, Token::ProcessingInstruction(..)) |
762            (State::AfterDeclaration, Token::Comment(..)) |
763            (State::AfterDeclaration, Token::Whitespace(..)) => {
764                State::AfterDeclaration
765            },
766            (State::AfterDeclaration, Token::DocumentTypeDeclaration) => {
767                State::AfterDeclaration
768            },
769            (State::AfterDeclaration, Token::ElementStart(..)) => {
770                State::AfterElementStart(0)
771            },
772
773            (State::AfterElementStart(d), Token::AttributeStart(_, q)) => {
774                State::AfterAttributeStart(d, q)
775            },
776            (State::AfterElementStart(d), Token::ElementStartClose) => {
777                State::Content(d)
778            },
779            (State::AfterElementStart(0), Token::ElementSelfClose) => {
780                State::AfterMainElement
781            },
782            (State::AfterElementStart(d), Token::ElementSelfClose) => {
783                State::Content(d - 1)
784            },
785
786            (State::AfterAttributeStart(d, q), Token::LiteralAttributeValue(..)) |
787            (State::AfterAttributeStart(d, q), Token::ReferenceAttributeValue(..)) => {
788                State::AfterAttributeStart(d, q)
789            },
790            (State::AfterAttributeStart(d, _), Token::AttributeEnd) => {
791                State::AfterElementStart(d)
792            },
793
794            (State::Content(d), Token::CharData(..)) |
795            (State::Content(d), Token::CData(..)) |
796            (State::Content(d), Token::ContentReference(..)) |
797            (State::Content(d), Token::Comment(..)) |
798            (State::Content(d), Token::ProcessingInstruction(..)) => {
799                State::Content(d)
800            },
801            (State::Content(d), Token::ElementStart(..)) => {
802                State::AfterElementStart(d + 1)
803            }
804            (State::Content(0), Token::ElementClose(..)) => {
805                State::AfterMainElement
806            }
807            (State::Content(d), Token::ElementClose(..)) => {
808                State::Content(d - 1)
809            }
810
811            (State::AfterMainElement, Token::Comment(..)) |
812            (State::AfterMainElement, Token::ProcessingInstruction(..)) |
813            (State::AfterMainElement, Token::Whitespace(..)) => {
814                State::AfterMainElement
815            }
816
817            (s, t) => {
818                unreachable!("Transitioning from {:?} to {:?} is impossible", s, t);
819            },
820        };
821
822        self.state = next_state;
823        self.xml = pt;
824
825        Some(Ok(r))
826    }
827}
828
829struct DomBuilder<'d> {
830    doc: dom::Document<'d>,
831    elements: Vec<dom::Element<'d>>,
832    element_names: Vec<Span<PrefixedName<'d>>>,
833    attributes: Vec<DeferredAttribute<'d>>,
834    seen_top_element: bool,
835}
836
837impl<'d> DomBuilder<'d> {
838    fn new(doc: dom::Document<'d>) -> DomBuilder<'d> {
839        DomBuilder {
840            doc: doc,
841            elements: vec![],
842            element_names: Vec::new(),
843            attributes: Vec::new(),
844            seen_top_element: false,
845        }
846    }
847
848    fn append_to_either<T>(&self, child: T)
849        where T: Into<dom::ChildOfRoot<'d>>
850    {
851        match self.elements.last() {
852            None => self.doc.root().append_child(child),
853            Some(parent) => parent.append_child(child.into()),
854        }
855    }
856
857    fn default_namespace_uri(&self) -> Option<&str> {
858        self.elements.last().and_then(|e| e.recursive_default_namespace_uri())
859    }
860
861    fn namespace_uri_for_prefix(&self, prefix: &str) -> Option<&str> {
862        self.elements.last().and_then(|e| e.namespace_uri_for_prefix(prefix))
863    }
864
865    fn finish_opening_tag(&mut self) -> DomBuilderResult<()> {
866        let deferred_element = self.element_names.last().expect("Unknown element name");
867        let attributes = DeferredAttributes::new(replace(&mut self.attributes, Vec::new()));
868
869        try!(attributes.check_duplicates());
870        let default_namespace = try!(attributes.default_namespace());
871
872        let mut new_prefix_mappings = HashMap::new();
873        for ns in attributes.namespaces() {
874            let value = try!(AttributeValueBuilder::convert(&ns.values));
875
876            if value.is_empty() {
877                return Err(ns.name.map(|_| SpecificError::EmptyNamespace));
878            }
879
880            new_prefix_mappings.insert(ns.name.value.local_part, value);
881        }
882        let new_prefix_mappings = new_prefix_mappings;
883
884        let element_name = &deferred_element.value;
885
886        let element = if let Some(prefix) = element_name.prefix {
887            let ns_uri = new_prefix_mappings.get(prefix).map(|p| &p[..]);
888            let ns_uri = ns_uri.or_else(|| self.namespace_uri_for_prefix(prefix));
889
890            if let Some(ns_uri) = ns_uri {
891                let element = self.doc.create_element((ns_uri, element_name.local_part));
892                element.set_preferred_prefix(Some(prefix));
893                element
894            } else {
895                return Err(deferred_element.map(|_| SpecificError::UnknownNamespacePrefix));
896            }
897        } else if let Some(ns_uri) = default_namespace {
898            if ns_uri.is_empty() {
899                let element = self.doc.create_element(element_name.local_part);
900                element.set_default_namespace_uri(None);
901                element
902            } else {
903                let element = self.doc.create_element((&ns_uri[..], element_name.local_part));
904                element.set_default_namespace_uri(Some(&ns_uri));
905                element
906            }
907        } else {
908            let ns_uri = self.default_namespace_uri();
909            let name = QName::with_namespace_uri(ns_uri, element_name.local_part);
910            self.doc.create_element(name)
911        };
912
913        for (prefix, ns_uri) in &new_prefix_mappings {
914            element.register_prefix(*prefix, ns_uri);
915        }
916
917        if !self.seen_top_element {
918            self.seen_top_element = true;
919            element.register_prefix(::XML_NS_PREFIX, ::XML_NS_URI);
920        }
921
922        self.append_to_either(element);
923        self.elements.push(element);
924
925        let mut builder = AttributeValueBuilder::new();
926
927        for attribute in attributes.attributes() {
928            let name = &attribute.name.value;
929
930            builder.clear();
931            try!(builder.ingest(&attribute.values));
932
933            if let Some(prefix) = name.prefix {
934                let ns_uri = new_prefix_mappings.get(prefix).map(|p| &p[..]);
935                let ns_uri = ns_uri.or_else(|| self.namespace_uri_for_prefix(prefix));
936
937                if let Some(ns_uri) = ns_uri {
938                    let attr = element.set_attribute_value((ns_uri, name.local_part), &builder);
939                    attr.set_preferred_prefix(Some(prefix));
940                } else {
941                    return Err(attribute.name.map(|_| SpecificError::UnknownNamespacePrefix))
942                }
943            } else {
944                element.set_attribute_value(name.local_part, &builder);
945            }
946        }
947
948        Ok(())
949    }
950
951    fn add_attribute_value(&mut self, v: AttributeValue<'d>) {
952        let a = self.attributes.last_mut().expect("Cannot add attribute value without an attribute");
953        a.values.push(v);
954    }
955
956    fn add_text_data(&self, text: &str) {
957        let e = self.elements.last().expect("Cannot add text node without a parent");
958        let t = self.doc.create_text(text);
959        e.append_child(t);
960    }
961
962    fn has_unclosed_elements(&self) -> bool {
963        !self.elements.is_empty()
964    }
965
966    fn consume(&mut self, token: Token<'d>) -> DomBuilderResult<()> {
967        use self::Token::*;
968
969        match token {
970            XmlDeclaration => {},
971
972            DocumentTypeDeclaration => {},
973
974            ElementStart(n) => {
975                self.element_names.push(n);
976            },
977
978            ElementStartClose => {
979                try!(self.finish_opening_tag());
980            },
981
982            ElementSelfClose => {
983                try!(self.finish_opening_tag());
984
985                self.element_names.pop();
986                self.elements.pop();
987            },
988
989            ElementClose(n) => {
990                let open_name = self.element_names.pop().expect("No open element");
991                self.elements.pop();
992
993                if n.value != open_name.value {
994                    return Err(n.map(|_| SpecificError::MismatchedElementEndName));
995                }
996            },
997
998            AttributeStart(n, _) => {
999                let attr = DeferredAttribute { name: n, values: Vec::new() };
1000                self.attributes.push(attr);
1001            },
1002
1003            LiteralAttributeValue(v) => {
1004                self.add_attribute_value(AttributeValue::LiteralAttributeValue(v));
1005            },
1006
1007            ReferenceAttributeValue(v) => {
1008                self.add_attribute_value(AttributeValue::ReferenceAttributeValue(v));
1009            },
1010
1011            AttributeEnd => {},
1012
1013            Whitespace(..) => {},
1014
1015            CharData(t) | CData(t) => {
1016                self.add_text_data(t)
1017            },
1018
1019            ContentReference(t) => {
1020                try!(decode_reference(t, |s| self.add_text_data(s)));
1021            },
1022
1023            Comment(c) => {
1024                let c = self.doc.create_comment(c);
1025                self.append_to_either(c);
1026            },
1027
1028            ProcessingInstruction(t, v) => {
1029                let pi = self.doc.create_processing_instruction(t, v);
1030                self.append_to_either(pi);
1031            },
1032        };
1033
1034        Ok(())
1035    }
1036}
1037
1038#[derive(Debug, PartialEq, Eq)]
1039pub struct Error {
1040    location: usize,
1041    errors: BTreeSet<SpecificError>,
1042}
1043
1044impl Error {
1045    fn new(location: usize, error: SpecificError) -> Self {
1046        let mut errors = BTreeSet::new();
1047        errors.insert(error);
1048        Error { location, errors }
1049    }
1050
1051    pub fn location(&self) -> usize { self.location }
1052}
1053
1054impl From<(usize, Vec<SpecificError>)> for Error {
1055    fn from(other: (usize, Vec<SpecificError>)) -> Self {
1056        let (location, errors) = other;
1057        let errors = errors.into_iter().collect();
1058        Error { location, errors }
1059    }
1060}
1061
1062impl From<Span<SpecificError>> for Error {
1063    fn from(other: Span<SpecificError>) -> Self {
1064        Self::new(other.offset, other.value)
1065    }
1066}
1067
1068impl fmt::Display for Error {
1069    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1070        write!(f, "XML parsing error at {}: {:?}", self.location, self.errors)
1071    }
1072}
1073
1074impl error::Error for Error {
1075    fn description(&self) -> &str {
1076        "Unable to parse XML"
1077    }
1078}
1079
1080/// Parses a string into a DOM. On failure, the location of the
1081/// parsing failure and all possible failures will be returned.
1082pub fn parse(xml: &str) -> Result<super::Package, Error> {
1083    let parser = PullParser::new(xml);
1084    let package = super::Package::new();
1085
1086    {
1087        let doc = package.as_document();
1088        let mut builder = DomBuilder::new(doc);
1089
1090        for token in parser {
1091            let token = try!(token);
1092            try!(builder.consume(token));
1093        }
1094
1095        if builder.has_unclosed_elements() {
1096            return Err(Error::new(xml.len(), SpecificError::UnclosedElement));
1097        }
1098    }
1099
1100    Ok(package)
1101}
1102
1103type DomBuilderResult<T> = Result<T, Span<SpecificError>>;
1104
1105fn decode_reference<F>(ref_data: Reference, cb: F) -> DomBuilderResult<()>
1106    where F: FnOnce(&str)
1107{
1108    match ref_data {
1109        DecimalCharReference(span) => {
1110            u32::from_str_radix(span.value, 10).ok()
1111                .and_then(char::from_u32)
1112                .ok_or(span.map(|_| SpecificError::InvalidDecimalReference))
1113                .and_then(|c| {
1114                    let s: String = iter::repeat(c).take(1).collect();
1115                    cb(&s);
1116                    Ok(())
1117                })
1118        },
1119        HexCharReference(span) => {
1120            u32::from_str_radix(span.value, 16).ok()
1121                .and_then(char::from_u32)
1122                .ok_or(span.map(|_| SpecificError::InvalidHexReference))
1123                .and_then(|c| {
1124                    let s: String = iter::repeat(c).take(1).collect();
1125                    cb(&s);
1126                    Ok(())
1127                })
1128        },
1129        EntityReference(span) => {
1130            let s = match span.value {
1131                "amp"  => "&",
1132                "lt"   => "<",
1133                "gt"   => ">",
1134                "apos" => "'",
1135                "quot" => "\"",
1136                _      => return Err(span.map(|_| SpecificError::UnknownNamedReference)),
1137            };
1138            cb(s);
1139            Ok(())
1140        }
1141    }
1142}
1143
1144#[derive(Debug,Copy,Clone)]
1145enum AttributeValue<'a> {
1146    ReferenceAttributeValue(Reference<'a>),
1147    LiteralAttributeValue(&'a str),
1148}
1149
1150struct AttributeValueBuilder {
1151    value: String,
1152}
1153
1154impl AttributeValueBuilder {
1155    fn convert(values: &[AttributeValue]) -> DomBuilderResult<String> {
1156        let mut builder = AttributeValueBuilder::new();
1157        try!(builder.ingest(values));
1158        Ok(builder.implode())
1159    }
1160
1161    fn new() -> AttributeValueBuilder {
1162        AttributeValueBuilder {
1163            value: String::new(),
1164        }
1165    }
1166
1167    fn ingest(&mut self, values: &[AttributeValue]) -> DomBuilderResult<()> {
1168        use self::AttributeValue::*;
1169
1170        for value in values.iter() {
1171            match *value {
1172                LiteralAttributeValue(v) => self.value.push_str(v),
1173                ReferenceAttributeValue(r) => try!(decode_reference(r, |s| self.value.push_str(s))),
1174            }
1175        }
1176
1177        Ok(())
1178    }
1179
1180    fn clear(&mut self) {
1181        self.value.clear();
1182    }
1183
1184    fn implode(self) -> String {
1185        self.value
1186    }
1187}
1188
1189impl Deref for AttributeValueBuilder {
1190    type Target = str;
1191
1192    fn deref(&self) -> &str {
1193        &self.value
1194    }
1195}
1196
1197#[derive(Debug)]
1198struct DeferredAttribute<'d> {
1199    name: Span<PrefixedName<'d>>,
1200    values: Vec<AttributeValue<'d>>,
1201}
1202
1203struct DeferredAttributes<'a> {
1204    attributes: Vec<DeferredAttribute<'a>>,
1205    namespaces: Vec<DeferredAttribute<'a>>,
1206    default_namespaces: Vec<DeferredAttribute<'a>>,
1207}
1208
1209impl<'a> DeferredAttributes<'a> {
1210    fn new(attributes: Vec<DeferredAttribute<'a>>) -> DeferredAttributes<'a> {
1211        let (mut namespaces, attributes): (Vec<_>, Vec<_>) =
1212            attributes.into_iter().partition(|attr| attr.name.value.prefix == Some("xmlns"));
1213
1214        let (mut default_namespaces, mut attributes): (Vec<_>, Vec<_>) =
1215            attributes.into_iter().partition(|attr| attr.name.value.local_part == "xmlns");
1216
1217        fn sort_by_name(a: &DeferredAttribute, b: &DeferredAttribute) -> ::std::cmp::Ordering {
1218            a.name.value.cmp(&b.name.value)
1219        }
1220
1221        attributes.sort_by(sort_by_name);
1222        namespaces.sort_by(sort_by_name);
1223        default_namespaces.sort_by(sort_by_name);
1224
1225        DeferredAttributes {
1226            attributes: attributes,
1227            namespaces: namespaces,
1228            default_namespaces: default_namespaces,
1229        }
1230    }
1231
1232    fn check_duplicates(&self) -> DomBuilderResult<()> {
1233        for w in self.attributes.windows(2) {
1234            if w[0].name.value == w[1].name.value {
1235                return Err(w[1].name.map(|_| SpecificError::DuplicateAttribute));
1236            }
1237        }
1238
1239        for w in self.namespaces.windows(2) {
1240            if w[0].name.value == w[1].name.value {
1241                return Err(w[1].name.map(|_| SpecificError::RedefinedNamespace));
1242            }
1243        }
1244
1245        Ok(())
1246    }
1247
1248    fn attributes(&self) -> &[DeferredAttribute<'a>] {
1249        &self.attributes
1250    }
1251
1252    fn namespaces(&self) -> &[DeferredAttribute<'a>] {
1253        &self.namespaces
1254    }
1255
1256    fn default_namespace(&self) -> DomBuilderResult<Option<String>> {
1257        match self.default_namespaces.len() {
1258            0 => Ok(None),
1259            1 => {
1260                let ns = &self.default_namespaces[0];
1261                let value = try!(AttributeValueBuilder::convert(&ns.values));
1262                Ok(Some(value))
1263            },
1264            _ => {
1265                let last_namespace = self.default_namespaces.last().unwrap();
1266                Err(last_namespace.name.map(|_| SpecificError::RedefinedDefaultNamespace))
1267            },
1268        }
1269    }
1270}
1271
1272#[cfg(test)]
1273mod test {
1274    use super::*;
1275    use ::{dom, Package, QName};
1276
1277    macro_rules! assert_qname_eq(
1278        ($l:expr, $r:expr) => (assert_eq!(Into::<QName>::into($l), $r.into()));
1279    );
1280
1281    fn full_parse(xml: &str) -> Result<Package, Error> {
1282        super::parse(xml)
1283    }
1284
1285    fn quick_parse(xml: &str) -> Package {
1286        full_parse(xml).expect("Failed to parse the XML string")
1287    }
1288
1289    fn top<'d>(doc: &'d dom::Document<'d>) -> dom::Element<'d> {
1290        doc.root().children()[0].element().unwrap()
1291    }
1292
1293    #[test]
1294    fn a_document_with_a_prolog() {
1295        let package = quick_parse("<?xml version='1.0' ?><hello />");
1296        let doc = package.as_document();
1297        let top = top(&doc);
1298
1299        assert_qname_eq!(top.name(), "hello");
1300    }
1301
1302    #[test]
1303    fn a_document_with_a_prolog_with_double_quotes() {
1304        let package = quick_parse("<?xml version=\"1.0\" ?><hello />");
1305        let doc = package.as_document();
1306        let top = top(&doc);
1307
1308        assert_qname_eq!(top.name(), "hello");
1309    }
1310
1311    #[test]
1312    fn a_prolog_with_an_encoding() {
1313        let package = quick_parse("<?xml version='1.0' encoding='UTF-8' ?><hello />");
1314        let doc = package.as_document();
1315        let top = top(&doc);
1316
1317        assert_qname_eq!(top.name(), "hello");
1318    }
1319
1320    #[test]
1321    fn a_non_standalone_prolog() {
1322        let package = quick_parse("<?xml version='1.0' standalone='no'?><hello/>");
1323        let doc = package.as_document();
1324        let top = top(&doc);
1325
1326        assert_qname_eq!(top.name(), "hello");
1327    }
1328
1329    #[test]
1330    fn a_complete_prolog() {
1331        let package = quick_parse("<?xml version='1.0' encoding='UTF-8' standalone='yes'?><hello/>");
1332        let doc = package.as_document();
1333        let top = top(&doc);
1334
1335        assert_qname_eq!(top.name(), "hello");
1336    }
1337
1338    #[test]
1339    fn a_prolog_with_a_doc_type_declaration_external_id() {
1340        let package = quick_parse(r#"<?xml version='1.0'?>
1341        <!DOCTYPE doc SYSTEM "http://example.com/doc.dtd">
1342        <hello/>"#);
1343        let doc = package.as_document();
1344        let top = top(&doc);
1345
1346        assert_qname_eq!(top.name(), "hello");
1347    }
1348
1349    #[test]
1350    fn a_prolog_with_a_doc_type_declaration_int_subset() {
1351        let package = quick_parse(r#"<?xml version="1.0"?>
1352            <!DOCTYPE note [
1353            <!ELEMENT note (to,from,heading,body)>
1354            <!ELEMENT to (#PCDATA)>
1355            <!ELEMENT from (#PCDATA)>
1356            <!ELEMENT heading (#PCDATA)>
1357            <!ELEMENT body (#PCDATA)>
1358            ]>
1359            <note>
1360            <to>Tove</to>
1361            <from>Jani</from>
1362            <heading>Reminder</heading>
1363            <body>Don't forget me this weekend</body>
1364            </note>
1365        "#);
1366        let doc = package.as_document();
1367        let top = top(&doc);
1368
1369        assert_qname_eq!(top.name(), "note");
1370    }
1371
1372    #[test]
1373    fn a_prolog_with_a_doc_type_declaration_int_subset_trailing_ws() {
1374        let package = quick_parse(r#"<?xml version="1.0"?>
1375            <!DOCTYPE note
1376                [
1377                    <!ELEMENT note (to,from,heading,body)>
1378                    <!ELEMENT to (#PCDATA)>
1379                    <!ELEMENT from (#PCDATA)>
1380                    <!ELEMENT heading (#PCDATA)>
1381                    <!ELEMENT body (#PCDATA)>
1382                ]
1383
1384            >
1385            <note>
1386            <to>Tove</to>
1387            <from>Jani</from>
1388            <heading>Reminder</heading>
1389            <body>Don't forget me this weekend</body>
1390            </note>
1391        "#);
1392        let doc = package.as_document();
1393        let top = top(&doc);
1394
1395        assert_qname_eq!(top.name(), "note");
1396    }
1397
1398    #[test]
1399    fn a_prolog_with_a_doc_type_declaration_zero_def() {
1400        let package = quick_parse("<?xml version='1.0'?>
1401        <!DOCTYPE doc>
1402        <hello/>");
1403        let doc = package.as_document();
1404        let top = top(&doc);
1405
1406        assert_qname_eq!(top.name(), "hello");
1407    }
1408
1409    #[test]
1410    fn a_prolog_with_a_doc_type_declaration_zero_def_trailing_ws() {
1411        let package = quick_parse("<?xml version='1.0'?>
1412        <!DOCTYPE doc  >
1413        <hello/>");
1414        let doc = package.as_document();
1415        let top = top(&doc);
1416
1417        assert_qname_eq!(top.name(), "hello");
1418    }
1419
1420    #[test]
1421    fn a_prolog_with_a_doc_type_declaration_both_int_subset_and_external_id() {
1422        let package = quick_parse(r#"<?xml version='1.0'?>
1423        <!DOCTYPE doc SYSTEM "http://example.com/doc.dtd" [
1424        <!ELEMENT hello (#PCDATA)>
1425        ]>
1426        <hello/>"#);
1427        let doc = package.as_document();
1428        let top = top(&doc);
1429
1430        assert_qname_eq!(top.name(), "hello");
1431    }
1432
1433    #[test]
1434    fn a_prolog_with_a_doc_type_declaration_both_int_subset_and_external_id_trailing_ws() {
1435        let package = quick_parse(r#"<?xml version='1.0'?>
1436        <!DOCTYPE doc SYSTEM "http://example.com/doc.dtd" [
1437        <!ELEMENT hello (#PCDATA)>
1438         ]  >
1439        <hello/>"#);
1440        let doc = package.as_document();
1441        let top = top(&doc);
1442
1443        assert_qname_eq!(top.name(), "hello");
1444    }
1445
1446    #[test]
1447    fn a_document_with_a_single_element() {
1448        let package = quick_parse("<hello />");
1449        let doc = package.as_document();
1450        let top = top(&doc);
1451
1452        assert_qname_eq!(top.name(), "hello");
1453    }
1454
1455    #[test]
1456    fn an_element_with_a_namespace() {
1457        let package = quick_parse("<ns:hello xmlns:ns='namespace'/>");
1458        let doc = package.as_document();
1459        let top = top(&doc);
1460
1461        assert_eq!(top.preferred_prefix(), Some("ns"));
1462        assert_qname_eq!(("namespace", "hello"), top.name());
1463    }
1464
1465    #[test]
1466    fn an_element_with_a_default_namespace() {
1467        let package = quick_parse("<hello xmlns='namespace'/>");
1468        let doc = package.as_document();
1469        let top = top(&doc);
1470
1471        assert_eq!(top.default_namespace_uri(), Some("namespace"));
1472        assert_qname_eq!(("namespace", "hello"), top.name());
1473    }
1474
1475    #[test]
1476    fn an_element_with_an_attribute() {
1477        let package = quick_parse("<hello scope='world'/>");
1478        let doc = package.as_document();
1479        let top = top(&doc);
1480
1481        assert_eq!(top.attribute_value("scope"), Some("world"));
1482    }
1483
1484    #[test]
1485    fn an_element_with_an_attribute_using_double_quotes() {
1486        let package = quick_parse("<hello scope=\"world\"/>");
1487        let doc = package.as_document();
1488        let top = top(&doc);
1489
1490        assert_eq!(top.attribute_value("scope"), Some("world"));
1491    }
1492
1493    #[test]
1494    fn an_element_with_multiple_attributes() {
1495        let package = quick_parse("<hello scope='world' happy='true'/>");
1496        let doc = package.as_document();
1497        let top = top(&doc);
1498
1499        assert_eq!(top.attribute_value("scope"), Some("world"));
1500        assert_eq!(top.attribute_value("happy"), Some("true"));
1501    }
1502
1503    #[test]
1504    fn an_attribute_with_a_namespace() {
1505        let package = quick_parse("<hello ns:a='b' xmlns:ns='namespace'/>");
1506        let doc = package.as_document();
1507        let top = top(&doc);
1508
1509        let attr = top.attribute(("namespace", "a")).unwrap();
1510
1511        assert_eq!(attr.preferred_prefix(), Some("ns"));
1512        assert_eq!(attr.value(), "b");
1513    }
1514
1515    #[test]
1516    fn an_attribute_with_xml_space_preserve() {
1517        let package = quick_parse("<hello xml:space='preserve'> <a/> </hello>");
1518        let doc = package.as_document();
1519        let top = top(&doc);
1520
1521        assert_eq!(top.attribute((::XML_NS_URI, "space")).unwrap().value(), "preserve");
1522
1523        let children = top.children();
1524        assert_eq!(children.len(), 3);
1525        assert_eq!(children[0].text().unwrap().text(), " ");
1526        assert_qname_eq!(children[1].element().unwrap().name(), "a");
1527        assert_eq!(children[2].text().unwrap().text(), " ");
1528    }
1529
1530    #[test]
1531    fn an_attribute_with_references() {
1532        let package = quick_parse("<log msg='I &lt;3 math' />");
1533        let doc = package.as_document();
1534        let top = top(&doc);
1535
1536        assert_eq!(top.attribute_value("msg"), Some("I <3 math"));
1537    }
1538
1539    #[test]
1540    fn an_element_that_is_not_self_closing() {
1541        let package = quick_parse("<hello></hello>");
1542        let doc = package.as_document();
1543        let top = top(&doc);
1544
1545        assert_qname_eq!(top.name(), "hello");
1546    }
1547
1548    #[test]
1549    fn nested_elements() {
1550        let package = quick_parse("<hello><world/></hello>");
1551        let doc = package.as_document();
1552        let hello = top(&doc);
1553        let world = hello.children()[0].element().unwrap();
1554
1555        assert_qname_eq!(world.name(), "world");
1556    }
1557
1558    #[test]
1559    fn multiply_nested_elements() {
1560        let package = quick_parse("<hello><awesome><world/></awesome></hello>");
1561        let doc = package.as_document();
1562        let hello = top(&doc);
1563        let awesome = hello.children()[0].element().unwrap();
1564        let world = awesome.children()[0].element().unwrap();
1565
1566        assert_qname_eq!(world.name(), "world");
1567    }
1568
1569    #[test]
1570    fn nested_elements_with_namespaces() {
1571        let package = quick_parse("<ns1:hello xmlns:ns1='outer'><ns2:world xmlns:ns2='inner'/></ns1:hello>");
1572        let doc = package.as_document();
1573        let hello = top(&doc);
1574        let world = hello.children()[0].element().unwrap();
1575
1576        assert_qname_eq!(world.name(), ("inner", "world"));
1577    }
1578
1579    #[test]
1580    fn nested_elements_with_inherited_namespaces() {
1581        let package = quick_parse("<ns1:hello xmlns:ns1='outer'><ns1:world/></ns1:hello>");
1582        let doc = package.as_document();
1583        let hello = top(&doc);
1584        let world = hello.children()[0].element().unwrap();
1585
1586        assert_eq!(world.preferred_prefix(), Some("ns1"));
1587        assert_qname_eq!(world.name(), ("outer", "world"));
1588    }
1589
1590    #[test]
1591    fn nested_elements_with_inherited_default_namespace() {
1592        let package = quick_parse("<hello xmlns='outer'><world/></hello>");
1593        let doc = package.as_document();
1594        let hello = top(&doc);
1595        let world = hello.children()[0].element().unwrap();
1596
1597        assert_qname_eq!(world.name(), ("outer", "world"));
1598    }
1599
1600    #[test]
1601    fn nested_elements_with_reset_default_namespace() {
1602        let package = quick_parse("<hello xmlns='outer'><world xmlns=''/></hello>");
1603        let doc = package.as_document();
1604        let hello = top(&doc);
1605        let world = hello.children()[0].element().unwrap();
1606
1607        assert_qname_eq!(world.name(), "world");
1608    }
1609
1610    #[test]
1611    fn nested_elements_with_attributes() {
1612        let package = quick_parse("<hello><world name='Earth'/></hello>");
1613        let doc = package.as_document();
1614        let hello = top(&doc);
1615        let world = hello.children()[0].element().unwrap();
1616
1617        assert_eq!(world.attribute_value("name"), Some("Earth"));
1618    }
1619
1620    #[test]
1621    fn nested_elements_with_attributes_with_inherited_namespaces() {
1622        let package = quick_parse("<hello xmlns:ns1='outer'><world ns1:name='Earth'/></hello>");
1623        let doc = package.as_document();
1624        let hello = top(&doc);
1625        let world = hello.children()[0].element().unwrap();
1626
1627        let attr = world.attribute(("outer", "name")).unwrap();
1628
1629        assert_eq!(attr.preferred_prefix(), Some("ns1"));
1630        assert_eq!(attr.value(), "Earth");
1631    }
1632
1633    #[test]
1634    fn element_with_text() {
1635        let package = quick_parse("<hello>world</hello>");
1636        let doc = package.as_document();
1637        let hello = top(&doc);
1638        let text = hello.children()[0].text().unwrap();
1639
1640        assert_eq!(text.text(), "world");
1641    }
1642
1643    #[test]
1644    fn element_with_cdata() {
1645        let package = quick_parse("<words><![CDATA[I have & and < !]]></words>");
1646        let doc = package.as_document();
1647        let words = top(&doc);
1648        let text = words.children()[0].text().unwrap();
1649
1650        assert_eq!(text.text(), "I have & and < !");
1651    }
1652
1653    #[test]
1654    fn element_with_comment() {
1655        let package = quick_parse("<hello><!-- A comment --></hello>");
1656        let doc = package.as_document();
1657        let words = top(&doc);
1658        let comment = words.children()[0].comment().unwrap();
1659
1660        assert_eq!(comment.text(), " A comment ");
1661    }
1662
1663    #[test]
1664    fn comment_before_top_element() {
1665        let package = quick_parse("<!-- A comment --><hello />");
1666        let doc = package.as_document();
1667        let comment = doc.root().children()[0].comment().unwrap();
1668
1669        assert_eq!(comment.text(), " A comment ");
1670    }
1671
1672    #[test]
1673    fn multiple_comments_before_top_element() {
1674        let xml = r"
1675<!--Comment 1-->
1676<!--Comment 2-->
1677<hello />";
1678        let package = quick_parse(xml);
1679        let doc = package.as_document();
1680        let comment1 = doc.root().children()[0].comment().unwrap();
1681        let comment2 = doc.root().children()[1].comment().unwrap();
1682
1683        assert_eq!(comment1.text(), "Comment 1");
1684        assert_eq!(comment2.text(), "Comment 2");
1685    }
1686
1687    #[test]
1688    fn multiple_comments_after_top_element() {
1689        let xml = r"
1690<hello />
1691<!--Comment 1-->
1692<!--Comment 2-->";
1693        let package = quick_parse(xml);
1694        let doc = package.as_document();
1695        let comment1 = doc.root().children()[1].comment().unwrap();
1696        let comment2 = doc.root().children()[2].comment().unwrap();
1697
1698        assert_eq!(comment1.text(), "Comment 1");
1699        assert_eq!(comment2.text(), "Comment 2");
1700    }
1701
1702    #[test]
1703    fn element_with_processing_instruction() {
1704        let package = quick_parse("<hello><?device?></hello>");
1705        let doc = package.as_document();
1706        let hello = top(&doc);
1707        let pi = hello.children()[0].processing_instruction().unwrap();
1708
1709        assert_eq!(pi.target(), "device");
1710        assert_eq!(pi.value(), None);
1711    }
1712
1713    #[test]
1714    fn top_level_processing_instructions() {
1715        let xml = r"
1716<?output printer?>
1717<hello />
1718<?validated?>";
1719
1720        let package = quick_parse(xml);
1721        let doc = package.as_document();
1722        let pi1 = doc.root().children()[0].processing_instruction().unwrap();
1723        let pi2 = doc.root().children()[2].processing_instruction().unwrap();
1724
1725        assert_eq!(pi1.target(), "output");
1726        assert_eq!(pi1.value(), Some("printer"));
1727
1728        assert_eq!(pi2.target(), "validated");
1729        assert_eq!(pi2.value(), None);
1730    }
1731
1732    #[test]
1733    fn element_with_decimal_char_reference() {
1734        let package = quick_parse("<math>2 &#62; 1</math>");
1735        let doc = package.as_document();
1736        let math = top(&doc);
1737        let text1 = math.children()[0].text().unwrap();
1738        let text2 = math.children()[1].text().unwrap();
1739        let text3 = math.children()[2].text().unwrap();
1740
1741        assert_eq!(text1.text(), "2 ");
1742        assert_eq!(text2.text(), ">");
1743        assert_eq!(text3.text(), " 1");
1744    }
1745
1746    #[test]
1747    fn element_with_hexidecimal_char_reference() {
1748        let package = quick_parse("<math>1 &#x3c; 2</math>");
1749        let doc = package.as_document();
1750        let math = top(&doc);
1751        let text1 = math.children()[0].text().unwrap();
1752        let text2 = math.children()[1].text().unwrap();
1753        let text3 = math.children()[2].text().unwrap();
1754
1755        assert_eq!(text1.text(), "1 ");
1756        assert_eq!(text2.text(), "<");
1757        assert_eq!(text3.text(), " 2");
1758    }
1759
1760    #[test]
1761    fn element_with_entity_reference() {
1762        let package = quick_parse("<math>I &lt;3 math</math>");
1763        let doc = package.as_document();
1764        let math = top(&doc);
1765        let text1 = math.children()[0].text().unwrap();
1766        let text2 = math.children()[1].text().unwrap();
1767        let text3 = math.children()[2].text().unwrap();
1768
1769        assert_eq!(text1.text(), "I ");
1770        assert_eq!(text2.text(), "<");
1771        assert_eq!(text3.text(), "3 math");
1772    }
1773
1774    #[test]
1775    fn element_with_mixed_children() {
1776        let package = quick_parse("<hello>to <!--fixme--><a><![CDATA[the]]></a><?world?></hello>");
1777        let doc = package.as_document();
1778        let hello = top(&doc);
1779
1780        let text    = hello.children()[0].text().unwrap();
1781        let comment = hello.children()[1].comment().unwrap();
1782        let element = hello.children()[2].element().unwrap();
1783        let pi      = hello.children()[3].processing_instruction().unwrap();
1784
1785        assert_eq!(text.text(),    "to ");
1786        assert_eq!(comment.text(), "fixme");
1787        assert_qname_eq!(element.name(), "a");
1788        assert_eq!(pi.target(),    "world");
1789    }
1790
1791    // TODO: untested errors
1792    //
1793    // versionnumber
1794    // prefixedname
1795    // decimal chars
1796    // hex chars
1797    // chardata
1798    // cdata
1799    // commentbody
1800    // pinstructionvalue
1801
1802    macro_rules! assert_parse_failure {
1803        ($actual:expr, $pos:expr, $($err:expr),+) => {
1804            {
1805                let errors = vec![$($err),+];
1806                let expected = Err(Error::from(($pos, errors)));
1807                assert_eq!($actual, expected);
1808            }
1809        }
1810    }
1811
1812    #[test]
1813    fn failure_invalid_encoding() {
1814        use super::SpecificError::*;
1815
1816        let r = full_parse("<?xml version='1.0' encoding='8BIT' ?><hi/>");
1817
1818        assert_parse_failure!(r, 30, ExpectedEncoding);
1819    }
1820
1821    #[test]
1822    fn failure_invalid_standalone() {
1823        use super::SpecificError::*;
1824
1825        let r = full_parse("<?xml version='1.0' standalone='invalid'?><hello/>");
1826
1827        assert_parse_failure!(r, 32, ExpectedYesNo);
1828    }
1829
1830    #[test]
1831    fn failure_no_open_brace() {
1832        use super::SpecificError::*;
1833
1834        let r = full_parse("hi />");
1835
1836        assert_parse_failure!(r, 0, Expected("<?xml"), ExpectedComment, ExpectedProcessingInstruction, ExpectedWhitespace, ExpectedElement);
1837    }
1838
1839    #[test]
1840    fn failure_unclosed_tag() {
1841        use super::SpecificError::*;
1842
1843        let r = full_parse("<hi");
1844
1845        assert_parse_failure!(r, 3, ExpectedWhitespace, ExpectedElementSelfClosed, ExpectedElementEnd);
1846    }
1847
1848    #[test]
1849    fn failure_unexpected_space() {
1850        use super::SpecificError::*;
1851
1852        let r = full_parse("<hi / >");
1853
1854        assert_parse_failure!(r, 4, ExpectedAttribute, ExpectedElementSelfClosed, ExpectedElementEnd);
1855    }
1856
1857    #[test]
1858    fn failure_attribute_without_open_quote() {
1859        use super::SpecificError::*;
1860
1861        let r = full_parse("<hi oops=value' />");
1862
1863        assert_parse_failure!(r, 9, ExpectedOpeningQuote("\'"), ExpectedOpeningQuote("\""));
1864    }
1865
1866    #[test]
1867    fn failure_attribute_without_close_quote() {
1868        use super::SpecificError::*;
1869
1870        let r = full_parse("<hi oops='value />");
1871
1872        assert_parse_failure!(r, 18, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1873    }
1874
1875    #[test]
1876    fn failure_unclosed_attribute_and_tag() {
1877        use super::SpecificError::*;
1878
1879        let r = full_parse("<hi oops='value");
1880
1881        assert_parse_failure!(r, 15, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1882    }
1883
1884    #[test]
1885    fn failure_nested_unclosed_tag() {
1886        use super::SpecificError::*;
1887
1888        let r = full_parse("<hi><oops</hi>");
1889
1890        assert_parse_failure!(r, 9, ExpectedWhitespace, ExpectedElementSelfClosed, ExpectedElementEnd);
1891    }
1892
1893    #[test]
1894    fn failure_missing_close_tag() {
1895        use super::SpecificError::*;
1896
1897        let r = full_parse("<hi>wow");
1898
1899        assert_parse_failure!(r, 7, UnclosedElement);
1900    }
1901
1902    #[test]
1903    fn failure_nested_unexpected_space() {
1904        use super::SpecificError::*;
1905
1906        let r = full_parse("<hi><oops / ></hi>");
1907
1908        assert_parse_failure!(r, 10, ExpectedAttribute, ExpectedElementSelfClosed, ExpectedElementEnd);
1909    }
1910
1911    #[test]
1912    fn failure_malformed_entity_reference() {
1913        use super::SpecificError::*;
1914
1915        let r = full_parse("<hi>Entity: &;</hi>");
1916
1917        assert_parse_failure!(r, 13, ExpectedNamedReferenceValue);
1918    }
1919
1920    #[test]
1921    fn failure_nested_malformed_entity_reference() {
1922        use super::SpecificError::*;
1923
1924        let r = full_parse("<hi><bye>Entity: &;</bye></hi>");
1925
1926        assert_parse_failure!(r, 18, ExpectedNamedReferenceValue);
1927    }
1928
1929    #[test]
1930    fn failure_nested_attribute_without_open_quote() {
1931        use super::SpecificError::*;
1932
1933        let r = full_parse("<hi><bye oops=value' /></hi>");
1934
1935        assert_parse_failure!(r, 14, ExpectedOpeningQuote("\'"), ExpectedOpeningQuote("\""));
1936    }
1937
1938    #[test]
1939    fn failure_nested_attribute_without_close_quote() {
1940        use super::SpecificError::*;
1941
1942        let r = full_parse("<hi><bye oops='value /></hi>");
1943
1944        assert_parse_failure!(r, 23, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1945    }
1946
1947    #[test]
1948    fn failure_nested_unclosed_attribute_and_tag() {
1949        use super::SpecificError::*;
1950
1951        let r = full_parse("<hi><bye oops='value</hi>");
1952
1953        assert_parse_failure!(r, 20, ExpectedNamedReference, ExpectedDecimalReference, ExpectedAttributeValue, ExpectedHexReference, ExpectedClosingQuote("\'"));
1954    }
1955
1956    #[test]
1957    fn failure_pi_target_as_xml() {
1958        use super::SpecificError::*;
1959
1960        let r = full_parse("<a><?xml?></a>");
1961
1962        assert_parse_failure!(r, 5, InvalidProcessingInstructionTarget);
1963    }
1964
1965    #[test]
1966    fn failure_end_tag_does_not_match() {
1967        use super::SpecificError::*;
1968
1969        let r = full_parse("<a></b>");
1970
1971        assert_parse_failure!(r, 5, MismatchedElementEndName);
1972    }
1973
1974    #[test]
1975    fn failure_invalid_decimal_reference() {
1976        use super::SpecificError::*;
1977
1978        let r = full_parse("<a>&#99999999;</a>");
1979
1980        assert_parse_failure!(r, 5, InvalidDecimalReference);
1981    }
1982
1983    #[test]
1984    fn failure_invalid_hex_reference() {
1985        use super::SpecificError::*;
1986
1987        let r = full_parse("<a>&#x99999999;</a>");
1988
1989        assert_parse_failure!(r, 6, InvalidHexReference);
1990    }
1991
1992    #[test]
1993    fn failure_unknown_named_reference() {
1994        use super::SpecificError::*;
1995
1996        let r = full_parse("<a>&fake;</a>");
1997
1998        assert_parse_failure!(r, 4, UnknownNamedReference);
1999    }
2000
2001    #[test]
2002    fn failure_duplicate_attribute() {
2003        use super::SpecificError::*;
2004
2005        let r = full_parse("<a b='c' b='d'/>");
2006
2007        assert_parse_failure!(r, 9, DuplicateAttribute);
2008    }
2009
2010    #[test]
2011    fn failure_redefined_namespace() {
2012        use super::SpecificError::*;
2013
2014        let r = full_parse("<a xmlns:b='c' xmlns:b='d'/>");
2015
2016        assert_parse_failure!(r, 15, RedefinedNamespace);
2017    }
2018
2019    #[test]
2020    fn failure_redefined_default_namespace() {
2021        use super::SpecificError::*;
2022
2023        let r = full_parse("<a xmlns='a' xmlns='b'/>");
2024
2025        assert_parse_failure!(r, 13, RedefinedDefaultNamespace);
2026    }
2027
2028    #[test]
2029    fn failure_empty_namespace() {
2030        use super::SpecificError::*;
2031
2032        let r = full_parse("<a xmlns:b=''/>");
2033
2034        assert_parse_failure!(r, 3, EmptyNamespace);
2035    }
2036
2037    #[test]
2038    fn failure_unknown_attribute_namespace_prefix() {
2039        use super::SpecificError::*;
2040
2041        let r = full_parse("<a b:foo='a'/>");
2042
2043        assert_parse_failure!(r, 3, UnknownNamespacePrefix);
2044    }
2045
2046    #[test]
2047    fn failure_unknown_element_namespace_prefix() {
2048        use super::SpecificError::*;
2049
2050        let r = full_parse("<b:a/>");
2051
2052        assert_parse_failure!(r, 1, UnknownNamespacePrefix);
2053    }
2054
2055    #[test]
2056    fn failure_is_an_error() {
2057        fn __assert_well_behaved_error()
2058        where
2059            Error: ::std::error::Error + Send + Sync + 'static,
2060        {}
2061    }
2062}