smbioslib/structs/types/
management_device.rs

1use crate::core::{strings::*, UndefinedStruct};
2use crate::SMBiosStruct;
3use serde::{ser::SerializeStruct, Serialize, Serializer};
4use std::fmt;
5use std::ops::Deref;
6
7/// # Management Device (Type 34)
8///
9/// The information in this structure defines the attributes of a Management Device.
10///
11/// Compliant with:
12/// DMTF SMBIOS Reference Specification 3.4.0 (DSP0134)
13/// Document Date: 2020-07-17
14pub struct SMBiosManagementDevice<'a> {
15    parts: &'a UndefinedStruct,
16}
17
18impl<'a> SMBiosStruct<'a> for SMBiosManagementDevice<'a> {
19    const STRUCT_TYPE: u8 = 34u8;
20
21    fn new(parts: &'a UndefinedStruct) -> Self {
22        Self { parts }
23    }
24
25    fn parts(&self) -> &'a UndefinedStruct {
26        self.parts
27    }
28}
29
30impl<'a> SMBiosManagementDevice<'a> {
31    /// Additional descriptive information about the device or its location
32    pub fn description(&self) -> SMBiosString {
33        self.parts.get_field_string(0x04)
34    }
35
36    /// Device's type
37    pub fn device_type(&self) -> Option<ManagementDeviceTypeData> {
38        self.parts
39            .get_field_byte(0x05)
40            .map(|raw| ManagementDeviceTypeData::from(raw))
41    }
42
43    /// Device's address
44    pub fn address(&self) -> Option<u32> {
45        self.parts.get_field_dword(0x06)
46    }
47
48    /// Type of addressing used to access the device
49    pub fn address_type(&self) -> Option<ManagementDeviceAddressTypeData> {
50        self.parts
51            .get_field_byte(0x0A)
52            .map(|raw| ManagementDeviceAddressTypeData::from(raw))
53    }
54}
55
56impl fmt::Debug for SMBiosManagementDevice<'_> {
57    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
58        fmt.debug_struct(std::any::type_name::<SMBiosManagementDevice<'_>>())
59            .field("header", &self.parts.header)
60            .field("description", &self.description())
61            .field("device_type", &self.device_type())
62            .field("address", &self.address())
63            .field("address_type", &self.address_type())
64            .finish()
65    }
66}
67
68impl Serialize for SMBiosManagementDevice<'_> {
69    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70    where
71        S: Serializer,
72    {
73        let mut state = serializer.serialize_struct("SMBiosManagementDevice", 5)?;
74        state.serialize_field("header", &self.parts.header)?;
75        state.serialize_field("description", &self.description())?;
76        state.serialize_field("device_type", &self.device_type())?;
77        state.serialize_field("address", &self.address())?;
78        state.serialize_field("address_type", &self.address_type())?;
79        state.end()
80    }
81}
82
83/// # Management Device - Type Data
84pub struct ManagementDeviceTypeData {
85    /// Raw value
86    ///
87    /// _raw_ is most useful when _value_ is None.
88    /// This is most likely to occur when the standard was updated but
89    /// this library code has not been updated to match the current
90    /// standard.
91    pub raw: u8,
92    /// The contained [ManagementDeviceType] value
93    pub value: ManagementDeviceType,
94}
95
96impl fmt::Debug for ManagementDeviceTypeData {
97    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
98        fmt.debug_struct(std::any::type_name::<ManagementDeviceTypeData>())
99            .field("raw", &self.raw)
100            .field("value", &self.value)
101            .finish()
102    }
103}
104
105impl Serialize for ManagementDeviceTypeData {
106    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107    where
108        S: Serializer,
109    {
110        let mut state = serializer.serialize_struct("ManagementDeviceTypeData", 2)?;
111        state.serialize_field("raw", &self.raw)?;
112        state.serialize_field("value", &self.value)?;
113        state.end()
114    }
115}
116
117impl fmt::Display for ManagementDeviceTypeData {
118    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119        match &self.value {
120            ManagementDeviceType::None => write!(f, "{}", &self.raw),
121            _ => write!(f, "{:?}", &self.value),
122        }
123    }
124}
125
126impl Deref for ManagementDeviceTypeData {
127    type Target = ManagementDeviceType;
128
129    fn deref(&self) -> &Self::Target {
130        &self.value
131    }
132}
133
134/// # Management Device - Type
135#[derive(Serialize, Debug, PartialEq, Eq)]
136pub enum ManagementDeviceType {
137    /// Other
138    Other,
139    /// Unknown
140    Unknown,
141    /// National Semiconductor LM75
142    NationalSemiconductorLM75,
143    /// National Semiconductor LM78
144    NationalSemiconductorLM78,
145    /// National Semiconductor LM79
146    NationalSemiconductorLM79,
147    /// National Semiconductor LM80
148    NationalSemiconductorLM80,
149    /// National Semiconductor LM81
150    NationalSemiconductorLM81,
151    /// Analog Devices ADM9240
152    AnalogDevicesADM9240,
153    /// Dallas Semiconductor DS1780
154    DallasSemiconductorDS1780,
155    /// Maxim 1617
156    Maxim1617,
157    /// Genesys GL518SM
158    GenesysGL518SM,
159    /// Winbond W83781D
160    WinbondW83781D,
161    /// Holtek HT82H791
162    HoltekHT82H791,
163    /// A value unknown to this standard, check the raw value
164    None,
165}
166
167impl From<u8> for ManagementDeviceTypeData {
168    fn from(raw: u8) -> Self {
169        ManagementDeviceTypeData {
170            value: match raw {
171                0x01 => ManagementDeviceType::Other,
172                0x02 => ManagementDeviceType::Unknown,
173                0x03 => ManagementDeviceType::NationalSemiconductorLM75,
174                0x04 => ManagementDeviceType::NationalSemiconductorLM78,
175                0x05 => ManagementDeviceType::NationalSemiconductorLM79,
176                0x06 => ManagementDeviceType::NationalSemiconductorLM80,
177                0x07 => ManagementDeviceType::NationalSemiconductorLM81,
178                0x08 => ManagementDeviceType::AnalogDevicesADM9240,
179                0x09 => ManagementDeviceType::DallasSemiconductorDS1780,
180                0x0A => ManagementDeviceType::Maxim1617,
181                0x0B => ManagementDeviceType::GenesysGL518SM,
182                0x0C => ManagementDeviceType::WinbondW83781D,
183                0x0D => ManagementDeviceType::HoltekHT82H791,
184                _ => ManagementDeviceType::None,
185            },
186            raw,
187        }
188    }
189}
190
191/// # Management Device — Address Type Data
192pub struct ManagementDeviceAddressTypeData {
193    /// Raw value
194    ///
195    /// _raw_ is most useful when _value_ is None.
196    /// This is most likely to occur when the standard was updated but
197    /// this library code has not been updated to match the current
198    /// standard.
199    pub raw: u8,
200    /// The contained [ManagementDeviceAddressType] value
201    pub value: ManagementDeviceAddressType,
202}
203
204impl fmt::Debug for ManagementDeviceAddressTypeData {
205    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
206        fmt.debug_struct(std::any::type_name::<ManagementDeviceAddressTypeData>())
207            .field("raw", &self.raw)
208            .field("value", &self.value)
209            .finish()
210    }
211}
212
213impl Serialize for ManagementDeviceAddressTypeData {
214    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
215    where
216        S: Serializer,
217    {
218        let mut state = serializer.serialize_struct("ManagementDeviceAddressTypeData", 2)?;
219        state.serialize_field("raw", &self.raw)?;
220        state.serialize_field("value", &self.value)?;
221        state.end()
222    }
223}
224
225impl fmt::Display for ManagementDeviceAddressTypeData {
226    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227        match &self.value {
228            ManagementDeviceAddressType::None => write!(f, "{}", &self.raw),
229            _ => write!(f, "{:?}", &self.value),
230        }
231    }
232}
233
234impl Deref for ManagementDeviceAddressTypeData {
235    type Target = ManagementDeviceAddressType;
236
237    fn deref(&self) -> &Self::Target {
238        &self.value
239    }
240}
241
242/// # Management Device — Address Type
243#[derive(Serialize, Debug, PartialEq, Eq)]
244pub enum ManagementDeviceAddressType {
245    /// Other
246    Other,
247    /// Unknown
248    Unknown,
249    /// I/O Port
250    IOPort,
251    /// Memory
252    Memory,
253    /// SM Bus
254    SMBus,
255    /// A value unknown to this standard, check the raw value
256    None,
257}
258
259impl From<u8> for ManagementDeviceAddressTypeData {
260    fn from(raw: u8) -> Self {
261        ManagementDeviceAddressTypeData {
262            value: match raw {
263                0x01 => ManagementDeviceAddressType::Other,
264                0x02 => ManagementDeviceAddressType::Unknown,
265                0x03 => ManagementDeviceAddressType::IOPort,
266                0x04 => ManagementDeviceAddressType::Memory,
267                0x05 => ManagementDeviceAddressType::SMBus,
268                _ => ManagementDeviceAddressType::None,
269            },
270            raw,
271        }
272    }
273}
274
275#[cfg(test)]
276mod tests {
277    use super::*;
278
279    #[test]
280    fn unit_test() {
281        let struct_type34 = vec![
282            0x22, 0x0B, 0x26, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x4C, 0x4D, 0x37,
283            0x38, 0x2D, 0x31, 0x00, 0x00,
284        ];
285
286        let parts = UndefinedStruct::new(&struct_type34);
287        let test_struct = SMBiosManagementDevice::new(&parts);
288
289        assert_eq!(test_struct.description().to_string(), "LM78-1".to_string());
290        assert_eq!(
291            *test_struct.device_type().unwrap(),
292            ManagementDeviceType::NationalSemiconductorLM78
293        );
294        assert_eq!(test_struct.address(), Some(0));
295        assert_eq!(
296            *test_struct.address_type().unwrap(),
297            ManagementDeviceAddressType::IOPort
298        );
299    }
300}