use super::error::KResult;
use konfigkoll_hwinfo::pci::PciDevice;
use konfigkoll_hwinfo::pci::PciIdDb;
use rune::Any;
use rune::ContextError;
use rune::Module;
use sysinfo::CpuRefreshKind;
use sysinfo::MemoryRefreshKind;
#[derive(Debug, Any)]
#[rune(item = ::sysinfo)]
struct SysInfo {
inner: sysinfo::System,
cpu_loaded: bool,
pci_devices: Option<Vec<PciDevice>>,
#[allow(dead_code)]
pci_db: Option<PciIdDb>,
}
impl SysInfo {
#[rune::function(path = Self::new)]
fn new() -> Self {
Self {
inner: sysinfo::System::new(),
cpu_loaded: false,
pci_devices: None,
pci_db: None,
}
}
#[rune::function]
fn total_memory(&mut self) -> u64 {
self.inner
.refresh_memory_specifics(MemoryRefreshKind::nothing().with_ram());
self.inner.total_memory() / 1024
}
#[rune::function]
fn architecture(&self) -> Option<String> {
Some(sysinfo::System::cpu_arch())
}
#[rune::function]
fn kernel(&self) -> Option<String> {
sysinfo::System::kernel_version()
}
#[rune::function]
fn host_name(&self) -> Option<String> {
sysinfo::System::host_name()
}
#[rune::function]
fn os_id(&self) -> String {
sysinfo::System::distribution_id()
}
#[rune::function]
fn os_version(&self) -> Option<String> {
sysinfo::System::os_version()
}
#[rune::function]
fn cpu_cores(&self) -> Option<usize> {
sysinfo::System::physical_core_count()
}
#[rune::function]
fn cpu_vendor_id(&mut self) -> Option<String> {
if !self.cpu_loaded {
self.inner.refresh_cpu_specifics(CpuRefreshKind::default());
self.cpu_loaded = true;
}
self.inner
.cpus()
.first()
.map(|cpu| cpu.vendor_id().to_string())
}
#[rune::function]
fn cpu_brand(&mut self) -> Option<String> {
if !self.cpu_loaded {
self.inner.refresh_cpu_specifics(CpuRefreshKind::default());
self.cpu_loaded = true;
}
self.inner.cpus().first().map(|cpu| cpu.brand().to_string())
}
#[rune::function]
fn pci_devices(&mut self) -> KResult<Vec<PciDevice>> {
if self.pci_devices.is_none() {
let devices = konfigkoll_hwinfo::pci::load_pci_devices()?;
self.pci_devices = Some(devices.collect());
}
self.pci_devices
.clone()
.ok_or_else(|| eyre::eyre!("Failed to load PCI devices").into())
}
}
#[rune::module(::sysinfo)]
pub(crate) fn module() -> Result<Module, ContextError> {
let mut m = Module::from_meta(module_meta)?;
m.ty::<SysInfo>()?;
m.function_meta(SysInfo::new)?;
m.function_meta(SysInfo::architecture)?;
m.function_meta(SysInfo::kernel)?;
m.function_meta(SysInfo::host_name)?;
m.function_meta(SysInfo::os_id)?;
m.function_meta(SysInfo::os_version)?;
m.function_meta(SysInfo::cpu_cores)?;
m.function_meta(SysInfo::total_memory)?;
m.function_meta(SysInfo::cpu_vendor_id)?;
m.function_meta(SysInfo::cpu_brand)?;
m.function_meta(SysInfo::pci_devices)?;
m.ty::<PciDevice>()?;
m.ty::<PciIdDb>()?;
Ok(m)
}