use crate::{SMBiosStruct, UndefinedStruct};
use serde::{ser::SerializeSeq, ser::SerializeStruct, Serialize, Serializer};
use std::{fmt, ops::Deref};
pub struct SMBiosSystemSlot<'a> {
parts: &'a UndefinedStruct,
}
impl<'a> SMBiosStruct<'a> for SMBiosSystemSlot<'a> {
const STRUCT_TYPE: u8 = 9u8;
fn new(parts: &'a UndefinedStruct) -> Self {
Self { parts }
}
fn parts(&self) -> &'a UndefinedStruct {
self.parts
}
}
impl<'a> SMBiosSystemSlot<'a> {
pub fn slot_designation(&self) -> Option<String> {
self.parts.get_field_string(0x04)
}
pub fn system_slot_type(&self) -> Option<SystemSlotTypeData> {
self.parts
.get_field_byte(0x05)
.map(|raw| SystemSlotTypeData::from(raw))
}
pub fn slot_data_bus_width(&self) -> Option<SlotWidthData> {
self.parts
.get_field_byte(0x06)
.map(|raw| SlotWidthData::from(raw))
}
pub fn current_usage(&self) -> Option<SlotCurrentUsageData> {
self.parts
.get_field_byte(0x07)
.map(|raw| SlotCurrentUsageData::from(raw))
}
pub fn slot_length(&self) -> Option<SlotLengthData> {
self.parts
.get_field_byte(0x08)
.map(|raw| SlotLengthData::from(raw))
}
pub fn slot_id(&self) -> Option<u16> {
self.parts.get_field_word(0x09)
}
pub fn slot_characteristics_1(&self) -> Option<SystemSlotCharacteristics1> {
self.parts
.get_field_byte(0x0B)
.map(|raw| SystemSlotCharacteristics1::from(raw))
}
pub fn slot_characteristics_2(&self) -> Option<SystemSlotCharacteristics2> {
self.parts
.get_field_byte(0x0C)
.map(|raw| SystemSlotCharacteristics2::from(raw))
}
pub fn segment_group_number(&self) -> Option<u16> {
self.parts.get_field_word(0x0D)
}
pub fn bus_number(&self) -> Option<u8> {
self.parts.get_field_byte(0x0F)
}
pub fn device_function_number(&self) -> Option<u8> {
self.parts.get_field_byte(0x10)
}
pub fn data_bus_width(&self) -> Option<u8> {
self.parts.get_field_byte(0x11)
}
pub fn peer_group_count(&self) -> Option<usize> {
self.parts
.get_field_byte(0x12)
.and_then(|count| Some(count as usize))
}
fn peer_group_size(&self) -> Option<usize> {
self.peer_group_count()
.and_then(|count| Some(count as usize * SlotPeerGroup::SIZE))
}
pub fn peer_group_iterator(&'a self) -> SlotPeerGroupIterator<'a> {
SlotPeerGroupIterator::new(self)
}
pub fn slot_information(&self) -> Option<u8> {
self.peer_group_size()
.and_then(|size| self.parts.get_field_byte(size + 0x13))
}
pub fn slot_physical_width(&self) -> Option<SlotWidthData> {
self.peer_group_size().and_then(|size| {
self.parts
.get_field_byte(size + 0x14)
.map(|raw| SlotWidthData::from(raw))
})
}
pub fn slot_pitch(&self) -> Option<u16> {
self.peer_group_size()
.and_then(|size| self.parts.get_field_word(size + 0x15))
}
}
impl fmt::Debug for SMBiosSystemSlot<'_> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SMBiosSystemSlot<'_>>())
.field("header", &self.parts.header)
.field("slot_designation", &self.slot_designation())
.field("system_slot_type", &self.system_slot_type())
.field("slot_data_bus_width", &self.slot_data_bus_width())
.field("current_usage", &self.current_usage())
.field("slot_length", &self.slot_length())
.field("slot_id", &self.slot_id())
.field("slot_characteristics_1", &self.slot_characteristics_1())
.field("slot_characteristics_2", &self.slot_characteristics_2())
.field("segment_group_number", &self.segment_group_number())
.field("bus_number", &self.bus_number())
.field("device_function_number", &self.device_function_number())
.field("data_bus_width", &self.data_bus_width())
.field("peer_group_count", &self.peer_group_count())
.field("peer_group_iterator", &self.peer_group_iterator())
.field("slot_information", &self.slot_information())
.field("slot_physical_width", &self.slot_physical_width())
.field("slot_pitch", &self.slot_pitch())
.finish()
}
}
impl Serialize for SMBiosSystemSlot<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SMBiosSystemSlot", 18)?;
state.serialize_field("header", &self.parts.header)?;
state.serialize_field("slot_designation", &self.slot_designation())?;
state.serialize_field("system_slot_type", &self.system_slot_type())?;
state.serialize_field("slot_data_bus_width", &self.slot_data_bus_width())?;
state.serialize_field("current_usage", &self.current_usage())?;
state.serialize_field("slot_length", &self.slot_length())?;
state.serialize_field("slot_id", &self.slot_id())?;
state.serialize_field("slot_characteristics_1", &self.slot_characteristics_1())?;
state.serialize_field("slot_characteristics_2", &self.slot_characteristics_2())?;
state.serialize_field("segment_group_number", &self.segment_group_number())?;
state.serialize_field("bus_number", &self.bus_number())?;
state.serialize_field("device_function_number", &self.device_function_number())?;
state.serialize_field("data_bus_width", &self.data_bus_width())?;
state.serialize_field("peer_group_count", &self.peer_group_count())?;
state.serialize_field("peer_group_iterator", &self.peer_group_iterator())?;
state.serialize_field("slot_information", &self.slot_information())?;
state.serialize_field("slot_physical_width", &self.slot_physical_width())?;
state.serialize_field("slot_pitch", &self.slot_pitch())?;
state.end()
}
}
pub struct SystemSlotTypeData {
raw: u8,
value: SystemSlotType,
}
impl Deref for SystemSlotTypeData {
type Target = SystemSlotType;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<u8> for SystemSlotTypeData {
fn from(raw: u8) -> Self {
SystemSlotTypeData {
value: match raw {
0x01 => SystemSlotType::Other,
0x02 => SystemSlotType::Unknown,
0x03 => SystemSlotType::Isa,
0x04 => SystemSlotType::Mca,
0x05 => SystemSlotType::Eisa,
0x06 => SystemSlotType::Pci,
0x07 => SystemSlotType::Pcmcia,
0x08 => SystemSlotType::VlVesa,
0x09 => SystemSlotType::Proprietary,
0x0A => SystemSlotType::ProcessorCardSlot,
0x0B => SystemSlotType::ProprietaryMemoryCardSlot,
0x0C => SystemSlotType::IORiserCardSlot,
0x0D => SystemSlotType::NuBus,
0x0E => SystemSlotType::Pci66MhzCapable,
0x0F => SystemSlotType::Agp,
0x10 => SystemSlotType::Agp2x,
0x11 => SystemSlotType::Agp4x,
0x12 => SystemSlotType::PciX,
0x13 => SystemSlotType::Agp8X,
0x14 => SystemSlotType::M2Socket1DP,
0x15 => SystemSlotType::M2Socket1SD,
0x16 => SystemSlotType::M2Socket2,
0x17 => SystemSlotType::M2Socket3,
0x18 => SystemSlotType::MxmTypeI,
0x19 => SystemSlotType::MxmTypeII,
0x1A => SystemSlotType::MxmTypeIIIStandard,
0x1B => SystemSlotType::MxmTypeIIIHE,
0x1C => SystemSlotType::MxmTypeIV,
0x1D => SystemSlotType::Mxm3TypeA,
0x1E => SystemSlotType::Mxm3TypeB,
0x1F => SystemSlotType::PciExpressGen2Sff8639,
0x20 => SystemSlotType::PciExpressGen3Sff8639,
0x21 => SystemSlotType::PciExpressMini52WithKeepouts,
0x22 => SystemSlotType::PciExpressMini52WithoutKeepouts,
0x23 => SystemSlotType::PciExpressMini76,
0x24 => SystemSlotType::PciExpressGen4Sff8639,
0x25 => SystemSlotType::PciExpressGen5Sff8639,
0x30 => SystemSlotType::CxlFlexbus1,
0xA0 => SystemSlotType::PC98C20,
0xA1 => SystemSlotType::PC98C24,
0xA2 => SystemSlotType::PC98E,
0xA3 => SystemSlotType::PC98LocalBus,
0xA4 => SystemSlotType::PC98Card,
0xA5 => SystemSlotType::PciExpress,
0xA6 => SystemSlotType::PciExpressx1,
0xA7 => SystemSlotType::PciExpressx2,
0xA8 => SystemSlotType::PciExpressx4,
0xA9 => SystemSlotType::PciExpressx8,
0xAA => SystemSlotType::PciExpressx16,
0xAB => SystemSlotType::PciExpressGen2,
0xAC => SystemSlotType::PciExpressGen2x1,
0xAD => SystemSlotType::PciExpressGen2x2,
0xAE => SystemSlotType::PciExpressGen2x4,
0xAF => SystemSlotType::PciExpressGen2x8,
0xB0 => SystemSlotType::PciExpressGen2x16,
0xB1 => SystemSlotType::PciExpressGen3,
0xB2 => SystemSlotType::PciExpressGen3x1,
0xB3 => SystemSlotType::PciExpressGen3x2,
0xB4 => SystemSlotType::PciExpressGen3x4,
0xB5 => SystemSlotType::PciExpressGen3x8,
0xB6 => SystemSlotType::PciExpressGen3x16,
0xB8 => SystemSlotType::PciExpressGen4,
0xB9 => SystemSlotType::PciExpressGen4x1,
0xBA => SystemSlotType::PciExpressGen4x2,
0xBB => SystemSlotType::PciExpressGen4x4,
0xBC => SystemSlotType::PciExpressGen4x8,
0xBD => SystemSlotType::PciExpressGen4x16,
0xBE => SystemSlotType::PciExpressGen5,
0xBF => SystemSlotType::PciExpressGen5x1,
0xC0 => SystemSlotType::PciExpressGen5x2,
0xC1 => SystemSlotType::PciExpressGen5x4,
0xC2 => SystemSlotType::PciExpressGen5x8,
0xC3 => SystemSlotType::PciExpressGen5x16,
0xC4 => SystemSlotType::PciExpressGen6,
0xC5 => SystemSlotType::EnterpriseAndDataCenter1UE1,
0xC6 => SystemSlotType::EnterpriseAndDataCenter3InE3,
_ => SystemSlotType::None,
},
raw,
}
}
}
impl fmt::Debug for SystemSlotTypeData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SystemSlotTypeData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Serialize for SystemSlotTypeData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SystemSlotTypeData", 2)?;
state.serialize_field("raw", &self.raw)?;
state.serialize_field("value", &self.value)?;
state.end()
}
}
impl fmt::Display for SystemSlotTypeData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.value {
SystemSlotType::None => write!(f, "{}", &self.raw),
_ => write!(f, "{:?}", &self.value),
}
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
pub enum SystemSlotType {
Other,
Unknown,
Isa,
Mca,
Eisa,
Pci,
Pcmcia,
VlVesa,
Proprietary,
ProcessorCardSlot,
ProprietaryMemoryCardSlot,
IORiserCardSlot,
NuBus,
Pci66MhzCapable,
Agp,
Agp2x,
Agp4x,
PciX,
Agp8X,
M2Socket1DP,
M2Socket1SD,
M2Socket2,
M2Socket3,
MxmTypeI,
MxmTypeII,
MxmTypeIIIStandard,
MxmTypeIIIHE,
MxmTypeIV,
Mxm3TypeA,
Mxm3TypeB,
PciExpressGen2Sff8639,
PciExpressGen3Sff8639,
PciExpressMini52WithKeepouts,
PciExpressMini52WithoutKeepouts,
PciExpressMini76,
PciExpressGen4Sff8639,
PciExpressGen5Sff8639,
CxlFlexbus1,
PC98C20,
PC98C24,
PC98E,
PC98LocalBus,
PC98Card,
PciExpress,
PciExpressx1,
PciExpressx2,
PciExpressx4,
PciExpressx8,
PciExpressx16,
PciExpressGen2,
PciExpressGen2x1,
PciExpressGen2x2,
PciExpressGen2x4,
PciExpressGen2x8,
PciExpressGen2x16,
PciExpressGen3,
PciExpressGen3x1,
PciExpressGen3x2,
PciExpressGen3x4,
PciExpressGen3x8,
PciExpressGen3x16,
PciExpressGen4,
PciExpressGen4x1,
PciExpressGen4x2,
PciExpressGen4x4,
PciExpressGen4x8,
PciExpressGen4x16,
PciExpressGen5,
PciExpressGen5x1,
PciExpressGen5x2,
PciExpressGen5x4,
PciExpressGen5x8,
PciExpressGen5x16,
PciExpressGen6,
EnterpriseAndDataCenter1UE1,
EnterpriseAndDataCenter3InE3,
None,
}
pub struct SlotWidthData {
pub raw: u8,
pub value: SlotWidth,
}
impl Deref for SlotWidthData {
type Target = SlotWidth;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<u8> for SlotWidthData {
fn from(raw: u8) -> Self {
SlotWidthData {
value: match raw {
0x01 => SlotWidth::Other,
0x02 => SlotWidth::Unknown,
0x03 => SlotWidth::Bit8,
0x04 => SlotWidth::Bit16,
0x05 => SlotWidth::Bit32,
0x06 => SlotWidth::Bit64,
0x07 => SlotWidth::Bit128,
0x08 => SlotWidth::X1,
0x09 => SlotWidth::X2,
0x0A => SlotWidth::X4,
0x0B => SlotWidth::X8,
0x0C => SlotWidth::X12,
0x0D => SlotWidth::X16,
0x0E => SlotWidth::X32,
_ => SlotWidth::None,
},
raw,
}
}
}
impl fmt::Debug for SlotWidthData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SlotWidthData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Serialize for SlotWidthData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SlotWidthData", 2)?;
state.serialize_field("raw", &self.raw)?;
state.serialize_field("value", &self.value)?;
state.end()
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
pub enum SlotWidth {
Other,
Unknown,
Bit8,
Bit16,
Bit32,
Bit64,
Bit128,
X1,
X2,
X4,
X8,
X12,
X16,
X32,
None,
}
pub struct SlotCurrentUsageData {
pub raw: u8,
pub value: SlotCurrentUsage,
}
impl Deref for SlotCurrentUsageData {
type Target = SlotCurrentUsage;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<u8> for SlotCurrentUsageData {
fn from(raw: u8) -> Self {
SlotCurrentUsageData {
value: match raw {
0x01 => SlotCurrentUsage::Other,
0x02 => SlotCurrentUsage::Unknown,
0x03 => SlotCurrentUsage::Available,
0x04 => SlotCurrentUsage::InUse,
0x05 => SlotCurrentUsage::Unavailable,
_ => SlotCurrentUsage::None,
},
raw,
}
}
}
impl fmt::Debug for SlotCurrentUsageData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SlotCurrentUsageData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Serialize for SlotCurrentUsageData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SlotCurrentUsageData", 2)?;
state.serialize_field("raw", &self.raw)?;
state.serialize_field("value", &self.value)?;
state.end()
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
pub enum SlotCurrentUsage {
Other,
Unknown,
Available,
InUse,
Unavailable,
None,
}
pub struct SlotLengthData {
pub raw: u8,
pub value: SlotLength,
}
impl Deref for SlotLengthData {
type Target = SlotLength;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl From<u8> for SlotLengthData {
fn from(raw: u8) -> Self {
SlotLengthData {
value: match raw {
0x01 => SlotLength::Other,
0x02 => SlotLength::Unknown,
0x03 => SlotLength::ShortLength,
0x04 => SlotLength::LongLength,
0x05 => SlotLength::DriveFormFactor25,
0x06 => SlotLength::DriveFormFactor35,
_ => SlotLength::None,
},
raw,
}
}
}
impl fmt::Debug for SlotLengthData {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SlotLengthData>())
.field("raw", &self.raw)
.field("value", &self.value)
.finish()
}
}
impl Serialize for SlotLengthData {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SlotLengthData", 2)?;
state.serialize_field("raw", &self.raw)?;
state.serialize_field("value", &self.value)?;
state.end()
}
}
#[derive(Serialize, Debug, PartialEq, Eq)]
pub enum SlotLength {
Other,
Unknown,
ShortLength,
LongLength,
DriveFormFactor25,
DriveFormFactor35,
None,
}
#[derive(PartialEq, Eq)]
pub struct SystemSlotCharacteristics1 {
raw: u8,
}
impl Deref for SystemSlotCharacteristics1 {
type Target = u8;
fn deref(&self) -> &Self::Target {
&self.raw
}
}
impl From<u8> for SystemSlotCharacteristics1 {
fn from(raw: u8) -> Self {
SystemSlotCharacteristics1 { raw }
}
}
impl SystemSlotCharacteristics1 {
pub fn unknown(&self) -> bool {
self.raw & 0x01 == 0x01
}
pub fn provides5_volts(&self) -> bool {
self.raw & 0x02 == 0x02
}
pub fn provides33_volts(&self) -> bool {
self.raw & 0x04 == 0x04
}
pub fn shared(&self) -> bool {
self.raw & 0x08 == 0x08
}
pub fn supports_pc_card16(&self) -> bool {
self.raw & 0x10 == 0x10
}
pub fn supports_card_bus(&self) -> bool {
self.raw & 0x20 == 0x20
}
pub fn supports_zoom_video(&self) -> bool {
self.raw & 0x40 == 0x40
}
pub fn supports_modem_ring_resume(&self) -> bool {
self.raw & 0x80 == 0x80
}
}
impl fmt::Debug for SystemSlotCharacteristics1 {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SystemSlotCharacteristics1>())
.field("raw", &self.raw)
.field("unknown", &self.unknown())
.field("provides5_volts", &self.provides5_volts())
.field("provides33_volts", &self.provides33_volts())
.field("shared", &self.shared())
.field("supports_pc_card16", &self.supports_pc_card16())
.field("supports_card_bus", &self.supports_card_bus())
.field("supports_zoom_video", &self.supports_zoom_video())
.field(
"supports_modem_ring_resume",
&self.supports_modem_ring_resume(),
)
.finish()
}
}
impl Serialize for SystemSlotCharacteristics1 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SystemSlotCharacteristics1", 9)?;
state.serialize_field("raw", &self.raw)?;
state.serialize_field("unknown", &self.unknown())?;
state.serialize_field("provides5_volts", &self.provides5_volts())?;
state.serialize_field("provides33_volts", &self.provides33_volts())?;
state.serialize_field("shared", &self.shared())?;
state.serialize_field("supports_pc_card16", &self.supports_pc_card16())?;
state.serialize_field("supports_card_bus", &self.supports_card_bus())?;
state.serialize_field("supports_zoom_video", &self.supports_zoom_video())?;
state.serialize_field(
"supports_modem_ring_resume",
&self.supports_modem_ring_resume(),
)?;
state.end()
}
}
#[derive(PartialEq, Eq)]
pub struct SystemSlotCharacteristics2 {
raw: u8,
}
impl Deref for SystemSlotCharacteristics2 {
type Target = u8;
fn deref(&self) -> &Self::Target {
&self.raw
}
}
impl From<u8> for SystemSlotCharacteristics2 {
fn from(raw: u8) -> Self {
SystemSlotCharacteristics2 { raw }
}
}
impl SystemSlotCharacteristics2 {
pub fn supports_power_management_event(&self) -> bool {
self.raw & 0x01 == 0x01
}
pub fn supports_hot_plug_devices(&self) -> bool {
self.raw & 0x02 == 0x02
}
pub fn supports_smbus_signal(&self) -> bool {
self.raw & 0x04 == 0x04
}
pub fn supports_bifurcation(&self) -> bool {
self.raw & 0x08 == 0x08
}
pub fn supports_suprise_removal(&self) -> bool {
self.raw & 0x10 == 0x10
}
pub fn flexbus_slot_cxl10_capable(&self) -> bool {
self.raw & 0x20 == 0x20
}
pub fn flexbus_slot_cxl20_capable(&self) -> bool {
self.raw & 0x40 == 0x40
}
}
impl fmt::Debug for SystemSlotCharacteristics2 {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SystemSlotCharacteristics2>())
.field("raw", &self.raw)
.field(
"supports_power_management_event",
&self.supports_power_management_event(),
)
.field(
"supports_hot_plug_devices",
&self.supports_hot_plug_devices(),
)
.field("supports_smbus_signal", &self.supports_smbus_signal())
.field("supports_bifurcation", &self.supports_bifurcation())
.field("supports_suprise_removal", &self.supports_suprise_removal())
.field(
"flexbus_slot_cxl10_capable",
&self.flexbus_slot_cxl10_capable(),
)
.field(
"flexbus_slot_cxl20_capable",
&self.flexbus_slot_cxl20_capable(),
)
.finish()
}
}
impl Serialize for SystemSlotCharacteristics2 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SystemSlotCharacteristics2", 8)?;
state.serialize_field("raw", &self.raw)?;
state.serialize_field(
"supports_power_management_event",
&self.supports_power_management_event(),
)?;
state.serialize_field(
"supports_hot_plug_devices",
&self.supports_hot_plug_devices(),
)?;
state.serialize_field("supports_smbus_signal", &self.supports_smbus_signal())?;
state.serialize_field("supports_bifurcation", &self.supports_bifurcation())?;
state.serialize_field("supports_suprise_removal", &self.supports_suprise_removal())?;
state.serialize_field(
"flexbus_slot_cxl10_capable",
&self.flexbus_slot_cxl10_capable(),
)?;
state.serialize_field(
"flexbus_slot_cxl20_capable",
&self.flexbus_slot_cxl20_capable(),
)?;
state.end()
}
}
pub struct SlotPeerGroup<'a> {
system_slot: &'a SMBiosSystemSlot<'a>,
entry_offset: usize,
}
impl<'a> SlotPeerGroup<'a> {
const SIZE: usize = 5;
const SEGMENT_GROUP_NUMBER_OFFSET: usize = 0;
const BUS_NUMBER_OFFSET: usize = 2;
const DEVICE_FUNCTION_NUMBER_OFFSET: usize = 3;
const DATA_BUS_WIDTH_OFFSET: usize = 4;
fn new(system_slot: &'a SMBiosSystemSlot<'a>, entry_offset: usize) -> Self {
Self {
system_slot,
entry_offset,
}
}
pub fn segment_group_number(&self) -> Option<u16> {
self.system_slot
.parts()
.get_field_word(self.entry_offset + Self::SEGMENT_GROUP_NUMBER_OFFSET)
}
pub fn bus_number(&self) -> Option<u8> {
self.system_slot
.parts()
.get_field_byte(self.entry_offset + Self::BUS_NUMBER_OFFSET)
}
pub fn device_function_number(&self) -> Option<u8> {
self.system_slot
.parts()
.get_field_byte(self.entry_offset + Self::DEVICE_FUNCTION_NUMBER_OFFSET)
}
pub fn data_bus_width(&self) -> Option<u8> {
self.system_slot
.parts()
.get_field_byte(self.entry_offset + Self::DATA_BUS_WIDTH_OFFSET)
}
}
impl fmt::Debug for SlotPeerGroup<'_> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct(std::any::type_name::<SlotPeerGroup<'_>>())
.field("segment_group_number", &self.segment_group_number())
.field("bus_number", &self.bus_number())
.field("device_function_number", &self.device_function_number())
.field("data_bus_width", &self.data_bus_width())
.finish()
}
}
impl Serialize for SlotPeerGroup<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("SlotPeerGroup", 4)?;
state.serialize_field("segment_group_number", &self.segment_group_number())?;
state.serialize_field("bus_number", &self.bus_number())?;
state.serialize_field("device_function_number", &self.device_function_number())?;
state.serialize_field("data_bus_width", &self.data_bus_width())?;
state.end()
}
}
pub struct SlotPeerGroupIterator<'a> {
data: &'a SMBiosSystemSlot<'a>,
current_index: usize,
current_entry: usize,
number_of_entries: usize,
}
impl<'a> SlotPeerGroupIterator<'a> {
const PEER_GROUPS_OFFSET: usize = 0x13;
fn new(data: &'a SMBiosSystemSlot<'a>) -> Self {
SlotPeerGroupIterator {
data: data,
current_index: Self::PEER_GROUPS_OFFSET,
current_entry: 0,
number_of_entries: data.peer_group_count().unwrap_or(0),
}
}
fn reset(&mut self) {
self.current_index = Self::PEER_GROUPS_OFFSET;
self.current_entry = 0;
}
}
impl<'a> IntoIterator for &'a SlotPeerGroupIterator<'a> {
type Item = SlotPeerGroup<'a>;
type IntoIter = SlotPeerGroupIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
SlotPeerGroupIterator {
data: self.data,
current_index: SlotPeerGroupIterator::PEER_GROUPS_OFFSET,
current_entry: 0,
number_of_entries: self.data.peer_group_count().unwrap_or(0),
}
}
}
impl<'a> Iterator for SlotPeerGroupIterator<'a> {
type Item = SlotPeerGroup<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.current_entry == self.number_of_entries {
self.reset();
return None;
}
let next_index = self.current_index + SlotPeerGroup::SIZE;
match self
.data
.parts()
.get_field_data(self.current_index, next_index)
{
Some(_) => {
let result = SlotPeerGroup::new(self.data, self.current_index);
self.current_index = next_index;
self.current_entry += 1;
Some(result)
}
None => {
self.reset();
None
}
}
}
}
impl<'a> fmt::Debug for SlotPeerGroupIterator<'a> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().entries(self.into_iter()).finish()
}
}
impl<'a> Serialize for SlotPeerGroupIterator<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let groups: Vec<SlotPeerGroup<'_>> = self.into_iter().collect();
let mut seq = serializer.serialize_seq(Some(groups.len()))?;
for e in groups {
seq.serialize_element(&e)?;
}
seq.end()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unit_test() {
let struct_type9 = vec![
0x09, 0x11, 0x1C, 0x00, 0x01, 0xA5, 0x0D, 0x04, 0x04, 0x00, 0x00, 0x0C, 0x01, 0x00,
0x00, 0x00, 0x08, 0x4A, 0x36, 0x42, 0x32, 0x00, 0x00,
];
let parts = UndefinedStruct::new(&struct_type9);
let test_struct = SMBiosSystemSlot::new(&parts);
assert_eq!(test_struct.slot_designation(), Some("J6B2".to_string()));
assert_eq!(
*test_struct.system_slot_type().unwrap(),
SystemSlotType::PciExpress
);
assert_eq!(*test_struct.slot_data_bus_width().unwrap(), SlotWidth::X16);
assert!(test_struct.data_bus_width().is_none());
let struct_type9 = vec![
0x09, 0x1C, 0x1C, 0x00, 0x01, 0xA5, 0x0D, 0x04, 0x04, 0x00, 0x00, 0x0C, 0x01, 0x00,
0x00, 0x00, 0x08, 0x99, 0x01, 0x23, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, 0xAB, 0x09,
0x4A, 0x36, 0x42, 0x32, 0x00, 0x00,
];
let parts = UndefinedStruct::new(&struct_type9);
let test_struct = SMBiosSystemSlot::new(&parts);
assert_eq!(test_struct.data_bus_width(), Some(0x99));
assert_eq!(test_struct.peer_group_count(), Some(0x01));
let mut iterator = test_struct.peer_group_iterator().into_iter();
let first = iterator.next().unwrap();
assert_eq!(first.segment_group_number(), Some(0x0123));
assert_eq!(first.bus_number(), Some(0x04));
assert_eq!(first.device_function_number(), Some(0x05));
assert_eq!(first.data_bus_width(), Some(0x06));
assert_eq!(test_struct.slot_information(), Some(0x07));
assert_eq!(*test_struct.slot_physical_width().unwrap(), SlotWidth::X1);
assert_eq!(test_struct.slot_pitch(), Some(0x09AB));
println!("{:?}", test_struct);
}
}