use crate::models::HardwareDto; use nvml_wrapper::Nvml; use sysinfo::System; impl HardwareDto { pub async fn collect() -> anyhow::Result { let mut sys = System::new_all(); sys.refresh_cpu_all(); sys.refresh_memory(); let cpus = sys.cpus(); let cpu_type = if !cpus.is_empty() { cpus[0].brand().to_string() } else { "Unknown CPU".to_string() }; let cpu_cores = cpus.len() as i32; let ram_bytes = sys.total_memory() as f64; let gpu_type = Self::detect_gpu_name(); let ip_address = local_ip_address::local_ip()?.to_string(); Ok(Self { cpu_type, cpu_cores, gpu_type, ram_size: ram_bytes, ip_address, }) } fn detect_gpu_name() -> String { // First try NVML (NVIDIA Management Library) if let Some(name) = Self::try_nvml_gpu_name() { return name; } // Fallback to OS-specific commands #[cfg(target_os = "linux")] { if let Ok(output) = std::process::Command::new("lshw") .args(&["-C", "display"]) .output() { if let Some(name) = String::from_utf8_lossy(&output.stdout) .lines() .find(|l| l.contains("product:")) .map(|l| l.trim().replace("product:", "").trim().to_string()) { return name; } } } #[cfg(target_os = "windows")] { if let Ok(output) = std::process::Command::new("wmic") .args(&["path", "win32_VideoController", "get", "name"]) .output() { if let Some(name) = String::from_utf8_lossy(&output.stdout) .lines() .nth(1) .map(|s| s.trim().to_string()) { return name; } } } // If all else fails "Unknown GPU".to_string() } fn try_nvml_gpu_name() -> Option { let nvml = Nvml::init().ok()?; let device = nvml.device_by_index(0).ok()?; device.name().ok().map(|s| s.to_string()) } }