use std::{time, thread};
pub use icmp::Icmp;
const DEFAULT_NUM_PINGS: u64 = 5;
const DEFAULT_INTERVAL_SECS: u64 = 1;
const DEFAULT_TIMEOUT_SECS: u64 = 10;
pub struct PingBuilder<'a> {
host: &'a str,
num_pings: u64,
interval_secs: u64,
timeout_secs: u64,
debug: bool,
}
impl<'a> PingBuilder<'a> {
pub fn new() -> PingBuilder<'a> {
PingBuilder {
host: "127.0.0.1",
num_pings: DEFAULT_NUM_PINGS,
interval_secs: DEFAULT_INTERVAL_SECS,
timeout_secs: DEFAULT_TIMEOUT_SECS,
debug: false,
}
}
pub fn host(self, host: &'a str) -> PingBuilder<'a> {
PingBuilder { host: host, .. self }
}
pub fn num_pings(self, num_pings: u64) -> PingBuilder<'a> {
PingBuilder { num_pings: num_pings, .. self }
}
pub fn interval_secs(self, interval_secs: u64) -> PingBuilder<'a> {
PingBuilder { interval_secs: interval_secs, .. self }
}
pub fn timeout_secs(self, timeout_secs: u64) -> PingBuilder<'a> {
PingBuilder { timeout_secs: timeout_secs, .. self }
}
pub fn debug(self, debug: bool) -> PingBuilder<'a> {
PingBuilder { debug: debug, .. self }
}
pub fn build(self) -> Ping<'a> {
Ping {
host: self.host,
num_pings: self.num_pings,
interval_secs: self.interval_secs,
timeout_secs: self.timeout_secs,
debug: self.debug,
}
}
}
pub struct Ping<'a> {
host: &'a str,
num_pings: u64,
interval_secs: u64,
timeout_secs: u64,
debug: bool,
}
impl<'a> Ping<'a> {
pub fn ping(&self) {
let started = time::Instant::now();
let timeout = time::Duration::from_secs(self.timeout_secs);
let time_between_pings = time::Duration::from_secs(self.interval_secs);
let mut icmp = Icmp::new(self.host);
if self.debug {
println!("PING {}", self.host);
}
let mut i = 1;
let mut last_ping_sent = started;
icmp.echo_request();
loop {
if time::Instant::now() > started + timeout {
return;
}
match icmp.poll() {
Some(ready) => if !ready { continue; },
_ => continue,
}
if let Some((reply, dur)) = icmp.get_echo_reply() {
let time = (dur.as_secs() * 1000) as f64 + dur.subsec_nanos() as f64 / 1e6;
if self.debug {
println!("{} bytes from {}: icmp_seq={} time={:.1} ms", reply.len(), self.host, reply.seq(), time);
}
}
if i > self.num_pings {
break;
}
thread::sleep(((last_ping_sent + time_between_pings) as time::Instant).duration_since(time::Instant::now()));
icmp.echo_request();
last_ping_sent = time::Instant::now();
i += 1;
}
}
}