mod network_stat;
use std::{
collections::HashSet,
hash::{Hash, Hasher},
io::ErrorKind,
thread::sleep,
time::Duration,
};
pub use network_stat::*;
use crate::scanner_rust::{generic_array::typenum::U1024, ScannerAscii, ScannerError};
#[derive(Default, Debug, Clone, Eq)]
pub struct Network {
pub interface: String,
pub stat: NetworkStat,
}
impl Hash for Network {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.interface.hash(state)
}
}
impl PartialEq for Network {
#[inline]
fn eq(&self, other: &Network) -> bool {
self.interface.eq(&other.interface)
}
}
pub fn get_networks() -> Result<Vec<Network>, ScannerError> {
let mut sc: ScannerAscii<_, U1024> = ScannerAscii::scan_path2("/proc/net/dev")?;
for _ in 0..2 {
sc.drop_next_line()?.ok_or(ErrorKind::UnexpectedEof)?;
}
let mut networks = Vec::with_capacity(1);
while let Some(interface) = sc.next_until_raw(":")? {
let interface = unsafe { String::from_utf8_unchecked(interface) };
let receive_bytes = sc.next_u64()?.ok_or(ErrorKind::UnexpectedEof)?;
for _ in 0..7 {
sc.drop_next()?.ok_or(ErrorKind::UnexpectedEof)?;
}
let transmit_bytes = sc.next_u64()?.ok_or(ErrorKind::UnexpectedEof)?;
let stat = NetworkStat {
receive_bytes,
transmit_bytes,
};
let network = Network {
interface,
stat,
};
networks.push(network);
sc.drop_next_line()?.ok_or(ErrorKind::UnexpectedEof)?;
}
Ok(networks)
}
pub fn get_networks_with_speed(
interval: Duration,
) -> Result<Vec<(Network, NetworkSpeed)>, ScannerError> {
let pre_networks = get_networks()?;
let pre_networks_length = pre_networks.len();
let mut pre_networks_hashset = HashSet::with_capacity(pre_networks_length);
for pre_network in pre_networks {
pre_networks_hashset.insert(pre_network);
}
sleep(interval);
let networks = get_networks()?;
let mut networks_with_speed = Vec::with_capacity(networks.len().min(pre_networks_length));
for network in networks {
if let Some(pre_network) = pre_networks_hashset.get(&network) {
let network_speed = pre_network.stat.compute_speed(&network.stat, interval);
networks_with_speed.push((network, network_speed));
}
}
Ok(networks_with_speed)
}