use anyhow::Result;
use serde::{Deserialize, Serialize};
use sysinfo::Networks;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NetworkInterface {
pub name: String,
pub ip: String,
pub mac: Option<String>,
pub is_up: bool,
pub received_bytes: u64,
pub transmitted_bytes: u64,
}
pub fn list_interfaces() -> Result<Vec<NetworkInterface>> {
let networks = Networks::new_with_refreshed_list();
let mut interfaces = Vec::new();
for (name, data) in &networks {
let mac = data.mac_address().to_string();
let mac = if mac.is_empty() || mac == "00:00:00:00:00:00" {
None
} else {
Some(mac)
};
let ip = get_interface_ip(name).unwrap_or_else(|| "N/A".to_string());
interfaces.push(NetworkInterface {
name: name.clone(),
ip,
mac,
is_up: data.received() > 0 || data.transmitted() > 0,
received_bytes: data.received(),
transmitted_bytes: data.transmitted(),
});
}
interfaces.sort_by(|a, b| a.name.cmp(&b.name));
Ok(interfaces)
}
fn get_interface_ip(interface_name: &str) -> Option<String> {
if let Ok(local_ip) = local_ip_address::local_ip() {
if interface_name.contains("en0")
|| interface_name.contains("eth0")
|| interface_name.contains("wlan0")
|| interface_name.contains("Wi-Fi")
|| interface_name.contains("Ethernet")
{
return Some(local_ip.to_string());
}
}
if interface_name.contains("lo") || interface_name.contains("Loopback") {
return Some("127.0.0.1".to_string());
}
None
}
#[allow(dead_code)]
pub fn get_bandwidth_usage() -> Result<BandwidthUsage> {
let networks = Networks::new_with_refreshed_list();
let mut total_rx: u64 = 0;
let mut total_tx: u64 = 0;
for (_, data) in &networks {
total_rx += data.received();
total_tx += data.transmitted();
}
Ok(BandwidthUsage {
received_bytes: total_rx,
transmitted_bytes: total_tx,
})
}
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct BandwidthUsage {
pub received_bytes: u64,
pub transmitted_bytes: u64,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_list_interfaces() {
let result = list_interfaces();
assert!(result.is_ok());
let interfaces = result.unwrap();
assert!(!interfaces.is_empty());
}
#[test]
fn test_bandwidth_usage() {
let result = get_bandwidth_usage();
assert!(result.is_ok());
}
}