hardware_query/
simple.rs

1//! Simplified hardware query interface
2//!
3//! This module provides a simplified API for common hardware queries,
4//! making it easy for developers to get started without dealing with
5//! the full complexity of the hardware information structures.
6
7use crate::{HardwareInfo, Result};
8use serde::{Deserialize, Serialize};
9
10/// Simplified system overview with the most commonly needed information
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct SystemOverview {
13    /// CPU name and core count
14    pub cpu: SimpleCPU,
15    /// Total system memory in GB
16    pub memory_gb: f64,
17    /// GPU information (if available)
18    pub gpu: Option<SimpleGPU>,
19    /// Storage summary
20    pub storage: SimpleStorage,
21    /// System health status
22    pub health: SystemHealth,
23    /// Environment type (native, container, VM, etc.)
24    pub environment: String,
25    /// Overall performance score (0-100)
26    pub performance_score: u8,
27}
28
29/// Simplified CPU information
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct SimpleCPU {
32    /// CPU model name
33    pub name: String,
34    /// Number of physical cores
35    pub cores: u32,
36    /// Number of logical cores (threads)
37    pub threads: u32,
38    /// Vendor (Intel, AMD, Apple, etc.)
39    pub vendor: String,
40    /// Supports AI acceleration features
41    pub ai_capable: bool,
42}
43
44/// Simplified GPU information
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct SimpleGPU {
47    /// GPU model name
48    pub name: String,
49    /// VRAM in GB
50    pub vram_gb: f64,
51    /// Vendor (NVIDIA, AMD, Intel, etc.)
52    pub vendor: String,
53    /// Supports hardware acceleration for AI/ML
54    pub ai_capable: bool,
55}
56
57/// Simplified storage summary
58#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct SimpleStorage {
60    /// Total storage capacity in GB
61    pub total_gb: f64,
62    /// Available storage in GB
63    pub available_gb: f64,
64    /// Primary drive type (SSD, HDD, NVMe, etc.)
65    pub drive_type: String,
66    /// Storage health (Good, Warning, Critical)
67    pub health: String,
68}
69
70/// System health overview
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct SystemHealth {
73    /// Overall health status
74    pub status: HealthStatus,
75    /// Current temperature status
76    pub temperature: TemperatureStatus,
77    /// Power consumption level
78    pub power: PowerStatus,
79    /// Any warnings or recommendations
80    pub warnings: Vec<String>,
81}
82
83/// Overall system health status
84#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
85pub enum HealthStatus {
86    /// Everything is running optimally
87    Excellent,
88    /// System is running well
89    Good,
90    /// Minor issues detected
91    Fair,
92    /// Significant issues that should be addressed
93    Poor,
94    /// Critical issues requiring immediate attention
95    Critical,
96}
97
98/// Temperature status
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
100pub enum TemperatureStatus {
101    /// Temperatures are normal
102    Normal,
103    /// Temperatures are elevated but acceptable
104    Warm,
105    /// High temperatures detected
106    Hot,
107    /// Critical temperatures that may cause throttling
108    Critical,
109}
110
111/// Power consumption status
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
113pub enum PowerStatus {
114    /// Low power consumption
115    Low,
116    /// Normal power consumption
117    Normal,
118    /// High power consumption
119    High,
120    /// Very high power consumption
121    VeryHigh,
122}
123
124/// Simplified hardware query functions
125impl SystemOverview {
126    /// Get a quick system overview with the most important information
127    pub fn quick() -> Result<Self> {
128        let hw_info = HardwareInfo::query()?;
129        Self::from_hardware_info(hw_info)
130    }
131
132    /// Create a system overview from detailed hardware information
133    pub fn from_hardware_info(hw_info: HardwareInfo) -> Result<Self> {
134        let cpu = SimpleCPU {
135            name: hw_info.cpu().model_name().to_string(),
136            cores: hw_info.cpu().physical_cores(),
137            threads: hw_info.cpu().logical_cores(),
138            vendor: hw_info.cpu().vendor().to_string(),
139            ai_capable: Self::check_cpu_ai_capabilities(&hw_info),
140        };
141
142        let memory_gb = hw_info.memory().total_gb();
143
144        let gpu = if !hw_info.gpus().is_empty() {
145            let primary_gpu = &hw_info.gpus()[0];
146            Some(SimpleGPU {
147                name: primary_gpu.model_name().to_string(),
148                vram_gb: primary_gpu.memory_gb(),
149                vendor: primary_gpu.vendor().to_string(),
150                ai_capable: Self::check_gpu_ai_capabilities(primary_gpu),
151            })
152        } else {
153            None
154        };
155
156        let storage = Self::calculate_storage_summary(&hw_info)?;
157        let health = Self::assess_system_health(&hw_info)?;
158        let environment = hw_info.virtualization().environment_type.to_string();
159        let performance_score = Self::calculate_performance_score(&hw_info);
160
161        Ok(Self {
162            cpu,
163            memory_gb,
164            gpu,
165            storage,
166            health,
167            environment,
168            performance_score,
169        })
170    }
171
172    /// Check if the system is suitable for AI/ML workloads
173    pub fn is_ai_ready(&self) -> bool {
174        // Basic AI readiness check
175        self.cpu.ai_capable || 
176        self.gpu.as_ref().map_or(false, |gpu| gpu.ai_capable) ||
177        self.memory_gb >= 8.0
178    }
179
180    /// Get AI/ML suitability score (0-100)
181    pub fn ai_score(&self) -> u8 {
182        let mut score = 0;
183
184        // GPU contribution (50 points max)
185        if let Some(gpu) = &self.gpu {
186            if gpu.ai_capable {
187                score += 30;
188                if gpu.vram_gb >= 8.0 {
189                    score += 15;
190                } else if gpu.vram_gb >= 4.0 {
191                    score += 10;
192                } else {
193                    score += 5;
194                }
195            }
196        }
197
198        // CPU contribution (25 points max)
199        if self.cpu.ai_capable {
200            score += 15;
201        }
202        if self.cpu.cores >= 8 {
203            score += 10;
204        } else if self.cpu.cores >= 4 {
205            score += 5;
206        }
207
208        // Memory contribution (25 points max)
209        if self.memory_gb >= 32.0 {
210            score += 25;
211        } else if self.memory_gb >= 16.0 {
212            score += 20;
213        } else if self.memory_gb >= 8.0 {
214            score += 15;
215        } else {
216            score += 5;
217        }
218
219        score.min(100)
220    }
221
222    /// Get simple recommendations for improving system performance
223    pub fn get_recommendations(&self) -> Vec<String> {
224        let mut recommendations = Vec::new();
225
226        // Memory recommendations
227        if self.memory_gb < 16.0 {
228            recommendations.push("Consider upgrading to 16GB+ RAM for better performance".to_string());
229        }
230
231        // GPU recommendations
232        if self.gpu.is_none() {
233            recommendations.push("Add a dedicated GPU for AI/ML acceleration".to_string());
234        } else if let Some(gpu) = &self.gpu {
235            if gpu.vram_gb < 4.0 {
236                recommendations.push("Consider a GPU with more VRAM for large AI models".to_string());
237            }
238        }
239
240        // Storage recommendations
241        if self.storage.drive_type.to_lowercase().contains("hdd") {
242            recommendations.push("Upgrade to SSD for faster data access".to_string());
243        }
244
245        // Health recommendations
246        for warning in &self.health.warnings {
247            recommendations.push(warning.clone());
248        }
249
250        recommendations
251    }
252
253    fn check_cpu_ai_capabilities(hw_info: &HardwareInfo) -> bool {
254        let cpu = hw_info.cpu();
255        // Check for AI-relevant features
256        cpu.has_feature("avx2") || 
257        cpu.has_feature("avx512") || 
258        cpu.has_feature("amx") ||
259        !hw_info.npus().is_empty()
260    }
261
262    fn check_gpu_ai_capabilities(gpu: &crate::GPUInfo) -> bool {
263        // Check if GPU supports common AI frameworks
264        let vendor = gpu.vendor().to_string().to_lowercase();
265        let name = gpu.model_name().to_lowercase();
266        
267        // NVIDIA GPUs generally support CUDA
268        if vendor.contains("nvidia") {
269            return true;
270        }
271        
272        // AMD GPUs with ROCm support
273        if vendor.contains("amd") && (name.contains("rx") || name.contains("radeon")) {
274            return true;
275        }
276        
277        // Intel Arc GPUs
278        if vendor.contains("intel") && name.contains("arc") {
279            return true;
280        }
281        
282        false
283    }
284
285    fn calculate_storage_summary(hw_info: &HardwareInfo) -> Result<SimpleStorage> {
286        let storage_devices = hw_info.storage_devices();
287        
288        if storage_devices.is_empty() {
289            return Ok(SimpleStorage {
290                total_gb: 0.0,
291                available_gb: 0.0,
292                drive_type: "Unknown".to_string(),
293                health: "Unknown".to_string(),
294            });
295        }
296
297        let total_gb: f64 = storage_devices.iter()
298            .map(|device| device.capacity_gb())
299            .sum();
300
301        let available_gb: f64 = storage_devices.iter()
302            .map(|device| device.available_gb())
303            .sum();
304
305        // Get primary drive type
306        let drive_type = storage_devices[0].drive_type().to_string();
307
308        // Simple health assessment
309        let health = if available_gb / total_gb < 0.1 {
310            "Critical - Low space".to_string()
311        } else if available_gb / total_gb < 0.2 {
312            "Warning - Low space".to_string()
313        } else {
314            "Good".to_string()
315        };
316
317        Ok(SimpleStorage {
318            total_gb,
319            available_gb,
320            drive_type,
321            health,
322        })
323    }
324
325    fn assess_system_health(hw_info: &HardwareInfo) -> Result<SystemHealth> {
326        let mut warnings = Vec::new();
327        
328        // Temperature assessment
329        let thermal = hw_info.thermal();
330        let temperature = if let Some(max_temp) = thermal.max_temperature() {
331            if max_temp >= 90.0 {
332                warnings.push("High CPU/GPU temperatures detected".to_string());
333                TemperatureStatus::Critical
334            } else if max_temp >= 80.0 {
335                warnings.push("Elevated temperatures detected".to_string());
336                TemperatureStatus::Hot
337            } else if max_temp >= 70.0 {
338                TemperatureStatus::Warm
339            } else {
340                TemperatureStatus::Normal
341            }
342        } else {
343            TemperatureStatus::Normal
344        };
345
346        // Power assessment
347        let power = if let Some(power_profile) = hw_info.power_profile() {
348            if let Some(power_draw) = power_profile.total_power_draw {
349                if power_draw > 200.0 {
350                    PowerStatus::VeryHigh
351                } else if power_draw > 100.0 {
352                    PowerStatus::High
353                } else if power_draw > 50.0 {
354                    PowerStatus::Normal
355                } else {
356                    PowerStatus::Low
357                }
358            } else {
359                PowerStatus::Normal
360            }
361        } else {
362            PowerStatus::Normal
363        };
364
365        // Overall health status
366        let status = match (&temperature, &power, warnings.len()) {
367            (TemperatureStatus::Critical, _, _) => HealthStatus::Critical,
368            (TemperatureStatus::Hot, PowerStatus::VeryHigh, _) => HealthStatus::Poor,
369            (TemperatureStatus::Hot, _, _) => HealthStatus::Fair,
370            (_, PowerStatus::VeryHigh, _) => HealthStatus::Fair,
371            (_, _, n) if n > 2 => HealthStatus::Poor,
372            (_, _, n) if n > 0 => HealthStatus::Fair,
373            (TemperatureStatus::Normal, PowerStatus::Normal | PowerStatus::Low, 0) => HealthStatus::Excellent,
374            _ => HealthStatus::Good,
375        };
376
377        Ok(SystemHealth {
378            status,
379            temperature,
380            power,
381            warnings,
382        })
383    }
384
385    fn calculate_performance_score(hw_info: &HardwareInfo) -> u8 {
386        let mut score = 0;
387
388        // CPU score (30 points)
389        let cpu_cores = hw_info.cpu().logical_cores();
390        score += match cpu_cores {
391            cores if cores >= 16 => 30,
392            cores if cores >= 8 => 25,
393            cores if cores >= 4 => 20,
394            _ => 10,
395        };
396
397        // Memory score (25 points)
398        let memory_gb = hw_info.memory().total_gb();
399        score += match memory_gb {
400            mem if mem >= 32.0 => 25,
401            mem if mem >= 16.0 => 20,
402            mem if mem >= 8.0 => 15,
403            _ => 5,
404        };
405
406        // GPU score (30 points)
407        if !hw_info.gpus().is_empty() {
408            let gpu = &hw_info.gpus()[0];
409            let vram = gpu.memory_gb();
410            score += match vram {
411                vram if vram >= 12.0 => 30,
412                vram if vram >= 8.0 => 25,
413                vram if vram >= 4.0 => 20,
414                _ => 10,
415            };
416        }
417
418        // Storage score (15 points)
419        let storage_devices = hw_info.storage_devices();
420        if !storage_devices.is_empty() {
421            let storage_type = storage_devices[0].drive_type().to_string().to_lowercase();
422            score += if storage_type.contains("nvme") {
423                15
424            } else if storage_type.contains("ssd") {
425                12
426            } else {
427                5
428            };
429        }
430
431        // Virtualization penalty
432        let virt_factor = hw_info.virtualization().get_performance_factor();
433        score = ((score as f64) * virt_factor) as u8;
434
435        score.min(100)
436    }
437}
438
439// Display implementations for better debugging
440impl std::fmt::Display for HealthStatus {
441    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
442        match self {
443            HealthStatus::Excellent => write!(f, "Excellent"),
444            HealthStatus::Good => write!(f, "Good"),
445            HealthStatus::Fair => write!(f, "Fair"),
446            HealthStatus::Poor => write!(f, "Poor"),
447            HealthStatus::Critical => write!(f, "Critical"),
448        }
449    }
450}
451
452impl std::fmt::Display for TemperatureStatus {
453    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454        match self {
455            TemperatureStatus::Normal => write!(f, "Normal"),
456            TemperatureStatus::Warm => write!(f, "Warm"),
457            TemperatureStatus::Hot => write!(f, "Hot"),
458            TemperatureStatus::Critical => write!(f, "Critical"),
459        }
460    }
461}
462
463impl std::fmt::Display for PowerStatus {
464    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465        match self {
466            PowerStatus::Low => write!(f, "Low"),
467            PowerStatus::Normal => write!(f, "Normal"),
468            PowerStatus::High => write!(f, "High"),
469            PowerStatus::VeryHigh => write!(f, "Very High"),
470        }
471    }
472}