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
use std::error::{Error as StdError};
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
use void::{unreachable, Void};
quick_error! {
#[derive(Debug)]
pub enum Error {
InvalidName(name: String, description: &'static str) {
description("name that you are trying to resolve is invalid")
display("name {:?} is invalid: {}", name, description)
}
TemporaryError(err: Box<StdError + Send + Sync>) {
description("temporary name resolution error")
display("temporary name resolution error: {}", err)
cause(&**err)
}
NameNotFound {
description("name not found")
display("name not found")
}
NoDefaultPort {
description("the resolver can only resolve hostname to an IP, \
address, so port must be specified to get full address")
}
}
}
impl Error {
pub fn into_io(self) -> IoError {
match self {
Error::InvalidName(_, _) =>
IoError::new(IoErrorKind::InvalidInput, self),
Error::TemporaryError(_) =>
IoError::new(IoErrorKind::Other, self),
Error::NameNotFound =>
IoError::new(IoErrorKind::NotFound, self),
Error::NoDefaultPort =>
IoError::new(IoErrorKind::NotFound, self),
}
}
}
impl From<Void> for Error {
fn from(v: Void) -> Error {
unreachable(v);
}
}
#[test]
fn send_sync() {
fn send_sync<T: Send+Sync>(_: T) {}
send_sync(Error::NameNotFound);
}
#[test]
fn wrap_into_io() {
assert_eq!(Error::InvalidName("foo".to_string(), "bar").into_io().kind(),
IoErrorKind::InvalidInput);
assert_eq!(Error::TemporaryError(Box::new(IoError::new(IoErrorKind::Other, "oh no!"))).into_io().kind(),
IoErrorKind::Other);
assert_eq!(Error::NameNotFound.into_io().kind(),
IoErrorKind::NotFound);
}