hardware_query/
simple.rs

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