use lhm_shared::{HardwareType, SensorType};
use std::collections::HashMap;
#[derive(Default)]
pub struct HardwareCache {
hardware: Vec<HardwareEntry>,
sensors: Vec<SensorEntry>,
hardware_lookup: HashMap<String, usize>,
sensor_lookup: HashMap<String, usize>,
}
pub struct HardwareEntry {
parent_index: Option<usize>,
hardware: lhm_sys::Hardware,
}
pub struct SensorEntry {
parent_index: usize,
sensor: lhm_sys::Sensor,
}
impl HardwareCache {
pub fn init(&mut self, hardware: Vec<lhm_sys::Hardware>) {
self.clear();
self.populate(hardware, None);
}
fn populate(&mut self, hardware: Vec<lhm_sys::Hardware>, parent_index: Option<usize>) {
for item in hardware {
let identifier = item.identifier();
let children = item.get_children();
let sensors = item.sensors();
let hardware_index = self.hardware.len();
self.hardware.push(HardwareEntry {
parent_index,
hardware: item,
});
self.hardware_lookup.insert(identifier, hardware_index);
for sensor in sensors {
let identifier = sensor.identifier();
let sensor_index = self.sensors.len();
self.sensors.push(SensorEntry {
parent_index: hardware_index,
sensor,
});
self.sensor_lookup.insert(identifier, sensor_index);
}
self.populate(children, Some(hardware_index));
}
}
pub fn get_hardware_by_id(&self, identifier: &str) -> Option<(usize, &lhm_sys::Hardware)> {
let index = *self.hardware_lookup.get(identifier)?;
let hardware = &self.hardware[index];
Some((index, &hardware.hardware))
}
pub fn get_sensor_by_id(&self, identifier: &str) -> Option<(usize, &lhm_sys::Sensor)> {
let index = *self.sensor_lookup.get(identifier)?;
let sensor = &self.sensors[index];
Some((index, &sensor.sensor))
}
pub fn get_hardware_by_id_mut(&mut self, identifier: &str) -> Option<&mut lhm_sys::Hardware> {
let index = *self.hardware_lookup.get(identifier)?;
let hardware = &mut self.hardware[index];
Some(&mut hardware.hardware)
}
pub fn get_hardware_by_idx_mut(&mut self, index: usize) -> Option<&mut lhm_sys::Hardware> {
self.hardware
.get_mut(index)
.map(|hardware| &mut hardware.hardware)
}
pub fn get_sensor_by_id_mut(&mut self, identifier: &str) -> Option<&mut lhm_sys::Sensor> {
let index = *self.sensor_lookup.get(identifier)?;
let sensor = &mut self.sensors[index];
Some(&mut sensor.sensor)
}
pub fn get_sensor_by_idx_mut(&mut self, index: usize) -> Option<&mut lhm_sys::Sensor> {
self.sensors.get_mut(index).map(|sensor| &mut sensor.sensor)
}
pub fn query_hardware_iter(
&self,
parent_index: Option<usize>,
ty: Option<HardwareType>,
) -> impl Iterator<Item = (usize, &lhm_sys::Hardware)> + '_ {
let ty_value: Option<i32> = ty.map(|value| value.into());
self.hardware
.iter()
.enumerate()
.filter(move |(_, hardware)| {
if ty_value
.as_ref()
.is_some_and(|ty_value| hardware.hardware.get_type().ne(ty_value))
{
return false;
}
if parent_index.is_some_and(|parent_index: usize| {
hardware
.parent_index
.is_none_or(|value| value != parent_index)
}) {
return false;
}
true
})
.map(|(index, entry)| (index, &entry.hardware))
}
pub fn query_sensors(
&self,
parent_index: Option<usize>,
ty: Option<SensorType>,
) -> impl Iterator<Item = (usize, &lhm_sys::Sensor)> + '_ {
let ty_value: Option<i32> = ty.map(|value| value.into());
self.sensors
.iter()
.enumerate()
.filter(move |(_, sensor)| {
if ty_value
.as_ref()
.is_some_and(|ty_value| sensor.sensor.get_type().ne(ty_value))
{
return false;
}
if parent_index
.is_some_and(|parent_index: usize| sensor.parent_index != parent_index)
{
return false;
}
true
})
.map(|(index, entry)| (index, &entry.sensor))
}
pub fn clear(&mut self) {
self.hardware.clear();
self.sensors.clear();
self.hardware_lookup.clear();
self.sensor_lookup.clear();
}
}