use crate::error::{AppError, AppResult}; use network_interface::{NetworkInterface, NetworkInterfaceConfig}; use std::fmt; #[derive(Debug, Clone, PartialEq, Eq)] pub struct NetworkAdapter { pub name: String, pub is_up: bool, pub is_loopback: bool, } impl fmt::Display for NetworkAdapter { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.name) } } impl From for NetworkAdapter { fn from(interface: NetworkInterface) -> Self { let is_loopback = interface.name.to_lowercase().contains("lo"); let is_up = !interface.addr.is_empty(); Self { name: interface.name, is_up, is_loopback, } } } pub fn get_network_adapters() -> AppResult> { NetworkInterface::show() .map_err(AppError::UnableToListNetworkInterfaces) .map(|interfaces| interfaces.into_iter().map(NetworkAdapter::from).collect()) } pub fn get_active_network_adapters() -> AppResult> { get_network_adapters().map(|adapters| { adapters .into_iter() .filter(|adapter| adapter.is_up && !adapter.is_loopback) .collect() }) } #[cfg(test)] mod tests { use super::*; use crate::test; test! { fn test_get_network_adapters() { let adapters = get_network_adapters()?; assert!(!adapters.is_empty(), "No network adapters found"); for adapter in &adapters { assert!(!adapter.name.is_empty(), "Found adapter with empty name"); } let up_adapters = adapters.iter().filter(|a| a.is_up).count(); assert!(up_adapters > 0, "No adapters are up"); let non_loopback = adapters.iter().filter(|a| !a.is_loopback).count(); assert!(non_loopback > 0, "All adapters are loopback interfaces"); } } test! { fn test_get_active_network_adapters() { let adapters = get_active_network_adapters()?; assert!(!adapters.is_empty(), "No active network adapters found"); for adapter in &adapters { assert!(adapter.is_up, "Found inactive adapter: {}", adapter.name); assert!(!adapter.is_loopback, "Found loopback adapter: {}", adapter.name); } } } test! { fn test_network_adapter_display() { let adapter = NetworkAdapter { name: "eth0".to_string(), is_up: true, is_loopback: false, }; assert_eq!(format!("{}", adapter), "eth0"); } } }