use core::fmt;
use core::str;
#[cfg(feature = "std")]
use std::error;
use TokenType;
#[derive(Debug)]
pub enum Error {
InvalidToken(TokenType, TextPos, Option<StreamError>),
UnexpectedToken(TokenType, TextPos),
UnknownToken(TextPos),
}
impl Error {
pub fn pos(&self) -> TextPos {
match *self {
Error::InvalidToken(_, pos, _) => pos,
Error::UnexpectedToken(_, pos) => pos,
Error::UnknownToken(pos) => pos,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::InvalidToken(token_type, pos, ref cause) => {
match *cause {
Some(ref cause) => {
write!(f, "invalid token '{}' at {} cause {}", token_type, pos, cause)
}
None => {
write!(f, "invalid token '{}' at {}", token_type, pos)
}
}
}
Error::UnexpectedToken(token_type, pos) => {
write!(f, "unexpected token '{}' at {}", token_type, pos)
}
Error::UnknownToken(pos) => {
write!(f, "unknown token at {}", pos)
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
"an XML parsing error"
}
}
#[derive(Debug)]
pub enum StreamError {
UnexpectedEndOfStream,
InvalidName,
NonXmlChar(char, TextPos),
InvalidChar(u8, u8, TextPos),
InvalidCharMultiple(u8, &'static [u8], TextPos),
InvalidQuote(u8, TextPos),
InvalidSpace(u8, TextPos),
InvalidString(&'static str, TextPos),
InvalidReference,
InvalidExternalID,
InvalidCharacterData,
}
impl fmt::Display for StreamError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
StreamError::UnexpectedEndOfStream => {
write!(f, "unexpected end of stream")
}
StreamError::InvalidName => {
write!(f, "invalid name token")
}
StreamError::NonXmlChar(c, pos) => {
write!(f, "a non-XML character {:?} found at {}", c, pos)
}
StreamError::InvalidChar(actual, expected, pos) => {
write!(f, "expected '{}' not '{}' at {}",
expected as char, actual as char, pos)
}
StreamError::InvalidCharMultiple(actual, ref expected, pos) => {
let mut expected_iter = expected.iter().peekable();
write!(f, "expected ")?;
while let Some(&c) = expected_iter.next() {
write!(f, "'{}'", c as char)?;
if expected_iter.peek().is_some() {
write!(f, ", ")?;
}
}
write!(f, " not '{}' at {}", actual as char, pos)
}
StreamError::InvalidQuote(c, pos) => {
write!(f, "expected quote mark not '{}' at {}", c as char, pos)
}
StreamError::InvalidSpace(c, pos) => {
write!(f, "expected space not '{}' at {}", c as char, pos)
}
StreamError::InvalidString(expected, pos) => {
write!(f, "expected '{}' at {}", expected, pos)
}
StreamError::InvalidReference => {
write!(f, "invalid reference")
}
StreamError::InvalidExternalID => {
write!(f, "invalid ExternalID")
}
StreamError::InvalidCharacterData => {
write!(f, "']]>' is not allowed inside a character data")
}
}
}
}
#[cfg(feature = "std")]
impl error::Error for StreamError {
fn description(&self) -> &str {
"an XML stream parsing error"
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
#[allow(missing_docs)]
pub struct TextPos {
pub row: u32,
pub col: u32,
}
impl TextPos {
pub fn new(row: u32, col: u32) -> TextPos {
TextPos { row, col }
}
}
impl fmt::Display for TextPos {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}", self.row, self.col)
}
}