use crate::{SMBiosStruct, UndefinedStruct};
use std::fmt;
use std::ops::Deref;
pub struct SMBiosMemoryErrorInformation32<'a> {
parts: &'a UndefinedStruct,
}
impl<'a> SMBiosStruct<'a> for SMBiosMemoryErrorInformation32<'a> {
const STRUCT_TYPE: u8 = 18u8;
fn new(parts: &'a UndefinedStruct) -> Self {
Self { parts }
}
fn parts(&self) -> &'a UndefinedStruct {
self.parts
}
}
impl<'a> SMBiosMemoryErrorInformation32<'a> {
pub fn error_type(&self) -> Option<MemoryErrorTypeData> {
self.parts
.get_field_byte(0x04)
.map(|raw| MemoryErrorTypeData::from(raw))
}
pub fn error_granularity(&self) -> Option<MemoryErrorGranularityData> {
self.parts
.get_field_byte(0x05)
.map(|raw| MemoryErrorGranularityData::from(raw))
}
pub fn error_operation(&self) -> Option<MemoryErrorOperationData> {
self.parts
.get_field_byte(0x06)
.map(|raw| MemoryErrorOperationData::from(raw))
}
pub fn vendor_syndrome(&self) -> Option<u32> {
self.parts.get_field_dword(0x07)
}
pub fn memory_array_error_address(&self) -> Option<u32> {
self.parts.get_field_dword(0x0B)
}
pub fn device_error_address(&self) -> Option<u32> {
self.parts.get_field_dword(0x0F)
}
pub fn error_resolution(&self) -> Option<u32> {
self.parts.get_field_dword(0x13)
}
}
impl fmt::Debug for SMBiosMemoryErrorInformation32<'_> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SMBiosMemoryErrorInformation32<'_>>())
.field("header", &self.parts.header)
.field("error_type", &self.error_type())
.field("error_granularity", &self.error_granularity())
.field("error_operation", &self.error_operation())
.field("vendor_syndrome", &self.vendor_syndrome())
.field(
"memory_array_error_address",
&self.memory_array_error_address(),
)
.field("device_error_address", &self.device_error_address())
.field("error_resolution", &self.error_resolution())
.finish()
}
}
pub struct MemoryErrorTypeData {
pub raw: u8,
pub value: MemoryErrorType,
}
impl fmt::Debug for MemoryErrorTypeData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<MemoryErrorTypeData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Deref for MemoryErrorTypeData {
type Target = MemoryErrorType;
fn deref(&self) -> &Self::Target {
&self.value
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum MemoryErrorType {
Other,
Unknown,
OK,
BadRead,
ParityError,
SingleBitError,
DoubleBitError,
MultiBitError,
NibbleError,
ChecksumError,
CrcError,
CorrectedSingleBitError,
CorrectedError,
UncorrectableError,
None,
}
impl From<u8> for MemoryErrorTypeData {
fn from(raw: u8) -> Self {
MemoryErrorTypeData {
value: match raw {
0x01 => MemoryErrorType::Other,
0x02 => MemoryErrorType::Unknown,
0x03 => MemoryErrorType::OK,
0x04 => MemoryErrorType::BadRead,
0x05 => MemoryErrorType::ParityError,
0x06 => MemoryErrorType::SingleBitError,
0x07 => MemoryErrorType::DoubleBitError,
0x08 => MemoryErrorType::MultiBitError,
0x09 => MemoryErrorType::NibbleError,
0x0A => MemoryErrorType::ChecksumError,
0x0B => MemoryErrorType::CrcError,
0x0C => MemoryErrorType::CorrectedSingleBitError,
0x0D => MemoryErrorType::CorrectedError,
0x0E => MemoryErrorType::UncorrectableError,
_ => MemoryErrorType::None,
},
raw,
}
}
}
pub struct MemoryErrorGranularityData {
pub raw: u8,
pub value: MemoryErrorGranularity,
}
impl fmt::Debug for MemoryErrorGranularityData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<MemoryErrorGranularityData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Deref for MemoryErrorGranularityData {
type Target = MemoryErrorGranularity;
fn deref(&self) -> &Self::Target {
&self.value
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum MemoryErrorGranularity {
Other,
Unknown,
DeviceLevel,
MemoryPartitionLevel,
None,
}
impl From<u8> for MemoryErrorGranularityData {
fn from(raw: u8) -> Self {
MemoryErrorGranularityData {
value: match raw {
0x01 => MemoryErrorGranularity::Other,
0x02 => MemoryErrorGranularity::Unknown,
0x03 => MemoryErrorGranularity::DeviceLevel,
0x04 => MemoryErrorGranularity::MemoryPartitionLevel,
_ => MemoryErrorGranularity::None,
},
raw,
}
}
}
pub struct MemoryErrorOperationData {
pub raw: u8,
pub value: MemoryErrorOperation,
}
impl fmt::Debug for MemoryErrorOperationData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<MemoryErrorOperationData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Deref for MemoryErrorOperationData {
type Target = MemoryErrorOperation;
fn deref(&self) -> &Self::Target {
&self.value
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum MemoryErrorOperation {
Other,
Unknown,
Read,
Write,
PartialWrite,
None,
}
impl From<u8> for MemoryErrorOperationData {
fn from(raw: u8) -> Self {
MemoryErrorOperationData {
value: match raw {
0x01 => MemoryErrorOperation::Other,
0x02 => MemoryErrorOperation::Unknown,
0x03 => MemoryErrorOperation::Read,
0x04 => MemoryErrorOperation::Write,
0x05 => MemoryErrorOperation::PartialWrite,
_ => MemoryErrorOperation::None,
},
raw,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unit_test() {
let struct_type18 = vec![
0x12, 0x17, 0x50, 0x00, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
];
let parts = UndefinedStruct::new(&struct_type18);
let test_struct = SMBiosMemoryErrorInformation32::new(&parts);
assert_eq!(*test_struct.error_type().unwrap(), MemoryErrorType::OK);
assert_eq!(
*test_struct.error_granularity().unwrap(),
MemoryErrorGranularity::Unknown
);
assert_eq!(
*test_struct.error_operation().unwrap(),
MemoryErrorOperation::Unknown
);
assert_eq!(test_struct.vendor_syndrome(), Some(0));
assert_eq!(test_struct.memory_array_error_address(), Some(0x8000_0000));
assert_eq!(test_struct.device_error_address(), Some(0x8000_0000));
assert_eq!(test_struct.error_resolution(), Some(0x8000_0000));
}
}