use std::time::Instant;
#[derive(Debug, Clone, Copy)]
pub struct TrafficData {
pub timestamp: Instant,
pub bytes_received: u64,
pub bytes_sent: u64,
pub packets_received: u64,
pub packets_sent: u64,
pub receive_errors: u64,
pub send_errors: u64,
pub collisions: u64,
}
impl TrafficData {
#[allow(clippy::too_many_arguments)]
pub fn new(
bytes_received: u64,
bytes_sent: u64,
packets_received: u64,
packets_sent: u64,
receive_errors: u64,
send_errors: u64,
collisions: u64,
) -> Self {
Self {
timestamp: Instant::now(),
bytes_received,
bytes_sent,
packets_received,
packets_sent,
receive_errors,
send_errors,
collisions,
}
}
}
#[derive(Debug, Clone)]
pub struct TrafficTracker {
current: TrafficData,
previous: Option<TrafficData>,
}
impl TrafficTracker {
#[allow(clippy::too_many_arguments)]
pub fn new(
bytes_received: u64,
bytes_sent: u64,
packets_received: u64,
packets_sent: u64,
receive_errors: u64,
send_errors: u64,
collisions: u64,
) -> Self {
let current = TrafficData::new(
bytes_received,
bytes_sent,
packets_received,
packets_sent,
receive_errors,
send_errors,
collisions,
);
Self { current, previous: None }
}
#[allow(clippy::too_many_arguments)]
pub fn update(
&mut self,
bytes_received: u64,
bytes_sent: u64,
packets_received: u64,
packets_sent: u64,
receive_errors: u64,
send_errors: u64,
collisions: u64,
) {
self.previous = Some(self.current);
self.current = TrafficData::new(
bytes_received,
bytes_sent,
packets_received,
packets_sent,
receive_errors,
send_errors,
collisions,
);
}
pub fn bytes_received(&self) -> u64 {
self.current.bytes_received
}
pub fn bytes_sent(&self) -> u64 {
self.current.bytes_sent
}
pub fn packets_received(&self) -> u64 {
self.current.packets_received
}
pub fn packets_sent(&self) -> u64 {
self.current.packets_sent
}
pub fn receive_errors(&self) -> u64 {
self.current.receive_errors
}
pub fn send_errors(&self) -> u64 {
self.current.send_errors
}
pub fn collisions(&self) -> u64 {
self.current.collisions
}
pub fn download_speed(&self) -> f64 {
if let Some(prev) = self.previous {
let bytes_diff = self.current.bytes_received.saturating_sub(prev.bytes_received);
let time_diff = self.current.timestamp.duration_since(prev.timestamp).as_secs_f64();
if time_diff > 0.0 {
bytes_diff as f64 / time_diff
} else {
0.0
}
} else {
0.0
}
}
pub fn upload_speed(&self) -> f64 {
if let Some(prev) = self.previous {
let bytes_diff = self.current.bytes_sent.saturating_sub(prev.bytes_sent);
let time_diff = self.current.timestamp.duration_since(prev.timestamp).as_secs_f64();
if time_diff > 0.0 {
bytes_diff as f64 / time_diff
} else {
0.0
}
} else {
0.0
}
}
pub fn packet_receive_rate(&self) -> f64 {
if let Some(prev) = self.previous {
let packets_diff = self.current.packets_received.saturating_sub(prev.packets_received);
let time_diff = self.current.timestamp.duration_since(prev.timestamp).as_secs_f64();
if time_diff > 0.0 {
packets_diff as f64 / time_diff
} else {
0.0
}
} else {
0.0
}
}
pub fn packet_send_rate(&self) -> f64 {
if let Some(prev) = self.previous {
let packets_diff = self.current.packets_sent.saturating_sub(prev.packets_sent);
let time_diff = self.current.timestamp.duration_since(prev.timestamp).as_secs_f64();
if time_diff > 0.0 {
packets_diff as f64 / time_diff
} else {
0.0
}
} else {
0.0
}
}
pub fn receive_error_rate(&self) -> f64 {
if self.current.packets_received > 0 {
self.current.receive_errors as f64 / self.current.packets_received as f64
} else {
0.0
}
}
pub fn send_error_rate(&self) -> f64 {
if self.current.packets_sent > 0 {
self.current.send_errors as f64 / self.current.packets_sent as f64
} else {
0.0
}
}
}