zenyx-engine-telemetry/subcrates/telemetry/src/modules/cpu.rs
2025-05-04 00:36:38 -04:00

67 lines
2 KiB
Rust

use crate::modules::{FmtCores, FmtThreads};
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::collections::HashMap;
use sysinfo::{CpuRefreshKind, RefreshKind, System};
use thiserror::Error;
#[derive(Debug, Serialize, Deserialize)]
pub struct CPUInfo {
vendor: String,
brand: String,
total_system_cores: FmtCores,
threads: FmtThreads,
architecture: String,
byte_order: String,
}
#[derive(Debug, Error)]
pub enum CPUError {
#[error("No CPU information available")]
NoCpusFound,
#[error("Failed to build JSON for Vec<CPUInfo>")]
JsonError(#[from] serde_json::Error),
}
#[allow(dead_code)]
pub fn get_struct() -> Result<Vec<CPUInfo>, CPUError> {
let mut system =
System::new_with_specifics(RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()));
system.refresh_cpu_all();
let mut processor_map: HashMap<String, CPUInfo> = HashMap::new();
for cpu in system.cpus() {
let brand = cpu.brand().trim().to_string();
let entry = processor_map
.entry(brand.clone())
.or_insert_with(|| CPUInfo {
vendor: cpu.vendor_id().trim().to_string(),
brand: brand.clone(),
total_system_cores: System::physical_core_count()
.map(|cores| cores.into())
.unwrap_or_else(|| 0.into()),
threads: 0.into(),
architecture: System::cpu_arch().trim().to_string(),
byte_order: if cfg!(target_endian = "little") {
String::from("little-endian")
} else {
String::from("big-endian")
},
});
entry.threads += 1.into();
}
let cpus: Vec<_> = processor_map.into_values().collect();
if cpus.is_empty() {
return Err(CPUError::NoCpusFound);
}
Ok(cpus)
}
#[allow(dead_code)]
pub fn get_json() -> Result<Value, CPUError> {
Ok(json!(get_struct()?))
}