1 extern crate xmlparser as xml;
2 
3 type Range = ::std::ops::Range<usize>;
4 
5 #[derive(PartialEq, Debug)]
6 pub enum Token<'a> {
7     Declaration(&'a str, Option<&'a str>, Option<bool>, Range),
8     PI(&'a str, Option<&'a str>, Range),
9     Comment(&'a str, Range),
10     DtdStart(&'a str, Option<ExternalId<'a>>, Range),
11     EmptyDtd(&'a str, Option<ExternalId<'a>>, Range),
12     EntityDecl(&'a str, EntityDefinition<'a>, Range),
13     DtdEnd(Range),
14     ElementStart(&'a str, &'a str, Range),
15     Attribute(&'a str, &'a str, &'a str, Range),
16     ElementEnd(ElementEnd<'a>, Range),
17     Text(&'a str, Range),
18     Cdata(&'a str, Range),
19     Error(String),
20 }
21 
22 #[derive(PartialEq, Debug)]
23 pub enum ElementEnd<'a> {
24     Open,
25     Close(&'a str, &'a str),
26     Empty,
27 }
28 
29 #[derive(PartialEq, Debug)]
30 pub enum ExternalId<'a> {
31     System(&'a str),
32     Public(&'a str, &'a str),
33 }
34 
35 #[derive(PartialEq, Debug)]
36 pub enum EntityDefinition<'a> {
37     EntityValue(&'a str),
38     ExternalId(ExternalId<'a>),
39 }
40 
41 #[macro_export]
42 macro_rules! test {
43     ($name:ident, $text:expr, $($token:expr),*) => (
44         #[test]
45         fn $name() {
46             let mut p = xml::Tokenizer::from($text);
47             $(
48                 let t = p.next().unwrap();
49                 assert_eq!(to_test_token(t), $token);
50             )*
51             assert!(p.next().is_none());
52         }
53     )
54 }
55 
56 #[inline(never)]
to_test_token(token: Result<xml::Token, xml::Error>) -> Token57 pub fn to_test_token(token: Result<xml::Token, xml::Error>) -> Token {
58     match token {
59         Ok(xml::Token::Declaration { version, encoding, standalone, span }) => {
60             Token::Declaration(
61                 version.as_str(),
62                 encoding.map(|v| v.as_str()),
63                 standalone,
64                 span.range(),
65             )
66         }
67         Ok(xml::Token::ProcessingInstruction { target, content, span }) => {
68             Token::PI(
69                 target.as_str(),
70                 content.map(|v| v.as_str()),
71                 span.range(),
72             )
73         }
74         Ok(xml::Token::Comment { text, span }) => Token::Comment(text.as_str(), span.range()),
75         Ok(xml::Token::DtdStart { name, external_id, span }) => {
76             Token::DtdStart(
77                 name.as_str(),
78                 external_id.map(|v| to_test_external_id(v)),
79                 span.range(),
80             )
81         }
82         Ok(xml::Token::EmptyDtd { name, external_id, span }) => {
83             Token::EmptyDtd(
84                 name.as_str(),
85                 external_id.map(|v| to_test_external_id(v)),
86                 span.range(),
87             )
88         }
89         Ok(xml::Token::EntityDeclaration { name, definition, span }) => {
90             Token::EntityDecl(
91                 name.as_str(),
92                 match definition {
93                     xml::EntityDefinition::EntityValue(name) => {
94                         EntityDefinition::EntityValue(name.as_str())
95                     }
96                     xml::EntityDefinition::ExternalId(id) => {
97                         EntityDefinition::ExternalId(to_test_external_id(id))
98                     }
99                 },
100                 span.range(),
101             )
102         }
103         Ok(xml::Token::DtdEnd { span }) => Token::DtdEnd(span.range()),
104         Ok(xml::Token::ElementStart { prefix, local, span }) => {
105             Token::ElementStart(prefix.as_str(), local.as_str(), span.range())
106         }
107         Ok(xml::Token::Attribute { prefix, local, value, span }) => {
108             Token::Attribute(prefix.as_str(), local.as_str(), value.as_str(), span.range())
109         }
110         Ok(xml::Token::ElementEnd { end, span }) => {
111             Token::ElementEnd(
112                 match end {
113                     xml::ElementEnd::Open => ElementEnd::Open,
114                     xml::ElementEnd::Close(prefix, local) => {
115                         ElementEnd::Close(prefix.as_str(), local.as_str())
116                     }
117                     xml::ElementEnd::Empty => ElementEnd::Empty,
118                 },
119                 span.range()
120             )
121         }
122         Ok(xml::Token::Text { text }) => Token::Text(text.as_str(), text.range()),
123         Ok(xml::Token::Cdata { text, span }) => Token::Cdata(text.as_str(), span.range()),
124         Err(ref e) => Token::Error(e.to_string()),
125     }
126 }
127 
to_test_external_id(id: xml::ExternalId) -> ExternalId128 fn to_test_external_id(id: xml::ExternalId) -> ExternalId {
129     match id {
130         xml::ExternalId::System(name) => {
131             ExternalId::System(name.as_str())
132         }
133         xml::ExternalId::Public(name, value) => {
134             ExternalId::Public(name.as_str(), value.as_str())
135         }
136     }
137 }
138