1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use std::error;
use std::fmt;
use std::io;
use std::result;
use status::StatusCode;
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub enum ErrorKind {
Io(io::Error),
BadResponse(String),
CommandFailed(StatusCode, String),
}
#[derive(Debug)]
pub struct Error {
kind: ErrorKind,
command: String,
}
impl Error {
pub fn new<C: Into<String>>(kind: ErrorKind, command: C) -> Error {
Error { kind: kind, command: command.into() }
}
pub fn io<C: Into<String>>(err: io::Error, command: C) -> Error {
Error::new(ErrorKind::Io(err), command)
}
pub fn io_custom<E, C>(kind: io::ErrorKind, error: E, command: C) -> Error
where E: Into<Box<error::Error + Send + Sync>>, C: Into<String>
{
Error::new(ErrorKind::Io(io::Error::new(kind, error)), command)
}
pub fn bad_response<D, C>(desc: D, command: C) -> Error
where D: Into<String>, C: Into<String>
{
Error::new(ErrorKind::BadResponse(desc.into()), command)
}
pub fn command_failed<M, C>(code: StatusCode, message: M, command: C) -> Error
where M: Into<String>, C: Into<String>
{
Error::new(ErrorKind::CommandFailed(code, message.into()), command)
}
pub fn kind(&self) -> &ErrorKind { &self.kind }
pub fn command(&self) -> &str { &self.command }
pub fn is_fatal(&self) -> bool {
match self.kind {
ErrorKind::Io(_) | ErrorKind::BadResponse(_) => true,
_ => false,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let have_command = self.command.len() > 0;
if have_command {
write!(f, "command failed: '{}' (", self.command)?;
}
match self.kind {
ErrorKind::Io(ref err) => write!(f, "I/O error: {}", err)?,
ErrorKind::BadResponse(ref desc) => write!(f, "bad response: {}", desc)?,
ErrorKind::CommandFailed(code, ref msg) => write!(f, "{}- {}", code, msg)?,
}
if have_command {
write!(f, ")")?;
}
Ok(())
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match self.kind {
ErrorKind::Io(ref err) => err.description(),
ErrorKind::BadResponse(ref desc) => desc.as_ref(),
ErrorKind::CommandFailed(_, ref msg) => msg.as_ref(),
}
}
fn cause(&self) -> Option<&::std::error::Error> {
match self.kind {
ErrorKind::Io(ref err) => Some(err),
_ => None,
}
}
}