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
use super::colors::colorize;
use std::io::{BufRead, Result};
use std::process::Command;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
type Ping = (f32, String);
fn parse_ping(output: Result<String>) -> Option<Ping> {
let output = output.ok()?;
if output.contains("time=") {
let mut ping_output = output.split("=").last().unwrap().split(" ");
let ping: f32 = ping_output.next().unwrap().parse().unwrap();
let unit = ping_output.next().unwrap();
Some((ping, unit.to_string()))
} else {
None
}
}
pub struct PingManager {
ping: Arc<Mutex<Option<Ping>>>,
host: String,
}
impl PingManager {
pub fn new(host: String) -> PingManager {
let ping_manager = PingManager {
host,
ping: Arc::new(Mutex::new(None)),
};
ping_manager.start();
ping_manager
}
fn start(self: &PingManager) -> () {
let ping = self.ping.clone();
let host = self.host.clone();
let _child = thread::spawn(move || {
let mut child = Command::new("ping")
.arg("-i 1")
.arg(host)
.stdout(std::process::Stdio::piped())
.spawn()
.expect("Failed to execute child!");
let child_stdout = child.stdout.as_mut().unwrap();
let reader = std::io::BufReader::new(child_stdout);
for line in reader.lines() {
*ping.lock().unwrap() = parse_ping(line);
}
});
}
pub fn wait(self: &PingManager) -> () {
for _ in 0..20 {
if self.ping.lock().unwrap().is_some() {
break;
}
thread::sleep(Duration::from_millis(10));
}
}
pub fn current(self: &PingManager) -> String {
match self.ping.lock().unwrap().as_ref() {
None => "N/A".to_string(),
Some(ping) => colorize(format!(" {} {}", ping.0, ping.1), ping.0, 30.0, 100.0),
}
}
}