xml/reader/
error.rs

1
2use std::io;
3use std::borrow::Cow;
4use std::fmt;
5use std::error;
6use std::str;
7
8use util;
9use common::{Position, TextPosition};
10
11#[derive(Debug)]
12pub enum ErrorKind {
13    Syntax(Cow<'static, str>),
14    Io(io::Error),
15    Utf8(str::Utf8Error),
16    UnexpectedEof,
17}
18
19/// An XML parsing error.
20///
21/// Consists of a 2D position in a document and a textual message describing the error.
22#[derive(Clone, PartialEq, Eq, Debug)]
23pub struct Error {
24    pos: TextPosition,
25    kind: ErrorKind,
26}
27
28impl fmt::Display for Error {
29    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30        write!(f, "{} {}", self.pos, self.msg())
31    }
32}
33
34impl Position for Error {
35    #[inline]
36    fn position(&self) -> TextPosition { self.pos }
37}
38
39impl Error {
40    /// Returns a reference to a message which is contained inside this error.
41    #[inline]
42    pub fn msg(&self) -> &str {
43        use self::ErrorKind::*;
44        match self.kind {
45            UnexpectedEof => &"Unexpected EOF",
46            Utf8(ref reason) => error_description(reason),
47            Io(ref io_error) => error_description(io_error),
48            Syntax(ref msg) => msg.as_ref(),
49        }
50    }
51
52    pub fn kind(&self) -> &ErrorKind { &self.kind }
53}
54
55impl error::Error for Error {
56    #[inline]
57    fn description(&self) -> &str { self.msg() }
58}
59
60impl<'a, P, M> From<(&'a P, M)> for Error where P: Position, M: Into<Cow<'static, str>> {
61    fn from(orig: (&'a P, M)) -> Self {
62        Error{
63            pos: orig.0.position(),
64            kind: ErrorKind::Syntax(orig.1.into())
65        }
66    }
67}
68
69impl From<util::CharReadError> for Error {
70    fn from(e: util::CharReadError) -> Self {
71        use util::CharReadError::*;
72        Error{
73            pos: TextPosition::new(),
74            kind: match e {
75                UnexpectedEof => ErrorKind::UnexpectedEof,
76                Utf8(reason) => ErrorKind::Utf8(reason),
77                Io(io_error) => ErrorKind::Io(io_error),
78            }
79        }
80    }
81}
82
83impl From<io::Error> for Error {
84    fn from(e: io::Error) -> Self {
85        Error {
86            pos: TextPosition::new(),
87            kind: ErrorKind::Io(e),
88        }
89    }
90}
91
92impl Clone for ErrorKind {
93    fn clone(&self) -> Self {
94        use self::ErrorKind::*;
95        match *self {
96            UnexpectedEof => UnexpectedEof,
97            Utf8(ref reason) => Utf8(reason.clone()),
98            Io(ref io_error) => Io(io::Error::new(io_error.kind(), error_description(io_error))),
99            Syntax(ref msg) => Syntax(msg.clone()),
100        }
101    }
102}
103impl PartialEq for ErrorKind {
104    fn eq(&self, other: &ErrorKind) -> bool {
105        use self::ErrorKind::*;
106        match (self, other) {
107            (&UnexpectedEof, &UnexpectedEof) => true,
108            (&Utf8(ref left), &Utf8(ref right)) => left == right,
109            (&Io(ref left), &Io(ref right)) =>
110                left.kind() == right.kind() &&
111                error_description(left) == error_description(right),
112            (&Syntax(ref left), &Syntax(ref right)) =>
113                left == right,
114
115            (_, _) => false,
116        }
117    }
118}
119impl Eq for ErrorKind {}
120
121fn error_description(e: &error::Error) -> &str { e.description() }