hardware_query/
builder.rs

1//! Hardware query builder for customizable hardware information gathering
2//!
3//! This module provides a builder pattern for creating customized hardware queries,
4//! allowing developers to request only the information they need without the
5//! overhead of collecting all available hardware data.
6
7use crate::{
8    HardwareInfo, CPUInfo, GPUInfo, MemoryInfo, StorageInfo, NetworkInfo, 
9    BatteryInfo, ThermalInfo, PCIDevice, USBDevice, VirtualizationInfo,
10    Result,
11};
12
13#[cfg(feature = "monitoring")]
14use crate::PowerProfile;
15
16use serde::{Serialize, Deserialize};
17
18/// Hardware query builder for selective information gathering
19pub struct HardwareQueryBuilder {
20    include_cpu: bool,
21    include_gpu: bool,
22    include_memory: bool,
23    include_storage: bool,
24    include_network: bool,
25    include_battery: bool,
26    include_thermal: bool,
27    include_pci: bool,
28    include_usb: bool,
29    include_virtualization: bool,
30    include_capabilities: bool,
31    
32    #[cfg(feature = "monitoring")]
33    include_power: bool,
34}
35
36/// Customizable hardware information result
37#[derive(Debug, Serialize, Deserialize)]
38pub struct CustomHardwareInfo {
39    pub cpu: Option<CPUInfo>,
40    pub gpus: Vec<GPUInfo>,
41    pub memory: Option<MemoryInfo>,
42    pub storage_devices: Vec<StorageInfo>,
43    pub network_interfaces: Vec<NetworkInfo>,
44    pub battery: Option<BatteryInfo>,
45    pub thermal: Option<ThermalInfo>,
46    pub pci_devices: Vec<PCIDevice>,
47    pub usb_devices: Vec<USBDevice>,
48    pub virtualization: Option<VirtualizationInfo>,
49    
50    #[cfg(feature = "monitoring")]
51    pub power_profile: Option<PowerProfile>,
52    
53    /// Timestamp when this information was collected
54    pub timestamp: std::time::SystemTime,
55    /// Query execution time in milliseconds
56    pub query_time_ms: u64,
57    /// Which components were requested
58    pub requested_components: Vec<String>,
59}
60
61impl HardwareQueryBuilder {
62    /// Create a new hardware query builder
63    pub fn new() -> Self {
64        Self {
65            include_cpu: false,
66            include_gpu: false,
67            include_memory: false,
68            include_storage: false,
69            include_network: false,
70            include_battery: false,
71            include_thermal: false,
72            include_pci: false,
73            include_usb: false,
74            include_virtualization: false,
75            include_capabilities: false,
76            
77            #[cfg(feature = "monitoring")]
78            include_power: false,
79        }
80    }
81
82    /// Include CPU information in the query
83    pub fn with_cpu(mut self) -> Self {
84        self.include_cpu = true;
85        self
86    }
87
88    /// Include GPU information in the query
89    pub fn with_gpu(mut self) -> Self {
90        self.include_gpu = true;
91        self
92    }
93
94    /// Include memory information in the query
95    pub fn with_memory(mut self) -> Self {
96        self.include_memory = true;
97        self
98    }
99
100    /// Include storage information in the query
101    pub fn with_storage(mut self) -> Self {
102        self.include_storage = true;
103        self
104    }
105
106    /// Include network information in the query
107    pub fn with_network(mut self) -> Self {
108        self.include_network = true;
109        self
110    }
111
112    /// Include battery information in the query
113    pub fn with_battery(mut self) -> Self {
114        self.include_battery = true;
115        self
116    }
117
118    /// Include thermal information in the query
119    pub fn with_thermal(mut self) -> Self {
120        self.include_thermal = true;
121        self
122    }
123
124    /// Include PCI device information in the query
125    pub fn with_pci(mut self) -> Self {
126        self.include_pci = true;
127        self
128    }
129
130    /// Include USB device information in the query
131    pub fn with_usb(mut self) -> Self {
132        self.include_usb = true;
133        self
134    }
135
136    /// Include virtualization information in the query
137    pub fn with_virtualization(mut self) -> Self {
138        self.include_virtualization = true;
139        self
140    }
141
142    /// Include power management information (requires monitoring feature)
143    #[cfg(feature = "monitoring")]
144    pub fn with_power(mut self) -> Self {
145        self.include_power = true;
146        self
147    }
148
149    /// Include all available hardware information
150    pub fn with_all(mut self) -> Self {
151        self.include_cpu = true;
152        self.include_gpu = true;
153        self.include_memory = true;
154        self.include_storage = true;
155        self.include_network = true;
156        self.include_battery = true;
157        self.include_thermal = true;
158        self.include_pci = true;
159        self.include_usb = true;
160        self.include_virtualization = true;
161        
162        #[cfg(feature = "monitoring")]
163        {
164            self.include_power = true;
165        }
166        
167        self
168    }
169
170    /// Include basic system information (CPU, memory, storage)
171    pub fn with_basic(mut self) -> Self {
172        self.include_cpu = true;
173        self.include_memory = true;
174        self.include_storage = true;
175        self
176    }
177
178    /// Include AI/ML relevant information (CPU, GPU, memory)
179    pub fn with_ai_focused(mut self) -> Self {
180        self.include_cpu = true;
181        self.include_gpu = true;
182        self.include_memory = true;
183        self.include_thermal = true;
184        self.include_virtualization = true;
185        
186        #[cfg(feature = "monitoring")]
187        {
188            self.include_power = true;
189        }
190        
191        self
192    }
193
194    /// Include gaming-relevant information (CPU, GPU, memory, thermal)
195    pub fn with_gaming_focused(mut self) -> Self {
196        self.include_cpu = true;
197        self.include_gpu = true;
198        self.include_memory = true;
199        self.include_thermal = true;
200        self.include_storage = true;
201        self
202    }
203
204    /// Include server/enterprise relevant information
205    pub fn with_server_focused(mut self) -> Self {
206        self.include_cpu = true;
207        self.include_memory = true;
208        self.include_storage = true;
209        self.include_network = true;
210        self.include_thermal = true;
211        self.include_pci = true;
212        self.include_virtualization = true;
213        
214        #[cfg(feature = "monitoring")]
215        {
216            self.include_power = true;
217        }
218        
219        self
220    }
221
222    /// Filter GPUs by a custom predicate  
223    pub fn filter_gpus<F>(self, _filter: F) -> Self 
224    where
225        F: Fn(&GPUInfo) -> bool + 'static,
226    {
227        // TODO: Implement filtering in a future version
228        self
229    }
230
231    /// Filter storage devices by a custom predicate
232    pub fn filter_storage<F>(self, _filter: F) -> Self 
233    where
234        F: Fn(&StorageInfo) -> bool + 'static,
235    {
236        // TODO: Implement filtering in a future version
237        self
238    }
239
240    /// Filter network interfaces by a custom predicate
241    pub fn filter_network<F>(self, _filter: F) -> Self 
242    where
243        F: Fn(&NetworkInfo) -> bool + 'static,
244    {
245        // TODO: Implement filtering in a future version
246        self
247    }
248
249    /// Execute the query and return the requested hardware information
250    pub fn query(self) -> Result<CustomHardwareInfo> {
251        let start_time = std::time::Instant::now();
252        let timestamp = std::time::SystemTime::now();
253        
254        // Track which components were requested
255        let mut requested_components = Vec::new();
256        
257        // Get full hardware info first (we'll optimize this later)
258        let full_hw = HardwareInfo::query()?;
259        
260        // Extract requested components
261        let cpu = if self.include_cpu {
262            requested_components.push("CPU".to_string());
263            Some(full_hw.cpu().clone())
264        } else {
265            None
266        };
267
268        let gpus = if self.include_gpu {
269            requested_components.push("GPU".to_string());
270            full_hw.gpus().to_vec()
271        } else {
272            Vec::new()
273        };
274
275        let memory = if self.include_memory {
276            requested_components.push("Memory".to_string());
277            Some(full_hw.memory().clone())
278        } else {
279            None
280        };
281
282        let storage_devices = if self.include_storage {
283            requested_components.push("Storage".to_string());
284            full_hw.storage_devices().to_vec()
285        } else {
286            Vec::new()
287        };
288
289        let network_interfaces = if self.include_network {
290            requested_components.push("Network".to_string());
291            full_hw.network_interfaces().to_vec()
292        } else {
293            Vec::new()
294        };
295
296        let battery = if self.include_battery {
297            requested_components.push("Battery".to_string());
298            full_hw.battery().cloned()
299        } else {
300            None
301        };
302
303        let thermal = if self.include_thermal {
304            requested_components.push("Thermal".to_string());
305            Some(full_hw.thermal().clone())
306        } else {
307            None
308        };
309
310        let pci_devices = if self.include_pci {
311            requested_components.push("PCI".to_string());
312            full_hw.pci_devices().to_vec()
313        } else {
314            Vec::new()
315        };
316
317        let usb_devices = if self.include_usb {
318            requested_components.push("USB".to_string());
319            full_hw.usb_devices().to_vec()
320        } else {
321            Vec::new()
322        };
323
324        let virtualization = if self.include_virtualization {
325            requested_components.push("Virtualization".to_string());
326            Some(full_hw.virtualization().clone())
327        } else {
328            None
329        };
330
331        #[cfg(feature = "monitoring")]
332        let power_profile = if self.include_power {
333            requested_components.push("Power".to_string());
334            full_hw.power_profile().cloned()
335        } else {
336            None
337        };
338
339        let query_time_ms = start_time.elapsed().as_millis() as u64;
340
341        Ok(CustomHardwareInfo {
342            cpu,
343            gpus,
344            memory,
345            storage_devices,
346            network_interfaces,
347            battery,
348            thermal,
349            pci_devices,
350            usb_devices,
351            virtualization,
352            
353            #[cfg(feature = "monitoring")]
354            power_profile,
355            
356            timestamp,
357            query_time_ms,
358            requested_components,
359        })
360    }
361
362    /// Execute a quick query that only gathers essential information
363    pub fn quick_query(self) -> Result<CustomHardwareInfo> {
364        // For quick queries, we can optimize by avoiding expensive operations
365        self.with_basic().query()
366    }
367}
368
369impl CustomHardwareInfo {
370    /// Check if a specific component was included in the query
371    pub fn has_component(&self, component: &str) -> bool {
372        self.requested_components.iter().any(|c| c.eq_ignore_ascii_case(component))
373    }
374
375    /// Get the total number of components that were queried
376    pub fn component_count(&self) -> usize {
377        self.requested_components.len()
378    }
379
380    /// Convert to a full HardwareInfo struct (filling missing components with defaults)
381    pub fn to_full_hardware_info(&self) -> HardwareInfo {
382        // This would require implementing Default for all the component types
383        // For now, we'll return an error if conversion is attempted with missing components
384        todo!("Implement conversion to full HardwareInfo")
385    }
386
387    /// Get a summary of what was queried
388    pub fn query_summary(&self) -> String {
389        format!(
390            "Queried {} components in {}ms: {}",
391            self.component_count(),
392            self.query_time_ms,
393            self.requested_components.join(", ")
394        )
395    }
396}
397
398// Convenience functions for common query patterns
399impl HardwareQueryBuilder {
400    /// Quick CPU and memory information
401    pub fn cpu_and_memory() -> Result<CustomHardwareInfo> {
402        Self::new().with_cpu().with_memory().query()
403    }
404
405    /// Quick GPU information for AI/gaming
406    pub fn gpu_info() -> Result<CustomHardwareInfo> {
407        Self::new().with_gpu().with_memory().query()
408    }
409
410    /// System health overview
411    pub fn health_check() -> Result<CustomHardwareInfo> {
412        Self::new()
413            .with_cpu()
414            .with_memory()
415            .with_thermal()
416            .with_battery()
417            .query()
418    }
419
420    /// Performance overview for gaming/AI
421    pub fn performance_check() -> Result<CustomHardwareInfo> {
422        Self::new()
423            .with_cpu()
424            .with_gpu()
425            .with_memory()
426            .with_storage()
427            .with_thermal()
428            .query()
429    }
430}