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#[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 #[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() }