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
use super::{ IoError, Result, tiny_future::{ Future, async } };
use std::{
time::Duration, str::FromStr,
net::{ SocketAddr, ToSocketAddrs },
io::ErrorKind as IoErrorKind
};
pub trait DnsResolvable {
fn dns_resolve(&self, timeout: Duration) -> Result<SocketAddr>;
}
impl<T: ToString> DnsResolvable for T {
fn dns_resolve(&self, timeout: Duration) -> Result<SocketAddr> {
let address = self.to_string();
let fut = async(move |fut: Future<Result<SocketAddr>>| {
loop {
if !fut.is_waiting() { job_die!(fut) }
match address.as_str().to_socket_addrs() {
Ok(mut addresses) => if let Some(address) = addresses.next() { job_return!(fut, Ok(address)) }
else { job_return!(fut, Err(new_err!(IoErrorKind::NotFound.into()))) },
Err(error) => {
let io_error = IoError::from(error);
if io_error.non_recoverable { job_return!(fut, Err(new_err!(io_error))) }
}
};
};
});
if let Ok(result) = fut.try_get_timeout(timeout) { result }
else { throw_err!(IoErrorKind::TimedOut.into()) }
}
}
pub trait IpParseable {
fn parse_ip(&self) -> Result<SocketAddr>;
}
impl<T: AsRef<str>> IpParseable for T {
fn parse_ip(&self) -> Result<SocketAddr> {
if let Ok(address) = SocketAddr::from_str(self.as_ref()) { Ok(address) }
else { throw_err!(IoErrorKind::InvalidInput.into()) }
}
}