use crate::{SMBiosStruct, UndefinedStruct};
use std::fmt;
pub struct SMBiosElectricalCurrentProbe<'a> {
parts: &'a UndefinedStruct,
}
impl<'a> SMBiosStruct<'a> for SMBiosElectricalCurrentProbe<'a> {
const STRUCT_TYPE: u8 = 29u8;
fn new(parts: &'a UndefinedStruct) -> Self {
Self { parts }
}
fn parts(&self) -> &'a UndefinedStruct {
self.parts
}
}
impl<'a> SMBiosElectricalCurrentProbe<'a> {
pub fn description(&self) -> Option<String> {
self.parts.get_field_string(0x04)
}
pub fn location_and_status(&self) -> Option<CurrentProbeLocationAndStatus> {
self.parts
.get_field_byte(0x05)
.map(|raw| CurrentProbeLocationAndStatus::from(raw))
}
pub fn maximum_value(&self) -> Option<u16> {
self.parts.get_field_word(0x06)
}
pub fn minimum_value(&self) -> Option<u16> {
self.parts.get_field_word(0x08)
}
pub fn resolution(&self) -> Option<u16> {
self.parts.get_field_word(0x0A)
}
pub fn tolerance(&self) -> Option<u16> {
self.parts.get_field_word(0x0C)
}
pub fn accuracy(&self) -> Option<u16> {
self.parts.get_field_word(0x0E)
}
pub fn oem_defined(&self) -> Option<u32> {
self.parts.get_field_dword(0x10)
}
pub fn nominal_value(&self) -> Option<u16> {
self.parts.get_field_word(0x14)
}
}
impl fmt::Debug for SMBiosElectricalCurrentProbe<'_> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SMBiosElectricalCurrentProbe<'_>>())
.field("header", &self.parts.header)
.field("description", &self.description())
.field("location_and_status", &self.location_and_status())
.field("maximum_value", &self.maximum_value())
.field("minimum_value", &self.minimum_value())
.field("resolution", &self.resolution())
.field("tolerance", &self.tolerance())
.field("accuracy", &self.accuracy())
.field("oem_defined", &self.oem_defined())
.field("nominal_value", &self.nominal_value())
.finish()
}
}
#[derive(PartialEq, Eq)]
pub struct CurrentProbeLocationAndStatus {
pub raw: u8,
pub status: CurrentProbeStatus,
pub location: CurrentProbeLocation,
}
impl fmt::Debug for CurrentProbeLocationAndStatus {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<CurrentProbeLocationAndStatus>())
.field("raw", &self.raw)
.field("status", &self.status)
.field("location", &self.location)
.finish()
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum CurrentProbeStatus {
Other,
Unknown,
OK,
NonCritical,
Critical,
NonRecoverable,
None,
}
#[derive(Debug, PartialEq, Eq)]
pub enum CurrentProbeLocation {
Other,
Unknown,
Processor,
Disk,
PeripheralBay,
SystemManagementModule,
Motherboard,
MemoryModule,
ProcessorModule,
PowerUnit,
AddInCard,
None,
}
impl From<u8> for CurrentProbeLocationAndStatus {
fn from(raw: u8) -> Self {
CurrentProbeLocationAndStatus {
status: match raw & 0b111_00000 {
0b001_00000 => CurrentProbeStatus::Other,
0b010_00000 => CurrentProbeStatus::Unknown,
0b011_00000 => CurrentProbeStatus::OK,
0b100_00000 => CurrentProbeStatus::NonCritical,
0b101_00000 => CurrentProbeStatus::Critical,
0b110_00000 => CurrentProbeStatus::NonRecoverable,
_ => CurrentProbeStatus::None,
},
location: match raw & 0b000_11111 {
0b000_00001 => CurrentProbeLocation::Other,
0b000_00010 => CurrentProbeLocation::Unknown,
0b000_00011 => CurrentProbeLocation::Processor,
0b000_00100 => CurrentProbeLocation::Disk,
0b000_00101 => CurrentProbeLocation::PeripheralBay,
0b000_00110 => CurrentProbeLocation::SystemManagementModule,
0b000_00111 => CurrentProbeLocation::Motherboard,
0b000_01000 => CurrentProbeLocation::MemoryModule,
0b000_01001 => CurrentProbeLocation::ProcessorModule,
0b000_01010 => CurrentProbeLocation::PowerUnit,
0b000_01011 => CurrentProbeLocation::AddInCard,
_ => CurrentProbeLocation::None,
},
raw,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unit_test() {
let struct_type29 = vec![
0x1D, 0x16, 0x33, 0x00, 0x01, 0x67, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80,
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x42, 0x43, 0x00, 0x00,
];
let parts = UndefinedStruct::new(&struct_type29);
let test_struct = SMBiosElectricalCurrentProbe::new(&parts);
assert_eq!(test_struct.description(), Some("ABC".to_string()));
let location_and_status = test_struct.location_and_status().unwrap();
assert_eq!(location_and_status.status, CurrentProbeStatus::OK);
assert_eq!(
location_and_status.location,
CurrentProbeLocation::Motherboard
);
assert_eq!(
test_struct.location_and_status(),
Some(CurrentProbeLocationAndStatus::from(103))
);
assert_eq!(test_struct.maximum_value(), Some(32768));
assert_eq!(test_struct.minimum_value(), Some(32768));
assert_eq!(test_struct.resolution(), Some(32768));
assert_eq!(test_struct.tolerance(), Some(32768));
assert_eq!(test_struct.accuracy(), Some(32768));
assert_eq!(test_struct.oem_defined(), Some(0));
assert_eq!(test_struct.nominal_value(), Some(32768));
}
}