aboutsummaryrefslogtreecommitdiff
path: root/src/reader/parser/inside_opening_tag.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/reader/parser/inside_opening_tag.rs')
-rw-r--r--src/reader/parser/inside_opening_tag.rs73
1 files changed, 39 insertions, 34 deletions
diff --git a/src/reader/parser/inside_opening_tag.rs b/src/reader/parser/inside_opening_tag.rs
index 533874f..b7f185a 100644
--- a/src/reader/parser/inside_opening_tag.rs
+++ b/src/reader/parser/inside_opening_tag.rs
@@ -1,26 +1,26 @@
-use common::is_name_start_char;
-use attribute::OwnedAttribute;
-use namespace;
+use crate::reader::error::SyntaxError;
+use crate::common::is_name_start_char;
+use crate::namespace;
+use crate::{attribute::OwnedAttribute, common::is_whitespace_char};
-use reader::lexer::Token;
+use crate::reader::lexer::Token;
-use super::{Result, PullParser, State, OpeningTagSubstate, QualifiedNameTarget};
+use super::{OpeningTagSubstate, PullParser, QualifiedNameTarget, Result, State};
impl PullParser {
pub fn inside_opening_tag(&mut self, t: Token, s: OpeningTagSubstate) -> Option<Result> {
- macro_rules! unexpected_token(($t:expr) => (Some(self_error!(self; "Unexpected token inside opening tag: {}", $t))));
match s {
OpeningTagSubstate::InsideName => self.read_qualified_name(t, QualifiedNameTarget::OpeningTagNameTarget, |this, token, name| {
match name.prefix_ref() {
Some(prefix) if prefix == namespace::NS_XML_PREFIX ||
prefix == namespace::NS_XMLNS_PREFIX =>
- Some(self_error!(this; "'{:?}' cannot be an element name prefix", name.prefix)),
+ Some(this.error(SyntaxError::InvalidNamePrefix(prefix.into()))),
_ => {
this.data.element_name = Some(name.clone());
match token {
Token::TagEnd => this.emit_start_element(false),
Token::EmptyTagEnd => this.emit_start_element(true),
- Token::Whitespace(_) => this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideTag)),
+ Token::Character(c) if is_whitespace_char(c) => this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideTag)),
_ => unreachable!()
}
}
@@ -28,66 +28,65 @@ impl PullParser {
}),
OpeningTagSubstate::InsideTag => match t {
- Token::Whitespace(_) => None, // skip whitespace
+ Token::TagEnd => self.emit_start_element(false),
+ Token::EmptyTagEnd => self.emit_start_element(true),
+ Token::Character(c) if is_whitespace_char(c) => None, // skip whitespace
Token::Character(c) if is_name_start_char(c) => {
self.buf.push(c);
self.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideAttributeName))
}
- Token::TagEnd => self.emit_start_element(false),
- Token::EmptyTagEnd => self.emit_start_element(true),
- _ => unexpected_token!(t)
+ _ => Some(self.error(SyntaxError::UnexpectedTokenInOpeningTag(t)))
},
OpeningTagSubstate::InsideAttributeName => self.read_qualified_name(t, QualifiedNameTarget::AttributeNameTarget, |this, token, name| {
this.data.attr_name = Some(name);
match token {
- Token::Whitespace(_) => this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::AfterAttributeName)),
Token::EqualsSign => this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideAttributeValue)),
+ Token::Character(c) if is_whitespace_char(c) => this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::AfterAttributeName)),
_ => unreachable!()
}
}),
OpeningTagSubstate::AfterAttributeName => match t {
- Token::Whitespace(_) => None,
Token::EqualsSign => self.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideAttributeValue)),
- _ => unexpected_token!(t)
+ Token::Character(c) if is_whitespace_char(c) => None,
+ _ => Some(self.error(SyntaxError::UnexpectedTokenInOpeningTag(t)))
},
OpeningTagSubstate::InsideAttributeValue => self.read_attribute_value(t, |this, value| {
- let name = this.data.take_attr_name().unwrap(); // unwrap() will always succeed here
-
+ let name = this.data.take_attr_name()?; // will always succeed here
// check that no attribute with such name is already present
// if there is one, XML is not well-formed
- if this.data.attributes.iter().find(|a| a.name == name).is_some() { // TODO: looks bad
+ if this.data.attributes.iter().any(|a| a.name == name) { // TODO: looks bad
// TODO: ideally this error should point to the beginning of the attribute,
// TODO: not the end of its value
- Some(self_error!(this; "Attribute '{}' is redefined", name))
+ Some(this.error(SyntaxError::RedefinedAttribute(name.to_string().into())))
} else {
match name.prefix_ref() {
// declaring a new prefix; it is sufficient to check prefix only
// because "xmlns" prefix is reserved
Some(namespace::NS_XMLNS_PREFIX) => {
- let ln = &name.local_name[..];
+ let ln = &*name.local_name;
if ln == namespace::NS_XMLNS_PREFIX {
- Some(self_error!(this; "Cannot redefine prefix '{}'", namespace::NS_XMLNS_PREFIX))
- } else if ln == namespace::NS_XML_PREFIX && &value[..] != namespace::NS_XML_URI {
- Some(self_error!(this; "Prefix '{}' cannot be rebound to another value", namespace::NS_XML_PREFIX))
+ Some(this.error(SyntaxError::CannotRedefineXmlnsPrefix))
+ } else if ln == namespace::NS_XML_PREFIX && &*value != namespace::NS_XML_URI {
+ Some(this.error(SyntaxError::CannotRedefineXmlPrefix))
} else if value.is_empty() {
- Some(self_error!(this; "Cannot undefine prefix '{}'", ln))
+ Some(this.error(SyntaxError::CannotUndefinePrefix(ln.into())))
} else {
this.nst.put(name.local_name.clone(), value);
- this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideTag))
+ this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::AfterAttributeValue))
}
}
// declaring default namespace
- None if &name.local_name[..] == namespace::NS_XMLNS_PREFIX =>
- match &value[..] {
- namespace::NS_XMLNS_PREFIX | namespace::NS_XML_PREFIX =>
- Some(self_error!(this; "Namespace '{}' cannot be default", value)),
+ None if &*name.local_name == namespace::NS_XMLNS_PREFIX =>
+ match &*value {
+ namespace::NS_XMLNS_PREFIX | namespace::NS_XML_PREFIX | namespace::NS_XML_URI | namespace::NS_XMLNS_URI =>
+ Some(this.error(SyntaxError::InvalidDefaultNamespace(value.into()))),
_ => {
this.nst.put(namespace::NS_NO_PREFIX, value.clone());
- this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideTag))
+ this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::AfterAttributeValue))
}
},
@@ -95,14 +94,20 @@ impl PullParser {
_ => {
this.data.attributes.push(OwnedAttribute {
name: name.clone(),
- value: value
+ value
});
- this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideTag))
+ this.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::AfterAttributeValue))
}
}
}
- })
+ }),
+
+ OpeningTagSubstate::AfterAttributeValue => match t {
+ Token::Character(c) if is_whitespace_char(c) => self.into_state_continue(State::InsideOpeningTag(OpeningTagSubstate::InsideTag)),
+ Token::TagEnd => self.emit_start_element(false),
+ Token::EmptyTagEnd => self.emit_start_element(true),
+ _ => Some(self.error(SyntaxError::UnexpectedTokenInOpeningTag(t)))
+ },
}
}
-
}