1use crate::resources::{ResourceType, CapabilityLevel, ResourceAmount};
4use crate::types::{SystemInfo, CpuInfo, GpuInfo, MemoryInfo, StorageInfo, NetworkInfo};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct CapabilityProfile {
10 pub cpu_capabilities: CpuCapabilities,
12 pub gpu_capabilities: GpuCapabilities,
14 pub memory_capabilities: MemoryCapabilities,
16 pub storage_capabilities: StorageCapabilities,
18 pub network_capabilities: NetworkCapabilities,
20 pub scores: CapabilityScores,
22 pub metadata: CapabilityMetadata,
24}
25
26impl CapabilityProfile {
27 pub fn from_system_info(system_info: &SystemInfo) -> Self {
29 let cpu_capabilities = CpuCapabilities::from_cpu_info(&system_info.cpu_info);
30 let gpu_capabilities = GpuCapabilities::from_gpu_info(&system_info.gpu_info);
31 let memory_capabilities = MemoryCapabilities::from_memory_info(&system_info.memory_info);
32 let storage_capabilities = StorageCapabilities::from_storage_info(&system_info.storage_info);
33 let network_capabilities = NetworkCapabilities::from_network_info(&system_info.network_info);
34
35 let scores = CapabilityScores::calculate(
36 &cpu_capabilities,
37 &gpu_capabilities,
38 &memory_capabilities,
39 &storage_capabilities,
40 &network_capabilities,
41 );
42
43 let metadata = CapabilityMetadata {
44 analysis_version: "1.0".to_string(),
45 created_at: chrono::Utc::now(),
46 system_fingerprint: Self::generate_fingerprint(system_info),
47 };
48
49 Self {
50 cpu_capabilities,
51 gpu_capabilities,
52 memory_capabilities,
53 storage_capabilities,
54 network_capabilities,
55 scores,
56 metadata,
57 }
58 }
59
60 fn generate_fingerprint(system_info: &SystemInfo) -> String {
62 use std::collections::hash_map::DefaultHasher;
63 use std::hash::{Hash, Hasher};
64
65 let mut hasher = DefaultHasher::new();
66 system_info.cpu_info.brand.hash(&mut hasher);
67 system_info.cpu_info.physical_cores.hash(&mut hasher);
68 system_info.memory_info.total_ram.hash(&mut hasher);
69
70 for gpu in &system_info.gpu_info {
71 gpu.name.hash(&mut hasher);
72 gpu.vendor.hash(&mut hasher);
73 }
74
75 format!("{:x}", hasher.finish())
76 }
77
78 pub fn get_capability_level(&self, resource_type: &ResourceType) -> CapabilityLevel {
80 match resource_type {
81 ResourceType::CPU => self.scores.cpu_score.into(),
82 ResourceType::GPU => self.scores.gpu_score.into(),
83 ResourceType::Memory => self.scores.memory_score.into(),
84 ResourceType::Storage => self.scores.storage_score.into(),
85 ResourceType::Network => self.scores.network_score.into(),
86 ResourceType::Custom(_) => CapabilityLevel::Medium, }
88 }
89
90 pub fn get_resource_amount(&self, resource_type: &ResourceType) -> Option<ResourceAmount> {
92 match resource_type {
93 ResourceType::CPU => Some(ResourceAmount::Score(self.scores.cpu_score)),
94 ResourceType::GPU => Some(ResourceAmount::Score(self.scores.gpu_score)),
95 ResourceType::Memory => Some(ResourceAmount::Gigabytes(
96 self.memory_capabilities.total_ram_gb
97 )),
98 ResourceType::Storage => Some(ResourceAmount::Gigabytes(
99 self.storage_capabilities.total_capacity_gb
100 )),
101 ResourceType::Network => Some(ResourceAmount::Score(self.scores.network_score)),
102 ResourceType::Custom(_) => None,
103 }
104 }
105
106 pub fn supports_feature(&self, feature: &SystemFeature) -> bool {
108 match feature {
109 SystemFeature::CudaCompute => self.gpu_capabilities.cuda_support,
110 SystemFeature::OpenCLCompute => self.gpu_capabilities.opencl_support,
111 SystemFeature::AVXInstructions => self.cpu_capabilities.avx_support,
112 SystemFeature::NVMeStorage => self.storage_capabilities.nvme_support,
113 SystemFeature::HighBandwidthMemory => self.memory_capabilities.high_bandwidth,
114 SystemFeature::VirtualizationSupport => self.cpu_capabilities.virtualization_support,
115 SystemFeature::HighSpeedNetwork => self.network_capabilities.high_speed_support,
116 }
117 }
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct CpuCapabilities {
123 pub physical_cores: usize,
125 pub logical_cores: usize,
127 pub base_frequency_mhz: u64,
129 pub max_frequency_mhz: Option<u64>,
131 pub cache_size_mb: Option<u64>,
133 pub architecture: String,
135 pub instruction_sets: Vec<String>,
137 pub avx_support: bool,
139 pub virtualization_support: bool,
141 pub thread_performance: f64,
143 pub multicore_efficiency: f64,
145}
146
147impl CpuCapabilities {
148 pub fn from_cpu_info(cpu_info: &CpuInfo) -> Self {
150 let avx_support = cpu_info.brand.to_lowercase().contains("intel") ||
151 cpu_info.brand.to_lowercase().contains("amd");
152
153 let virtualization_support = cpu_info.logical_cores > cpu_info.physical_cores;
154
155 let thread_performance = Self::calculate_thread_performance(cpu_info);
156 let multicore_efficiency = Self::calculate_multicore_efficiency(cpu_info);
157
158 Self {
159 physical_cores: cpu_info.physical_cores,
160 logical_cores: cpu_info.logical_cores,
161 base_frequency_mhz: cpu_info.base_frequency,
162 max_frequency_mhz: cpu_info.max_frequency,
163 cache_size_mb: cpu_info.cache_size,
164 architecture: cpu_info.architecture.clone(),
165 instruction_sets: vec![], avx_support,
167 virtualization_support,
168 thread_performance,
169 multicore_efficiency,
170 }
171 }
172
173 fn calculate_thread_performance(cpu_info: &CpuInfo) -> f64 {
175 let base_score = (cpu_info.base_frequency as f64 / 1000.0).min(5.0); let cache_bonus = cpu_info.cache_size.map(|c| (c as f64 / 16.0).min(2.0)).unwrap_or(0.0); let arch_bonus = if cpu_info.architecture.contains("x86_64") { 1.0 } else { 0.5 };
178
179 (base_score + cache_bonus + arch_bonus).min(10.0)
180 }
181
182 fn calculate_multicore_efficiency(cpu_info: &CpuInfo) -> f64 {
184 let core_score = (cpu_info.physical_cores as f64 / 2.0).min(5.0); let hyperthreading_bonus = if cpu_info.logical_cores > cpu_info.physical_cores { 2.0 } else { 0.0 };
186 let architecture_bonus = if cpu_info.architecture.contains("x86_64") { 1.0 } else { 0.5 };
187
188 (core_score + hyperthreading_bonus + architecture_bonus).min(10.0)
189 }
190
191 pub fn ai_capability_level(&self) -> crate::resources::CapabilityLevel {
193 let combined_score = (self.thread_performance + self.multicore_efficiency) / 2.0;
194 crate::resources::CapabilityLevel::from_numeric(combined_score)
195 }
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct GpuCapabilities {
201 pub gpus: Vec<GpuDevice>,
203 pub primary_compute_gpu: Option<usize>,
205 pub total_vram_gb: f64,
207 pub cuda_support: bool,
209 pub opencl_support: bool,
211 pub ai_acceleration_score: f64,
213 pub graphics_score: f64,
215 pub compute_score: f64,
217}
218
219impl GpuCapabilities {
220 pub fn from_gpu_info(gpu_info: &[GpuInfo]) -> Self {
222 let gpus: Vec<GpuDevice> = gpu_info.iter().map(GpuDevice::from_gpu_info).collect();
223
224 let total_vram_gb = gpus.iter()
225 .map(|gpu| gpu.vram_gb.unwrap_or(0.0))
226 .sum();
227
228 let cuda_support = gpus.iter().any(|gpu| gpu.cuda_support);
229 let opencl_support = gpus.iter().any(|gpu| gpu.opencl_support);
230
231 let primary_compute_gpu = Self::find_best_compute_gpu(&gpus);
232
233 let ai_acceleration_score = Self::calculate_ai_score(&gpus);
234 let graphics_score = Self::calculate_graphics_score(&gpus);
235 let compute_score = Self::calculate_compute_score(&gpus);
236
237 Self {
238 gpus,
239 primary_compute_gpu,
240 total_vram_gb,
241 cuda_support,
242 opencl_support,
243 ai_acceleration_score,
244 graphics_score,
245 compute_score,
246 }
247 }
248
249 fn find_best_compute_gpu(gpus: &[GpuDevice]) -> Option<usize> {
251 gpus.iter()
252 .enumerate()
253 .max_by(|(_, a), (_, b)| a.compute_capability_score.partial_cmp(&b.compute_capability_score).unwrap())
254 .map(|(idx, _)| idx)
255 }
256
257 fn calculate_ai_score(gpus: &[GpuDevice]) -> f64 {
259 if gpus.is_empty() {
260 return 0.0;
261 }
262
263 let best_gpu = gpus.iter()
264 .max_by(|a, b| a.compute_capability_score.partial_cmp(&b.compute_capability_score).unwrap())
265 .unwrap();
266
267 let vram_score = best_gpu.vram_gb.map(|v| (v / 8.0).min(4.0)).unwrap_or(0.0); let vendor_bonus = if best_gpu.vendor.to_lowercase().contains("nvidia") { 3.0 } else { 1.0 };
269 let cuda_bonus = if best_gpu.cuda_support { 2.0 } else { 0.0 };
270
271 (vram_score + vendor_bonus + cuda_bonus).min(10.0)
272 }
273
274 fn calculate_graphics_score(gpus: &[GpuDevice]) -> f64 {
276 if gpus.is_empty() {
277 return 0.0;
278 }
279
280 let best_gpu = gpus.iter()
281 .max_by(|a, b| a.graphics_score.partial_cmp(&b.graphics_score).unwrap())
282 .unwrap();
283
284 best_gpu.graphics_score
285 }
286
287 fn calculate_compute_score(gpus: &[GpuDevice]) -> f64 {
289 if gpus.is_empty() {
290 return 0.0;
291 }
292
293 let best_gpu = gpus.iter()
294 .max_by(|a, b| a.compute_capability_score.partial_cmp(&b.compute_capability_score).unwrap())
295 .unwrap();
296
297 best_gpu.compute_capability_score
298 }
299}
300
301#[derive(Debug, Clone, Serialize, Deserialize)]
303pub struct GpuDevice {
304 pub name: String,
306 pub vendor: String,
308 pub vram_gb: Option<f64>,
310 pub compute_capability: Option<String>,
312 pub cuda_support: bool,
314 pub opencl_support: bool,
316 pub graphics_score: f64,
318 pub compute_capability_score: f64,
320 pub power_efficiency: f64,
322}
323
324impl GpuDevice {
325 pub fn from_gpu_info(gpu_info: &GpuInfo) -> Self {
327 let vram_gb = gpu_info.vram_size.map(|v| v as f64 / 1024.0);
328
329 let graphics_score = Self::calculate_graphics_score_for_device(gpu_info);
330 let compute_score = Self::calculate_compute_score_for_device(gpu_info);
331 let power_efficiency = Self::calculate_power_efficiency(gpu_info);
332
333 Self {
334 name: gpu_info.name.clone(),
335 vendor: gpu_info.vendor.clone(),
336 vram_gb,
337 compute_capability: gpu_info.compute_capability.clone(),
338 cuda_support: gpu_info.cuda_support,
339 opencl_support: gpu_info.opencl_support,
340 graphics_score,
341 compute_capability_score: compute_score,
342 power_efficiency,
343 }
344 }
345
346 fn calculate_graphics_score_for_device(gpu_info: &GpuInfo) -> f64 {
348 let vram_score = gpu_info.vram_size.map(|v| (v as f64 / 1024.0 / 4.0).min(3.0)).unwrap_or(0.0);
349 let vendor_score = match gpu_info.vendor.to_lowercase().as_str() {
350 vendor if vendor.contains("nvidia") => 4.0,
351 vendor if vendor.contains("amd") => 3.5,
352 vendor if vendor.contains("intel") => 2.0,
353 _ => 1.0,
354 };
355 let modern_bonus = if gpu_info.name.contains("RTX") || gpu_info.name.contains("RX") { 2.0 } else { 0.0 };
356
357 (vram_score + vendor_score + modern_bonus).min(10.0)
358 }
359
360 fn calculate_compute_score_for_device(gpu_info: &GpuInfo) -> f64 {
362 let mut score = 0.0;
363
364 if let Some(vram) = gpu_info.vram_size {
366 score += (vram as f64 / 1024.0 / 8.0).min(4.0); }
368
369 if gpu_info.cuda_support {
371 score += 3.0;
372 }
373
374 score += match gpu_info.vendor.to_lowercase().as_str() {
376 vendor if vendor.contains("nvidia") => 2.0,
377 vendor if vendor.contains("amd") => 1.5,
378 vendor if vendor.contains("intel") => 0.5,
379 _ => 0.0,
380 };
381
382 if gpu_info.name.contains("RTX") || gpu_info.name.contains("A100") || gpu_info.name.contains("H100") {
384 score += 1.0;
385 }
386
387 score.min(10.0)
388 }
389
390 fn calculate_power_efficiency(gpu_info: &GpuInfo) -> f64 {
392 match gpu_info.vendor.to_lowercase().as_str() {
395 vendor if vendor.contains("nvidia") && gpu_info.name.contains("RTX") => 8.0,
396 vendor if vendor.contains("amd") && gpu_info.name.contains("RX") => 7.0,
397 vendor if vendor.contains("intel") => 6.0,
398 _ => 5.0,
399 }
400 }
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize)]
405pub struct MemoryCapabilities {
406 pub total_ram_gb: f64,
408 pub available_ram_gb: f64,
410 pub memory_type: Option<String>,
412 pub memory_speed_mhz: Option<u64>,
414 pub bandwidth_score: f64,
416 pub capacity_score: f64,
418 pub high_bandwidth: bool,
420 pub ecc_support: bool,
422}
423
424impl MemoryCapabilities {
425 pub fn from_memory_info(memory_info: &MemoryInfo) -> Self {
427 let total_ram_gb = memory_info.total_ram as f64 / 1024.0;
428 let available_ram_gb = memory_info.available_ram as f64 / 1024.0;
429
430 let capacity_score = Self::calculate_capacity_score(total_ram_gb);
431 let bandwidth_score = Self::calculate_bandwidth_score(memory_info);
432
433 let high_bandwidth = memory_info.memory_speed.map(|s| s >= 3200).unwrap_or(false);
434 let ecc_support = memory_info.memory_type.as_ref()
435 .map(|t| t.to_lowercase().contains("ecc"))
436 .unwrap_or(false);
437
438 Self {
439 total_ram_gb,
440 available_ram_gb,
441 memory_type: memory_info.memory_type.clone(),
442 memory_speed_mhz: memory_info.memory_speed,
443 bandwidth_score,
444 capacity_score,
445 high_bandwidth,
446 ecc_support,
447 }
448 }
449
450 fn calculate_capacity_score(total_gb: f64) -> f64 {
452 match total_gb {
453 gb if gb >= 128.0 => 10.0,
454 gb if gb >= 64.0 => 9.0,
455 gb if gb >= 32.0 => 8.0,
456 gb if gb >= 16.0 => 7.0,
457 gb if gb >= 8.0 => 5.0,
458 gb if gb >= 4.0 => 3.0,
459 _ => 1.0,
460 }
461 }
462
463 fn calculate_bandwidth_score(memory_info: &MemoryInfo) -> f64 {
465 let speed_score = memory_info.memory_speed
466 .map(|speed| (speed as f64 / 800.0).min(5.0)) .unwrap_or(2.0);
468
469 let type_bonus = memory_info.memory_type.as_ref()
470 .map(|t| match t.to_lowercase().as_str() {
471 t if t.contains("ddr5") => 3.0,
472 t if t.contains("ddr4") => 2.0,
473 t if t.contains("ddr3") => 1.0,
474 _ => 0.5,
475 })
476 .unwrap_or(1.0);
477
478 (speed_score + type_bonus).min(10.0)
479 }
480}
481
482#[derive(Debug, Clone, Serialize, Deserialize)]
484pub struct StorageCapabilities {
485 pub devices: Vec<StorageDevice>,
487 pub total_capacity_gb: f64,
489 pub available_capacity_gb: f64,
491 pub performance_score: f64,
493 pub nvme_support: bool,
495 pub ssd_ratio: f64,
497}
498
499impl StorageCapabilities {
500 pub fn from_storage_info(storage_info: &[StorageInfo]) -> Self {
502 let devices: Vec<StorageDevice> = storage_info.iter()
503 .map(StorageDevice::from_storage_info)
504 .collect();
505
506 let total_capacity_gb = devices.iter()
507 .map(|d| d.total_capacity_gb)
508 .sum();
509
510 let available_capacity_gb = devices.iter()
511 .map(|d| d.available_capacity_gb)
512 .sum();
513
514 let performance_score = devices.iter()
515 .map(|d| d.performance_score)
516 .fold(0.0, f64::max);
517
518 let nvme_support = devices.iter()
519 .any(|d| d.storage_type.to_lowercase().contains("nvme"));
520
521 let ssd_capacity: f64 = devices.iter()
522 .filter(|d| d.is_ssd())
523 .map(|d| d.total_capacity_gb)
524 .sum();
525
526 let ssd_ratio = if total_capacity_gb > 0.0 {
527 ssd_capacity / total_capacity_gb * 100.0
528 } else {
529 0.0
530 };
531
532 Self {
533 devices,
534 total_capacity_gb,
535 available_capacity_gb,
536 performance_score,
537 nvme_support,
538 ssd_ratio,
539 }
540 }
541}
542
543#[derive(Debug, Clone, Serialize, Deserialize)]
545pub struct StorageDevice {
546 pub name: String,
548 pub storage_type: String,
550 pub total_capacity_gb: f64,
552 pub available_capacity_gb: f64,
554 pub read_speed_mbps: Option<u64>,
556 pub write_speed_mbps: Option<u64>,
558 pub performance_score: f64,
560 pub reliability_score: f64,
562}
563
564impl StorageDevice {
565 pub fn from_storage_info(storage_info: &StorageInfo) -> Self {
567 let performance_score = Self::calculate_performance_score(storage_info);
568 let reliability_score = Self::calculate_reliability_score(storage_info);
569
570 Self {
571 name: storage_info.name.clone(),
572 storage_type: storage_info.storage_type.clone(),
573 total_capacity_gb: storage_info.total_capacity as f64,
574 available_capacity_gb: storage_info.available_capacity as f64,
575 read_speed_mbps: storage_info.read_speed,
576 write_speed_mbps: storage_info.write_speed,
577 performance_score,
578 reliability_score,
579 }
580 }
581
582 pub fn is_ssd(&self) -> bool {
584 let storage_type = self.storage_type.to_lowercase();
585 storage_type.contains("ssd") || storage_type.contains("nvme")
586 }
587
588 fn calculate_performance_score(storage_info: &StorageInfo) -> f64 {
590 let type_score = match storage_info.storage_type.to_lowercase().as_str() {
591 t if t.contains("nvme") => 8.0,
592 t if t.contains("ssd") => 6.0,
593 t if t.contains("hdd") => 2.0,
594 _ => 3.0,
595 };
596
597 let speed_bonus = storage_info.read_speed
598 .map(|s| (s as f64 / 1000.0).min(2.0)) .unwrap_or(0.0);
600
601 (type_score + speed_bonus).min(10.0)
602 }
603
604 fn calculate_reliability_score(storage_info: &StorageInfo) -> f64 {
606 match storage_info.storage_type.to_lowercase().as_str() {
607 t if t.contains("nvme") => 9.0,
608 t if t.contains("ssd") => 8.0,
609 t if t.contains("hdd") => 6.0,
610 _ => 5.0,
611 }
612 }
613}
614
615#[derive(Debug, Clone, Serialize, Deserialize)]
617pub struct NetworkCapabilities {
618 pub interfaces: Vec<NetworkInterface>,
620 pub internet_connected: bool,
622 pub estimated_bandwidth_mbps: Option<u64>,
624 pub performance_score: f64,
626 pub high_speed_support: bool,
628 pub estimated_latency_ms: Option<f64>,
630}
631
632impl NetworkCapabilities {
633 pub fn from_network_info(network_info: &NetworkInfo) -> Self {
635 let interfaces: Vec<NetworkInterface> = network_info.interfaces.iter()
636 .map(NetworkInterface::from_network_interface_info)
637 .collect();
638
639 let performance_score = Self::calculate_network_performance(&interfaces, network_info.estimated_bandwidth);
640 let high_speed_support = network_info.estimated_bandwidth
641 .map(|b| b >= 1000)
642 .unwrap_or(false);
643
644 Self {
645 interfaces,
646 internet_connected: network_info.internet_connected,
647 estimated_bandwidth_mbps: network_info.estimated_bandwidth,
648 performance_score,
649 high_speed_support,
650 estimated_latency_ms: None, }
652 }
653
654 fn calculate_network_performance(interfaces: &[NetworkInterface], bandwidth: Option<u64>) -> f64 {
656 let bandwidth_score = bandwidth
657 .map(|b| (b as f64 / 100.0).min(5.0)) .unwrap_or(1.0);
659
660 let interface_score = if interfaces.iter().any(|i| i.is_high_speed()) {
661 3.0
662 } else if interfaces.iter().any(|i| i.is_ethernet()) {
663 2.0
664 } else {
665 1.0
666 };
667
668 let connection_bonus = if interfaces.iter().any(|i| !i.ip_addresses.is_empty()) {
669 2.0
670 } else {
671 0.0
672 };
673
674 (bandwidth_score + interface_score + connection_bonus).min(10.0)
675 }
676}
677
678#[derive(Debug, Clone, Serialize, Deserialize)]
680pub struct NetworkInterface {
681 pub name: String,
683 pub interface_type: String,
685 pub mac_address: String,
687 pub ip_addresses: Vec<String>,
689 pub speed_mbps: Option<u64>,
691 pub quality_score: f64,
693}
694
695impl NetworkInterface {
696 pub fn from_network_interface_info(interface_info: &crate::types::NetworkInterface) -> Self {
698 let quality_score = Self::calculate_quality_score(interface_info);
699
700 Self {
701 name: interface_info.name.clone(),
702 interface_type: interface_info.interface_type.clone(),
703 mac_address: interface_info.mac_address.clone(),
704 ip_addresses: interface_info.ip_addresses.clone(),
705 speed_mbps: interface_info.speed,
706 quality_score,
707 }
708 }
709
710 pub fn is_high_speed(&self) -> bool {
712 self.speed_mbps.map(|s| s >= 1000).unwrap_or(false)
713 }
714
715 pub fn is_ethernet(&self) -> bool {
717 self.interface_type.to_lowercase().contains("ethernet")
718 }
719
720 fn calculate_quality_score(interface_info: &crate::types::NetworkInterface) -> f64 {
722 let type_score = match interface_info.interface_type.to_lowercase().as_str() {
723 t if t.contains("ethernet") => 4.0,
724 t if t.contains("wifi") => 3.0,
725 t if t.contains("wireless") => 3.0,
726 _ => 2.0,
727 };
728
729 let speed_score = interface_info.speed
730 .map(|s| (s as f64 / 500.0).min(3.0)) .unwrap_or(1.0);
732
733 let connection_bonus = if !interface_info.ip_addresses.is_empty() {
734 3.0
735 } else {
736 0.0
737 };
738
739 (type_score + speed_score + connection_bonus).min(10.0)
740 }
741}
742
743#[derive(Debug, Clone, Serialize, Deserialize)]
745pub struct CapabilityScores {
746 pub cpu_score: f64,
748 pub gpu_score: f64,
750 pub memory_score: f64,
752 pub storage_score: f64,
754 pub network_score: f64,
756 pub overall_score: f64,
758}
759
760impl CapabilityScores {
761 pub fn calculate(
763 cpu: &CpuCapabilities,
764 gpu: &GpuCapabilities,
765 memory: &MemoryCapabilities,
766 storage: &StorageCapabilities,
767 network: &NetworkCapabilities,
768 ) -> Self {
769 let cpu_score = (cpu.thread_performance + cpu.multicore_efficiency) / 2.0;
770 let gpu_score = (gpu.ai_acceleration_score + gpu.compute_score) / 2.0;
771 let memory_score = (memory.capacity_score + memory.bandwidth_score) / 2.0;
772 let storage_score = storage.performance_score;
773 let network_score = network.performance_score;
774
775 let overall_score = (cpu_score + gpu_score + memory_score + storage_score + network_score) / 5.0;
776
777 Self {
778 cpu_score,
779 gpu_score,
780 memory_score,
781 storage_score,
782 network_score,
783 overall_score,
784 }
785 }
786}
787
788#[derive(Debug, Clone, Serialize, Deserialize)]
790pub struct CapabilityMetadata {
791 pub analysis_version: String,
793 pub created_at: chrono::DateTime<chrono::Utc>,
795 pub system_fingerprint: String,
797}
798
799#[derive(Debug, Clone, Copy, PartialEq, Eq)]
801pub enum SystemFeature {
802 CudaCompute,
804 OpenCLCompute,
806 AVXInstructions,
808 NVMeStorage,
810 HighBandwidthMemory,
812 VirtualizationSupport,
814 HighSpeedNetwork,
816}
817#[cfg(test)]
818mod tests {
819 use super::*;
820 use crate::types::{CpuInfo, MemoryInfo, StorageInfo, NetworkInfo, NetworkInterface};
821
822 #[test]
823 fn test_cpu_capability_creation() {
824 let cpu_info = CpuInfo {
825 brand: "Intel Core i7-8700K".to_string(),
826 physical_cores: 6,
827 logical_cores: 12,
828 base_frequency: 3700,
829 max_frequency: Some(4700),
830 cache_size: Some(12288),
831 architecture: "x86_64".to_string(),
832 };
833
834 let cpu_capability = CpuCapabilities::from_cpu_info(&cpu_info);
835
836 assert_eq!(cpu_capability.architecture, "x86_64");
837 assert_eq!(cpu_capability.physical_cores, 6);
838 assert_eq!(cpu_capability.logical_cores, 12);
839 assert_eq!(cpu_capability.base_frequency_mhz, 3700);
840 assert!(cpu_capability.thread_performance > 0.0);
841 assert!(cpu_capability.multicore_efficiency > 0.0);
842 }
843
844 #[test]
845 fn test_memory_capability_creation() {
846 let memory_info = MemoryInfo {
847 total_ram: 16_000_000_000, available_ram: 12_000_000_000, memory_speed: Some(3200),
850 memory_type: Some("DDR4".to_string()),
851 };
852
853 let memory_capability = MemoryCapabilities::from_memory_info(&memory_info);
854
855 assert!(memory_capability.total_ram_gb > 0.0);
856 assert!(memory_capability.available_ram_gb > 0.0);
857 assert_eq!(memory_capability.memory_type, Some("DDR4".to_string()));
858 assert!(memory_capability.bandwidth_score > 0.0);
859 }
860
861 #[test]
862 fn test_storage_capability_creation() {
863 let storage_info = vec![StorageInfo {
864 name: "Samsung SSD 970 EVO".to_string(),
865 storage_type: "NVMe SSD".to_string(),
866 total_capacity: 500,
867 available_capacity: 400,
868 read_speed: Some(3500),
869 write_speed: Some(3200),
870 }];
871
872 let storage_capability = StorageCapabilities::from_storage_info(&storage_info);
873
874 assert!(storage_capability.total_capacity_gb > 0.0);
875 assert!(storage_capability.available_capacity_gb > 0.0);
876 assert!(storage_capability.nvme_support);
877 assert!(storage_capability.performance_score > 0.0);
878 }
879
880 #[test]
881 fn test_network_capability_creation() {
882 let network_info = NetworkInfo {
883 interfaces: vec![
884 NetworkInterface {
885 name: "Ethernet".to_string(),
886 interface_type: "Ethernet".to_string(),
887 mac_address: "00:11:22:33:44:55".to_string(),
888 ip_addresses: vec!["192.168.1.100".to_string()],
889 speed: Some(1000),
890 }
891 ],
892 internet_connected: true,
893 estimated_bandwidth: Some(1000),
894 };
895
896 let network_capability = NetworkCapabilities::from_network_info(&network_info);
897
898 assert!(network_capability.internet_connected);
899 assert!(network_capability.estimated_bandwidth_mbps.unwrap_or(0) > 0);
900 assert!(network_capability.performance_score > 0.0);
901 }
902
903 #[test]
904 fn test_capability_profile_creation() {
905 let cpu_info = CpuInfo {
906 brand: "Intel Core i5-8400".to_string(),
907 physical_cores: 6,
908 logical_cores: 6,
909 base_frequency: 2800,
910 max_frequency: Some(4000),
911 cache_size: Some(9216),
912 architecture: "x86_64".to_string(),
913 };
914
915 let memory_info = MemoryInfo {
916 total_ram: 8_000_000_000, available_ram: 6_000_000_000, memory_speed: Some(2666),
919 memory_type: Some("DDR4".to_string()),
920 };
921
922 let storage_info = vec![StorageInfo {
923 name: "Generic SSD".to_string(),
924 storage_type: "SSD".to_string(),
925 total_capacity: 256,
926 available_capacity: 200,
927 read_speed: Some(500),
928 write_speed: Some(450),
929 }];
930
931 let network_info = NetworkInfo {
932 interfaces: vec![],
933 internet_connected: false,
934 estimated_bandwidth: None,
935 };
936
937 let gpu_info = vec![];
938
939 let system_info = crate::types::SystemInfo {
940 os_name: "Windows".to_string(),
941 os_version: "11".to_string(),
942 cpu_info: cpu_info,
943 gpu_info: gpu_info,
944 memory_info: memory_info,
945 storage_info: storage_info,
946 network_info: network_info,
947 };
948
949 let capability_profile = CapabilityProfile::from_system_info(&system_info);
950
951 assert!(capability_profile.scores.overall_score >= 0.0);
952 assert!(capability_profile.scores.overall_score <= 10.0);
953 }
954
955 #[test]
956 fn test_ai_capability_levels() {
957 let low_end_cpu = CpuInfo {
959 brand: "Intel Celeron".to_string(),
960 physical_cores: 2,
961 logical_cores: 2,
962 base_frequency: 1600,
963 max_frequency: Some(2400),
964 cache_size: Some(2048),
965 architecture: "x86_64".to_string(),
966 };
967
968 let low_capability = CpuCapabilities::from_cpu_info(&low_end_cpu);
969 let low_ai_level = low_capability.ai_capability_level();
970
971 assert!(matches!(low_ai_level, CapabilityLevel::VeryLow | CapabilityLevel::Low));
973
974 let high_end_cpu = CpuInfo {
976 brand: "Intel Core i9-12900K".to_string(),
977 physical_cores: 16,
978 logical_cores: 24,
979 base_frequency: 3200,
980 max_frequency: Some(5200),
981 cache_size: Some(30720),
982 architecture: "x86_64".to_string(),
983 };
984
985 let high_capability = CpuCapabilities::from_cpu_info(&high_end_cpu);
986 let high_ai_level = high_capability.ai_capability_level();
987
988 assert!(matches!(high_ai_level, CapabilityLevel::High | CapabilityLevel::VeryHigh));
990 }
991}