aboutsummaryrefslogtreecommitdiff
path: root/src/network.rs
diff options
context:
space:
mode:
authorGus Power <gus@infinitesidequests.com>2025-06-07 14:55:21 +0100
committerGus Power <gus@infinitesidequests.com>2025-06-07 14:55:21 +0100
commit172f8163139f8112b76d462198a1213a5cb49dde (patch)
tree0a10558a0b2a4ce4e07177bc520b6f6030553763 /src/network.rs
parent3e5aa28345bb009c12b5a55f2e7174957bf4ed9a (diff)
first test of Junie - add network module for detecting available network adapters
Diffstat (limited to 'src/network.rs')
-rw-r--r--src/network.rs93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/network.rs b/src/network.rs
new file mode 100644
index 0000000..3697e29
--- /dev/null
+++ b/src/network.rs
@@ -0,0 +1,93 @@
+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<NetworkInterface> 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<Vec<NetworkAdapter>> {
+ NetworkInterface::show()
+ .map_err(AppError::NetworkInterfaceError)
+ .map(|interfaces| interfaces.into_iter().map(NetworkAdapter::from).collect())
+}
+
+pub fn get_active_network_adapters() -> AppResult<Vec<NetworkAdapter>> {
+ 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");
+ }
+ }
+}