Skip to main content

ferrix_lib/
dmi.rs

1/* dmi.rs
2 *
3 * Copyright 2025 Michail Krasnov <mskrasnov07@ya.ru>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21//! DMI table parser. Uses `smbios-lib` to data provider
22//!
23//! ## Usage
24//!
25//! ```no-test
26//! use ferrix::dmi::DMITable;
27//! let dmi = DMITable::new().unwrap();
28//! dbg!(dmi);
29//! ```
30
31use std::fmt::Display;
32
33use crate::traits::ToJson;
34use anyhow::{Result, anyhow};
35use serde::{Deserialize, Serialize};
36pub use smbioslib::SMBiosData;
37
38/// A structure containing data from the DMI table
39///
40/// ## Usage
41///
42/// ```no-test
43/// use ferrix::dmi::DMITable;
44/// let dmi = DMITable::new().unwrap();
45/// dbg!(dmi);
46/// ```
47#[derive(Debug, Serialize, Clone)]
48pub struct DMITable {
49    /// Information about BIOS (Type 0)
50    pub bios: Bios,
51
52    /// Information about system (Type 1)
53    pub system: System,
54
55    /// Information about baseboard (or module) - Type 2
56    pub baseboard: Baseboard,
57
58    /// Information about system enclosure or chassis - Type 3
59    pub chassis: Chassis,
60
61    /// Information about processor - Type 4
62    pub processor: Processor,
63
64    // /// Information about memory controller (Type 5)
65    // pub memory_controller: MemoryController,
66    //
67    // /// Information about memory module (Type 6)
68    // pub memory_module: MemoryModule,
69    /// Information about CPU cache (Type 7)
70    // pub caches: Caches,
71
72    /// Information about port connectors (Type 8)
73    // pub ports: PortConnectors,
74
75    /// Information about physical memory array (Type 16)
76    // pub mem_array: MemoryArray,
77
78    /// Information about installed memory devices (Type 17)
79    pub mem_devices: MemoryDevices,
80}
81
82impl DMITable {
83    /// Get information from DMI table
84    ///
85    /// > **NOTE:** This data DOES NOT NEED to be updated periodically!
86    pub fn new() -> Result<Self> {
87        let table = smbioslib::table_load_from_device()?;
88        Ok(Self {
89            bios: Bios::new_from_table(&table)?,
90            system: System::new_from_table(&table)?,
91            baseboard: Baseboard::new_from_table(&table)?,
92            chassis: Chassis::new_from_table(&table)?,
93            processor: Processor::new_from_table(&table)?,
94            // caches: Caches::new_from_table(&table)?,
95            // ports: PortConnectors::new_from_table(&table)?,
96            // mem_array: MemoryArray::new_from_table(&table)?,
97            mem_devices: MemoryDevices::new_from_table(&table)?,
98        })
99    }
100
101    /// Performs serialization of structure data in JSON.
102    ///
103    /// The returned value will be a SINGLE LINE of JSON data
104    /// intended for reading by third-party software or for
105    /// transmission over the network.
106    pub fn to_json(&self) -> Result<String> {
107        Ok(serde_json::to_string(&self)?)
108    }
109
110    /// Performs serialization in "pretty" JSON
111    ///
112    /// JSON will contain unnecessary newline transitions and spaces
113    /// to visually separate the blocks. It is well suited for human
114    /// reading and analysis.
115    pub fn to_json_pretty(&self) -> Result<String> {
116        Ok(serde_json::to_string_pretty(&self)?)
117    }
118
119    /// Performs data serialization in XML format
120    pub fn to_xml(&self) -> Result<String> {
121        let xml = DMITableXml::from(self);
122        xml.to_xml()
123    }
124}
125
126impl ToJson for DMITable {}
127
128/****************************** NOTE *********************************
129 * Дичайший костыль для того, чтобы структура XML была корректной    *
130 * Если не обернуть данные в поле "hardware" (тег <hardware> в XML), *
131 * то итоговый XML просто не распарсится.                            *
132 *********************************************************************/
133#[derive(Serialize, Clone)]
134pub struct DMITableXml<'a> {
135    pub hardware: &'a DMITable,
136}
137
138impl<'a> DMITableXml<'a> {
139    pub fn to_xml(&self) -> Result<String> {
140        Ok(xml_serde::to_string(&self)?)
141    }
142}
143
144impl<'a> From<&'a DMITable> for DMITableXml<'a> {
145    fn from(value: &'a DMITable) -> Self {
146        Self { hardware: value }
147    }
148}
149
150macro_rules! impl_from_struct {
151    ($s:ident, $p:path, {
152        $(
153            $field_name:ident : $field_type:ty
154        ),* $(,)?
155    }) => {
156        impl From<$p> for $s {
157            fn from(value: $p) -> Self {
158                Self {
159                    $(
160                        $field_name: value.$field_name,
161                    )*
162                }
163            }
164        }
165
166        impl ToJson for $s {}
167    };
168}
169
170/// Each SMBIOS structure has a handle or instance value associated
171/// with it. Some structs will reference other structures by using
172/// this value.
173#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
174pub struct Handle(pub u16);
175
176impl From<smbioslib::Handle> for Handle {
177    fn from(value: smbioslib::Handle) -> Self {
178        Self(value.0)
179    }
180}
181
182impl Handle {
183    pub fn from_opt(opt: Option<smbioslib::Handle>) -> Option<Self> {
184        match opt {
185            Some(handle) => Some(Handle::from(handle)),
186            None => None,
187        }
188    }
189}
190
191impl Display for Handle {
192    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193        write!(f, "{}", self.0)
194    }
195}
196
197/// BIOS ROM Size
198#[derive(Debug, Serialize, Deserialize, Clone)]
199pub enum RomSize {
200    /// Size of this ROM in bytes
201    Kilobytes(u16),
202
203    /// Extended size of the physical device(s) containing the
204    /// BIOS (in MB)
205    Megabytes(u16),
206
207    /// Extended size of the physical device(s) containing the
208    /// BIOS (in GB)
209    Gigabytes(u16),
210
211    /// Extended size of the physical device(s) containing the
212    /// BIOS in raw form.
213    ///
214    /// The standard currently only defines MB and GB as given
215    /// in the high nibble (bits 15-14).
216    Undefined(u16),
217
218    SeeExtendedRomSize,
219}
220
221impl From<smbioslib::RomSize> for RomSize {
222    fn from(value: smbioslib::RomSize) -> Self {
223        match value {
224            smbioslib::RomSize::Kilobytes(s) => Self::Kilobytes(s),
225            smbioslib::RomSize::Megabytes(s) => Self::Megabytes(s),
226            smbioslib::RomSize::Gigabytes(s) => Self::Gigabytes(s),
227            smbioslib::RomSize::Undefined(s) => Self::Undefined(s),
228            smbioslib::RomSize::SeeExtendedRomSize => Self::SeeExtendedRomSize,
229        }
230    }
231}
232
233impl Display for RomSize {
234    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235        write!(
236            f,
237            "{}",
238            match self {
239                Self::Kilobytes(n) => format!("{n} KB"),
240                Self::Megabytes(n) => format!("{n} MB"),
241                Self::Gigabytes(n) => format!("{n} GB"),
242                Self::Undefined(n) => format!("{n} ??"),
243                Self::SeeExtendedRomSize => format!("see extended ROM size"),
244            }
245        )
246    }
247}
248
249/// Information about BIOS/UEFI
250#[derive(Debug, Serialize, Deserialize, Clone)]
251pub struct Bios {
252    /// BIOS vendor's name
253    pub vendor: Option<String>,
254
255    /// BIOS version
256    pub version: Option<String>,
257
258    /// BIOS starting address segment
259    pub starting_address_segment: Option<u16>,
260
261    /// BIOS release date
262    pub release_date: Option<String>,
263
264    /// BIOS ROM size
265    pub rom_size: Option<RomSize>,
266
267    /// BIOS characteristics
268    pub characteristics: Option<BiosCharacteristics>,
269
270    /// BIOS vendor reserved characteristics
271    pub bios_vendor_reserved_characteristics: Option<u16>,
272
273    /// System vendor reserved characteristics
274    pub system_vendor_reserved_characteristics: Option<u16>,
275
276    /// Characteristics extension byte 0
277    pub characteristics_extension0: Option<BiosCharacteristicsExtension0>,
278
279    /// Characteristics extension byte 1
280    pub characteristics_extension1: Option<BiosCharacteristicsExtension1>,
281
282    /// System BIOS major release
283    pub system_bios_major_release: Option<u8>,
284
285    /// System BIOS minor release
286    pub system_bios_minor_release: Option<u8>,
287
288    /// Embedded controller firmware major release
289    pub e_c_firmware_major_release: Option<u8>,
290
291    /// Embedded controller firmware minor release
292    pub e_c_firmware_minor_release: Option<u8>,
293
294    /// Extended BIOS ROM size
295    pub extended_rom_size: Option<RomSize>,
296}
297
298impl Bios {
299    /// Creates a new instance of `Self`
300    ///
301    /// It is usually not required, since an instance of this
302    /// structure will be created using the method
303    /// [`Self::new_from_table(table: &SMBiosData)`] in the constructor
304    /// [`DMITable::new()`].
305    pub fn new() -> Result<Self> {
306        let table = smbioslib::table_load_from_device()?;
307        Self::new_from_table(&table)
308    }
309
310    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
311        let t = table
312            .find_map(|f: smbioslib::SMBiosInformation| Some(f))
313            .ok_or(anyhow!("Failed to get information about BIOS (type 0)!"))?;
314
315        Ok(Self {
316            vendor: t.vendor().ok(),
317            version: t.version().ok(),
318            starting_address_segment: t.starting_address_segment(),
319            release_date: t.release_date().ok(),
320            rom_size: match t.rom_size() {
321                Some(s) => Some(RomSize::from(s)),
322                None => None,
323            },
324            characteristics: match t.characteristics() {
325                Some(c) => Some(BiosCharacteristics::from(c)),
326                None => None,
327            },
328            bios_vendor_reserved_characteristics: t.bios_vendor_reserved_characteristics(),
329            system_vendor_reserved_characteristics: t.system_vendor_reserved_characteristics(),
330            characteristics_extension0: match t.characteristics_extension0() {
331                Some(ce0) => Some(BiosCharacteristicsExtension0::from(ce0)),
332                None => None,
333            },
334            characteristics_extension1: match t.characteristics_extension1() {
335                Some(ce1) => Some(BiosCharacteristicsExtension1::from(ce1)),
336                None => None,
337            },
338            system_bios_major_release: t.system_bios_major_release(),
339            system_bios_minor_release: t.system_bios_minor_release(),
340            e_c_firmware_major_release: t.e_c_firmware_major_release(),
341            e_c_firmware_minor_release: t.e_c_firmware_minor_release(),
342            extended_rom_size: match t.extended_rom_size() {
343                Some(s) => Some(RomSize::from(s)),
344                None => None,
345            },
346        })
347    }
348}
349
350impl ToJson for Bios {}
351
352/// BIOS characteristics
353#[derive(Debug, Serialize, Deserialize, Clone)]
354pub struct BiosCharacteristics {
355    /// Unknown
356    pub unknown: bool,
357
358    /// BIOS Characteristics aren't supported
359    pub bios_characteristics_not_supported: bool,
360
361    /// ISA is supported
362    pub isa_supported: bool,
363
364    /// MCA is supported
365    pub mca_supported: bool,
366
367    /// EISA is supported
368    pub eisa_supported: bool,
369
370    /// PCI is supported
371    pub pci_supported: bool,
372
373    /// PCMCIA is supported
374    pub pcmcia_supported: bool,
375
376    /// Plug-n-play is supported
377    pub plug_and_play_supported: bool,
378
379    /// APM is supported
380    pub apm_supported: bool,
381
382    /// BIOS is upgradeable (Flash)
383    pub bios_upgradeable: bool,
384
385    /// BIOS shadowing is allowed
386    pub bios_shadowing_allowed: bool,
387
388    /// VL-VESA is supported
389    pub vlvesa_supported: bool,
390
391    /// ESCD support is available
392    pub escd_support_available: bool,
393
394    /// Boot from CD is supported
395    pub boot_from_cdsupported: bool,
396
397    /// Selectable boot is supported
398    pub selectable_boot_supported: bool,
399
400    /// BIOS ROM is socketed (e.g. PLCC or SOP socket)
401    pub bios_rom_socketed: bool,
402
403    /// Boot from PCMCIA is supported
404    pub boot_from_pcmcia_supported: bool,
405
406    /// EDD specification is supported
407    pub edd_specification_supported: bool,
408
409    /// Japanese floppy for NEC 9800 1.2 MB (3.5", 1K bytes/sector,
410    /// 360 RPM) is supported
411    pub floppy_nec_japanese_supported: bool,
412
413    /// Japanese floppy for Toshiba 1.2 MB (3.5", 360 RPM) is
414    /// supported
415    pub floppy_toshiba_japanese_supported: bool,
416
417    /// 5.25" / 360 KB floppy services are supported
418    pub floppy_525_360_supported: bool,
419
420    /// 5.25" / 1.2 MB floppy services are supported
421    pub floppy_525_12_supported: bool,
422
423    /// 3.5" / 720 KB floppy services are supported
424    pub floppy_35_720_supported: bool,
425
426    /// 3.5" 2.88 MB floppy services are supported
427    pub floppy_35_288_supported: bool,
428
429    /// PrintScreen service is supported
430    pub print_screen_service_supported: bool,
431
432    /// 8042 keyboard services are supported
433    pub keyboard_8042services_supported: bool,
434
435    /// Serial services are supported
436    pub serial_services_supported: bool,
437
438    /// Printer services are supported
439    pub printer_services_supported: bool,
440
441    /// CGA/Mono Video Services are supported
442    pub cga_mono_video_services_supported: bool,
443
444    /// NEC PC-98 supported
445    pub nec_pc_98supported: bool,
446}
447
448impl From<smbioslib::BiosCharacteristics> for BiosCharacteristics {
449    fn from(value: smbioslib::BiosCharacteristics) -> Self {
450        Self {
451            unknown: value.unknown(),
452            bios_characteristics_not_supported: value.bios_characteristics_not_supported(),
453            isa_supported: value.isa_supported(),
454            mca_supported: value.mca_supported(),
455            eisa_supported: value.eisa_supported(),
456            pci_supported: value.pci_supported(),
457            pcmcia_supported: value.pcmcia_supported(),
458            plug_and_play_supported: value.plug_and_play_supported(),
459            apm_supported: value.apm_supported(),
460            bios_upgradeable: value.bios_upgradeable(),
461            bios_shadowing_allowed: value.bios_shadowing_allowed(),
462            vlvesa_supported: value.vlvesa_supported(),
463            escd_support_available: value.escd_support_available(),
464            boot_from_cdsupported: value.boot_from_cdsupported(),
465            selectable_boot_supported: value.selectable_boot_supported(),
466            bios_rom_socketed: value.bios_rom_socketed(),
467            boot_from_pcmcia_supported: value.boot_from_pcmcia_supported(),
468            edd_specification_supported: value.edd_specification_supported(),
469            floppy_nec_japanese_supported: value.floppy_nec_japanese_supported(),
470            floppy_toshiba_japanese_supported: value.floppy_toshiba_japanese_supported(),
471            floppy_525_360_supported: value.floppy_525_360_supported(),
472            floppy_525_12_supported: value.floppy_525_12_supported(),
473            floppy_35_720_supported: value.floppy_35_720_supported(),
474            floppy_35_288_supported: value.floppy_35_288_supported(),
475            print_screen_service_supported: value.print_screen_service_supported(),
476            keyboard_8042services_supported: value.keyboard_8042services_supported(),
477            serial_services_supported: value.serial_services_supported(),
478            printer_services_supported: value.printer_services_supported(),
479            cga_mono_video_services_supported: value.cga_mono_video_services_supported(),
480            nec_pc_98supported: value.nec_pc_98supported(),
481        }
482    }
483}
484impl ToJson for BiosCharacteristics {}
485
486/// Characteristics extension byte 0
487#[derive(Debug, Serialize, Deserialize, Clone)]
488pub struct BiosCharacteristicsExtension0 {
489    /// ACPI is supported
490    pub acpi_is_supported: bool,
491
492    /// USB Legacy is supported
493    pub usb_legacy_is_supported: bool,
494
495    /// AGP is supported
496    pub agp_is_supported: bool,
497
498    /// I2O boot is supported
499    pub i2oboot_is_supported: bool,
500
501    /// LS-120 SuperDisk boot is supported
502    pub ls120super_disk_boot_is_supported: bool,
503
504    /// ATAPI ZIP drive boot is supported
505    pub atapi_zip_drive_boot_is_supported: bool,
506
507    /// 1394 boot is supported
508    pub boot_1394is_supported: bool,
509
510    /// Smart battery is supported
511    pub smart_battery_is_supported: bool,
512}
513
514impl From<smbioslib::BiosCharacteristicsExtension0> for BiosCharacteristicsExtension0 {
515    fn from(value: smbioslib::BiosCharacteristicsExtension0) -> Self {
516        Self {
517            acpi_is_supported: value.acpi_is_supported(),
518            usb_legacy_is_supported: value.usb_legacy_is_supported(),
519            agp_is_supported: value.agp_is_supported(),
520            i2oboot_is_supported: value.i2oboot_is_supported(),
521            ls120super_disk_boot_is_supported: value.ls120super_disk_boot_is_supported(),
522            atapi_zip_drive_boot_is_supported: value.atapi_zip_drive_boot_is_supported(),
523            boot_1394is_supported: value.boot_1394is_supported(),
524            smart_battery_is_supported: value.smart_battery_is_supported(),
525        }
526    }
527}
528impl ToJson for BiosCharacteristicsExtension0 {}
529
530/// Characteristics extension byte 0
531#[derive(Debug, Serialize, Deserialize, Clone)]
532pub struct BiosCharacteristicsExtension1 {
533    /// BIOS Boot Specification is supported
534    pub bios_boot_specification_is_supported: bool,
535
536    /// Function key-initiated network service boot is supported.
537    /// When function key-uninitiated network service boot is not
538    /// supported, a network adapter option ROM may choose to offer
539    /// this functionality on its own, thus offering this capability
540    /// to legacy systems. When the function is supported, the
541    /// network adapter option ROM shall not offer this capability
542    pub fkey_initiated_network_boot_is_supported: bool,
543
544    /// Enable targeted content distribution. The manufacturer has
545    /// ensured that the SMBIOS data is useful in identifying the
546    /// computer for targeted delivery of model-specific software
547    /// and firmware content through third-party content
548    /// distribution services
549    pub targeted_content_distribution_is_supported: bool,
550
551    /// UEFI Specification is supported
552    pub uefi_specification_is_supported: bool,
553
554    /// SMBIOS table describes a virtual machine
555    pub smbios_table_describes_avirtual_machine: bool,
556
557    /// Manufacturing mode is supported. (Manufacturing mode is a
558    /// special boot mode, not normally available to end users, that
559    /// modifies BIOS features and settings for use while the
560    /// computer is being manufactured and tested)
561    pub manufacturing_mode_is_supported: bool,
562
563    /// Manufacturing mode is enabled
564    pub manufacturing_mode_is_enabled: bool,
565}
566
567impl From<smbioslib::BiosCharacteristicsExtension1> for BiosCharacteristicsExtension1 {
568    fn from(value: smbioslib::BiosCharacteristicsExtension1) -> Self {
569        Self {
570            bios_boot_specification_is_supported: value.bios_boot_specification_is_supported(),
571            fkey_initiated_network_boot_is_supported: value
572                .fkey_initiated_network_boot_is_supported(),
573            targeted_content_distribution_is_supported: value
574                .targeted_content_distribution_is_supported(),
575            uefi_specification_is_supported: value.uefi_specification_is_supported(),
576            smbios_table_describes_avirtual_machine: value
577                .smbios_table_describes_avirtual_machine(),
578            manufacturing_mode_is_supported: value.manufacturing_mode_is_supported(),
579            manufacturing_mode_is_enabled: value.manufacturing_mode_is_enabled(),
580        }
581    }
582}
583impl ToJson for BiosCharacteristicsExtension1 {}
584
585/// System UUID Data
586#[derive(Debug, Serialize, Deserialize, Clone)]
587pub enum SystemUuidData {
588    IdNotPresentButSettable,
589    IdNotPresent,
590    Uuid(SystemUuid),
591}
592
593impl From<smbioslib::SystemUuidData> for SystemUuidData {
594    fn from(value: smbioslib::SystemUuidData) -> Self {
595        match value {
596            smbioslib::SystemUuidData::IdNotPresentButSettable => Self::IdNotPresentButSettable,
597            smbioslib::SystemUuidData::IdNotPresent => Self::IdNotPresent,
598            smbioslib::SystemUuidData::Uuid(u) => Self::Uuid(SystemUuid::from(u)),
599        }
600    }
601}
602
603impl Display for SystemUuidData {
604    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
605        write!(
606            f,
607            "{}",
608            match self {
609                Self::IdNotPresentButSettable => format!("ID not present but settable"),
610                Self::IdNotPresent => format!("ID not present"),
611                Self::Uuid(uuid) => format!("{uuid}"),
612            }
613        )
614    }
615}
616
617/// System UUID
618#[derive(Debug, Serialize, Deserialize, Clone)]
619pub struct SystemUuid {
620    /// Raw byte array for this UUID
621    pub raw: [u8; 16],
622}
623
624impl_from_struct!(SystemUuid, smbioslib::SystemUuid, {
625    raw: [u8; 16],
626});
627
628impl Display for SystemUuid {
629    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
630        let time_low = u32::from_le_bytes([self.raw[0], self.raw[1], self.raw[2], self.raw[3]]);
631        let time_mid = u16::from_le_bytes([self.raw[4], self.raw[5]]);
632        let time_hi = u16::from_le_bytes([self.raw[6], self.raw[7]]);
633
634        let mut s = format!("{:08x}-{:04x}-{:04x}-", time_low, time_mid, time_hi);
635        let mut i = 8;
636
637        while i <= 9 {
638            s.push_str(&format!("{:02x}", self.raw[i]));
639            i += 1;
640        }
641        s.push('-');
642        while i < 16 {
643            s.push_str(&format!("{:02x}", self.raw[i]));
644            i += 1;
645        }
646        write!(f, "{s}",)
647    }
648}
649
650/// System wakeup data
651#[derive(Debug, Serialize, Deserialize, Clone)]
652pub struct SystemWakeUpTypeData {
653    /// Raw value
654    ///
655    /// Is most usable when `value` is None
656    pub raw: u8,
657
658    pub value: SystemWakeUpType,
659}
660
661impl From<smbioslib::SystemWakeUpTypeData> for SystemWakeUpTypeData {
662    fn from(value: smbioslib::SystemWakeUpTypeData) -> Self {
663        Self {
664            raw: value.raw,
665            value: SystemWakeUpType::from(value.value),
666        }
667    }
668}
669
670/// System wakeup type
671#[derive(Debug, Serialize, Deserialize, Clone)]
672pub enum SystemWakeUpType {
673    Other,
674    Unknown,
675    ApmTimer,
676    ModernRing,
677    LanRemote,
678    PowerSwitch,
679    PciPme,
680    ACPowerRestored,
681    None,
682}
683
684impl From<smbioslib::SystemWakeUpType> for SystemWakeUpType {
685    fn from(value: smbioslib::SystemWakeUpType) -> Self {
686        match value {
687            smbioslib::SystemWakeUpType::Other => Self::Other,
688            smbioslib::SystemWakeUpType::Unknown => Self::Unknown,
689            smbioslib::SystemWakeUpType::ApmTimer => Self::ApmTimer,
690            smbioslib::SystemWakeUpType::ModernRing => Self::ModernRing,
691            smbioslib::SystemWakeUpType::LanRemote => Self::LanRemote,
692            smbioslib::SystemWakeUpType::PowerSwitch => Self::PowerSwitch,
693            smbioslib::SystemWakeUpType::PciPme => Self::PciPme,
694            smbioslib::SystemWakeUpType::ACPowerRestored => Self::ACPowerRestored,
695            smbioslib::SystemWakeUpType::None => Self::None,
696        }
697    }
698}
699
700impl Display for SystemWakeUpType {
701    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
702        write!(
703            f,
704            "{}",
705            match self {
706                Self::Other => "Other",
707                Self::Unknown => "Unknown",
708                Self::ApmTimer => "APM Timer",
709                Self::ModernRing => "Modern Ring",
710                Self::LanRemote => "LAN Remote",
711                Self::PowerSwitch => "Power Switch",
712                Self::PciPme => "PCI PME#",
713                Self::ACPowerRestored => "AC Power Restored",
714                Self::None => "Unknown to this standard, check the raw value",
715            }
716        )
717    }
718}
719
720/// Attributes of the overall system
721#[derive(Debug, Serialize, Deserialize, Clone)]
722pub struct System {
723    /// System manufacturer
724    pub manufacturer: Option<String>,
725
726    /// System product name
727    pub product_name: Option<String>,
728
729    /// System version
730    pub version: Option<String>,
731
732    /// Serial number
733    pub serial_number: Option<String>,
734
735    /// System UUID
736    pub uuid: Option<SystemUuidData>,
737
738    /// Wake-up type
739    ///
740    /// Identifies the event that caused the system to power up
741    pub wakeup_type: Option<SystemWakeUpTypeData>,
742
743    /// SKU Number (particular computer information for sale.
744    /// Also called a product ID or purchase order number.
745    /// Typically for a given system board from a given OEM,
746    /// there are tens of unique processor, memory, hard
747    /// drive, and optical drive configurations).
748    pub sku_number: Option<String>,
749
750    /// Family to which a particular computer belongs
751    pub family: Option<String>,
752}
753
754impl System {
755    /// Creates a new instance of `Self`
756    ///
757    /// It is usually not required, since an instance of this
758    /// structure will be created using the method
759    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
760    /// [`DMITable::new()`].
761    pub fn new() -> Result<Self> {
762        let table = smbioslib::table_load_from_device()?;
763        Self::new_from_table(&table)
764    }
765
766    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
767        let t = table
768            .find_map(|f: smbioslib::SMBiosSystemInformation| Some(f))
769            .ok_or(anyhow!("Failed to get information about system (type 1)!"))?;
770
771        Ok(Self {
772            manufacturer: t.manufacturer().ok(),
773            product_name: t.product_name().ok(),
774            version: t.version().ok(),
775            serial_number: t.serial_number().ok(),
776            uuid: match t.uuid() {
777                Some(u) => Some(SystemUuidData::from(u)),
778                None => None,
779            },
780            wakeup_type: match t.wakeup_type() {
781                Some(wt) => Some(SystemWakeUpTypeData::from(wt)),
782                None => None,
783            },
784            sku_number: t.sku_number().ok(),
785            family: t.family().ok(),
786        })
787    }
788}
789
790impl ToJson for System {}
791
792/// Board type data
793#[derive(Debug, Serialize, Deserialize, Clone)]
794pub struct BoardTypeData {
795    pub raw: u8,
796    pub value: BoardType,
797}
798
799impl From<smbioslib::BoardTypeData> for BoardTypeData {
800    fn from(value: smbioslib::BoardTypeData) -> Self {
801        Self {
802            raw: value.raw,
803            value: BoardType::from(value.value),
804        }
805    }
806}
807
808/// Board type
809#[derive(Debug, Serialize, Deserialize, Clone)]
810pub enum BoardType {
811    Unknown,
812    Other,
813    ServerBlade,
814    ConnectivitySwitch,
815    SystemManagementModule,
816    ProcessorModule,
817    IOModule,
818    MemoryModule,
819    Daughterboard,
820    Motherboard,
821    ProcessorMemoryModule,
822    ProcessorIOModule,
823    InterconnectBoard,
824    None,
825}
826
827impl From<smbioslib::BoardType> for BoardType {
828    fn from(value: smbioslib::BoardType) -> Self {
829        match value {
830            smbioslib::BoardType::Unknown => Self::Unknown,
831            smbioslib::BoardType::Other => Self::Other,
832            smbioslib::BoardType::ServerBlade => Self::ServerBlade,
833            smbioslib::BoardType::ConnectivitySwitch => Self::ConnectivitySwitch,
834            smbioslib::BoardType::SystemManagementModule => Self::SystemManagementModule,
835            smbioslib::BoardType::ProcessorModule => Self::ProcessorModule,
836            smbioslib::BoardType::IOModule => Self::IOModule,
837            smbioslib::BoardType::MemoryModule => Self::MemoryModule,
838            smbioslib::BoardType::Daughterboard => Self::Daughterboard,
839            smbioslib::BoardType::Motherboard => Self::Motherboard,
840            smbioslib::BoardType::ProcessorMemoryModule => Self::ProcessorMemoryModule,
841            smbioslib::BoardType::ProcessorIOModule => Self::ProcessorIOModule,
842            smbioslib::BoardType::InterconnectBoard => Self::InterconnectBoard,
843            smbioslib::BoardType::None => Self::None,
844        }
845    }
846}
847
848impl Display for BoardType {
849    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
850        write!(
851            f,
852            "{}",
853            match self {
854                Self::Unknown => "Unknown",
855                Self::Other => "Other",
856                Self::ServerBlade => "Server Blade",
857                Self::ConnectivitySwitch => "Connectivity Switch",
858                Self::SystemManagementModule => "System Management Module",
859                Self::ProcessorModule => "Processor Module",
860                Self::IOModule => "I/O Module",
861                Self::MemoryModule => "Memory Module",
862                Self::Daughterboard => "Daughter Board",
863                Self::Motherboard => "Motherboard (includes processor, memory, and I/O)",
864                Self::ProcessorMemoryModule => "Processor or Memory Module",
865                Self::ProcessorIOModule => "Processor or I/O Module",
866                Self::InterconnectBoard => "Interconnect Board",
867                Self::None => "Unknown to this standard, check the raw value",
868            }
869        )
870    }
871}
872
873/// Information about baseboard/module
874#[derive(Debug, Serialize, Deserialize, Clone)]
875pub struct Baseboard {
876    /// Baseboard manufacturer
877    pub manufacturer: Option<String>,
878
879    /// Baseboard product
880    pub product: Option<String>,
881
882    /// Baseboard serial number
883    pub serial_number: Option<String>,
884
885    /// Asset tag
886    pub asset_tag: Option<String>,
887
888    /// Baseboard feature flags
889    pub feature_flags: Option<BaseboardFeatures>,
890
891    /// The board's location within the chassis
892    pub location_in_chassis: Option<String>,
893
894    /// Handle, or instance number, associated with the chassis in
895    /// which this board resides.
896    pub chassis_handle: Option<Handle>,
897
898    /// Type of baseboard
899    pub board_type: Option<BoardTypeData>,
900}
901
902impl Baseboard {
903    /// Creates a new instance of `Self`
904    ///
905    /// It is usually not required, since an instance of this
906    /// structure will be created using the method
907    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
908    /// [`DMITable::new()`].
909    pub fn new() -> Result<Self> {
910        let table = smbioslib::table_load_from_device()?;
911        Self::new_from_table(&table)
912    }
913
914    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
915        let t = table
916            .find_map(|f: smbioslib::SMBiosBaseboardInformation| Some(f))
917            .ok_or(anyhow!(
918                "Failed to get information about baseboard/module (type 2)!"
919            ))?;
920        Ok(Self {
921            manufacturer: t.manufacturer().ok(),
922            product: t.product().ok(),
923            serial_number: t.serial_number().ok(),
924            asset_tag: t.asset_tag().ok(),
925            feature_flags: match t.feature_flags() {
926                Some(ff) => Some(BaseboardFeatures::from(ff)),
927                None => None,
928            },
929            location_in_chassis: t.location_in_chassis().ok(),
930            chassis_handle: match t.chassis_handle() {
931                Some(h) => Some(Handle::from(h)),
932                None => None,
933            },
934            board_type: match t.board_type() {
935                Some(bt) => Some(BoardTypeData::from(bt)),
936                None => None,
937            },
938        })
939    }
940}
941
942impl ToJson for Baseboard {}
943
944/// Baseboard feature flags
945///
946/// Collection of flags that identify features of this board
947#[derive(Debug, Serialize, Deserialize, Clone)]
948pub struct BaseboardFeatures {
949    /// Set if the board is a hosting board (e.g. motherboard)
950    pub hosting_board: bool,
951
952    /// Set if the board requires at least one daughter board or
953    /// auxiliary card to function properly
954    pub requires_daughterboard: bool,
955
956    /// Set if the board is removable; it is designed to be taken in
957    /// and out of the chassis without impairing the function of
958    /// the chassis
959    pub is_removable: bool,
960
961    /// Set if the board is replaceable; it is possible to replace
962    /// (either as a field repair or as an upgrade) the board with a
963    /// physically different board. The board is inherently removable
964    pub is_replaceable: bool,
965
966    /// Set if the board if hot swappable; it is possible to replace
967    /// the board with a physically different but equivalent board
968    /// while power is applied to the board. The board is
969    /// inherently replaceable and removable.
970    pub is_hot_swappable: bool,
971}
972
973impl From<smbioslib::BaseboardFeatures> for BaseboardFeatures {
974    fn from(value: smbioslib::BaseboardFeatures) -> Self {
975        Self {
976            hosting_board: value.hosting_board(),
977            requires_daughterboard: value.requires_daughterboard(),
978            is_removable: value.is_removable(),
979            is_replaceable: value.is_replaceable(),
980            is_hot_swappable: value.is_hot_swappable(),
981        }
982    }
983}
984impl ToJson for BaseboardFeatures {}
985
986/// Chassis type data
987#[derive(Debug, Serialize, Deserialize, Clone)]
988pub struct ChassisTypeData {
989    pub raw: u8,
990    pub value: ChassisType,
991    pub lock_presence: ChassisLockPresence,
992}
993
994impl From<smbioslib::ChassisTypeData> for ChassisTypeData {
995    fn from(value: smbioslib::ChassisTypeData) -> Self {
996        Self {
997            raw: value.raw,
998            value: ChassisType::from(value.value),
999            lock_presence: ChassisLockPresence::from(value.lock_presence),
1000        }
1001    }
1002}
1003
1004/// Chassis type
1005#[derive(Debug, Serialize, Deserialize, Clone)]
1006pub enum ChassisType {
1007    Other,
1008    Unknown,
1009    Desktop,
1010    LowProfileDesktop,
1011    PizzaBox,
1012    MiniTower,
1013    Tower,
1014    Portable,
1015    Laptop,
1016    Notebook,
1017    HandHeld,
1018    DockingStation,
1019    AllInOne,
1020    SubNotebook,
1021    SpaceSaving,
1022    LunchBox,
1023    MainServerChassis,
1024    ExpansionChassis,
1025    SubChassis,
1026    BusExpansionChassis,
1027    PeripheralChassis,
1028    RaidChassis,
1029    RackMountChassis,
1030    SealedCasePC,
1031    MultiSystemChassis,
1032    CompactPci,
1033    AdvancedTca,
1034    Blade,
1035    BladeEnclosure,
1036    Tablet,
1037    Convertible,
1038    Detachable,
1039    IoTGateway,
1040    EmbeddedPC,
1041    MiniPC,
1042    StickPC,
1043    None,
1044}
1045
1046impl From<smbioslib::ChassisType> for ChassisType {
1047    fn from(value: smbioslib::ChassisType) -> Self {
1048        match value {
1049            smbioslib::ChassisType::Other => Self::Other,
1050            smbioslib::ChassisType::Unknown => Self::Unknown,
1051            smbioslib::ChassisType::Desktop => Self::Desktop,
1052            smbioslib::ChassisType::LowProfileDesktop => Self::LowProfileDesktop,
1053            smbioslib::ChassisType::PizzaBox => Self::PizzaBox,
1054            smbioslib::ChassisType::MiniTower => Self::MiniTower,
1055            smbioslib::ChassisType::Tower => Self::Tower,
1056            smbioslib::ChassisType::Portable => Self::Portable,
1057            smbioslib::ChassisType::Laptop => Self::Laptop,
1058            smbioslib::ChassisType::Notebook => Self::Notebook,
1059            smbioslib::ChassisType::HandHeld => Self::HandHeld,
1060            smbioslib::ChassisType::DockingStation => Self::DockingStation,
1061            smbioslib::ChassisType::AllInOne => Self::AllInOne,
1062            smbioslib::ChassisType::SubNotebook => Self::SubNotebook,
1063            smbioslib::ChassisType::SpaceSaving => Self::SpaceSaving,
1064            smbioslib::ChassisType::LunchBox => Self::LunchBox,
1065            smbioslib::ChassisType::MainServerChassis => Self::MainServerChassis,
1066            smbioslib::ChassisType::ExpansionChassis => Self::ExpansionChassis,
1067            smbioslib::ChassisType::SubChassis => Self::SubChassis,
1068            smbioslib::ChassisType::BusExpansionChassis => Self::BusExpansionChassis,
1069            smbioslib::ChassisType::PeripheralChassis => Self::PeripheralChassis,
1070            smbioslib::ChassisType::RaidChassis => Self::RaidChassis,
1071            smbioslib::ChassisType::RackMountChassis => Self::RackMountChassis,
1072            smbioslib::ChassisType::SealedCasePC => Self::SealedCasePC,
1073            smbioslib::ChassisType::MultiSystemChassis => Self::MultiSystemChassis,
1074            smbioslib::ChassisType::CompactPci => Self::CompactPci,
1075            smbioslib::ChassisType::AdvancedTca => Self::AdvancedTca,
1076            smbioslib::ChassisType::Blade => Self::Blade,
1077            smbioslib::ChassisType::BladeEnclosure => Self::BladeEnclosure,
1078            smbioslib::ChassisType::Tablet => Self::Tablet,
1079            smbioslib::ChassisType::Convertible => Self::Convertible,
1080            smbioslib::ChassisType::Detachable => Self::Detachable,
1081            smbioslib::ChassisType::IoTGateway => Self::IoTGateway,
1082            smbioslib::ChassisType::EmbeddedPC => Self::EmbeddedPC,
1083            smbioslib::ChassisType::MiniPC => Self::MiniPC,
1084            smbioslib::ChassisType::StickPC => Self::StickPC,
1085            smbioslib::ChassisType::None => Self::None,
1086        }
1087    }
1088}
1089
1090impl Display for ChassisType {
1091    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1092        write!(
1093            f,
1094            "{}",
1095            match self {
1096                Self::Other => "Other",
1097                Self::Unknown => "Unknown",
1098                Self::Desktop => "Desktop",
1099                Self::LowProfileDesktop => "Low profile desktop",
1100                Self::PizzaBox => "Pizza Box",
1101                Self::MiniTower => "Mini Tower",
1102                Self::Tower => "Tower",
1103                Self::Portable => "Portable",
1104                Self::Laptop => "Laptop",
1105                Self::Notebook => "Notebook",
1106                Self::HandHeld => "Hand Held",
1107                Self::DockingStation => "Docking Station",
1108                Self::AllInOne => "All In One",
1109                Self::SubNotebook => "Sub Notebook",
1110                Self::SpaceSaving => "Space Saving",
1111                Self::LunchBox => "Lunch Box",
1112                Self::MainServerChassis => "Main server chassis",
1113                Self::ExpansionChassis => "Expansion chassis",
1114                Self::SubChassis => "Sub chassis",
1115                Self::BusExpansionChassis => "Bus expansion chassis",
1116                Self::PeripheralChassis => "Peripheral chassis",
1117                Self::RaidChassis => "RAID chassis",
1118                Self::RackMountChassis => "Rack Mount chassis",
1119                Self::SealedCasePC => "Sealed-case chassis",
1120                Self::MultiSystemChassis => "Multi-system chassis",
1121                Self::CompactPci => "Compact PCI",
1122                Self::AdvancedTca => "Advanced TCA",
1123                Self::Blade => "Blade",
1124                Self::BladeEnclosure => "Blade encloser",
1125                Self::Tablet => "Tablet",
1126                Self::Convertible => "Convertivle",
1127                Self::Detachable => "Detachable",
1128                Self::IoTGateway => "IoT Gateway",
1129                Self::EmbeddedPC => "Embedded PC",
1130                Self::MiniPC => "Mini PC",
1131                Self::StickPC => "Stick PC",
1132                Self::None => "Unknown to this standard, check the raw value",
1133            }
1134        )
1135    }
1136}
1137
1138/// Chassis lock presence
1139#[derive(Debug, Serialize, Deserialize, Clone)]
1140pub enum ChassisLockPresence {
1141    Present,
1142    NotPresent,
1143}
1144
1145impl From<smbioslib::ChassisLockPresence> for ChassisLockPresence {
1146    fn from(value: smbioslib::ChassisLockPresence) -> Self {
1147        match value {
1148            smbioslib::ChassisLockPresence::Present => Self::Present,
1149            smbioslib::ChassisLockPresence::NotPresent => Self::NotPresent,
1150        }
1151    }
1152}
1153
1154impl Display for ChassisLockPresence {
1155    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1156        write!(
1157            f,
1158            "{}",
1159            match self {
1160                Self::Present => "Present",
1161                Self::NotPresent => "Not present",
1162            }
1163        )
1164    }
1165}
1166
1167/// Chassis state data
1168#[derive(Debug, Serialize, Deserialize, Clone)]
1169pub struct ChassisStateData {
1170    pub raw: u8,
1171    pub value: ChassisState,
1172}
1173
1174impl From<smbioslib::ChassisStateData> for ChassisStateData {
1175    fn from(value: smbioslib::ChassisStateData) -> Self {
1176        Self {
1177            raw: value.raw,
1178            value: ChassisState::from(value.value),
1179        }
1180    }
1181}
1182
1183/// Chassis state
1184#[derive(Debug, Serialize, Deserialize, Clone)]
1185pub enum ChassisState {
1186    Other,
1187    Unknown,
1188    Safe,
1189    Warning,
1190    Critical,
1191    NonRecoverable,
1192    None,
1193}
1194
1195impl From<smbioslib::ChassisState> for ChassisState {
1196    fn from(value: smbioslib::ChassisState) -> Self {
1197        match value {
1198            smbioslib::ChassisState::Other => Self::Other,
1199            smbioslib::ChassisState::Unknown => Self::Unknown,
1200            smbioslib::ChassisState::Safe => Self::Safe,
1201            smbioslib::ChassisState::Warning => Self::Warning,
1202            smbioslib::ChassisState::Critical => Self::Critical,
1203            smbioslib::ChassisState::NonRecoverable => Self::NonRecoverable,
1204            smbioslib::ChassisState::None => Self::None,
1205        }
1206    }
1207}
1208
1209impl Display for ChassisState {
1210    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1211        write!(
1212            f,
1213            "{}",
1214            match self {
1215                Self::Other => "Other",
1216                Self::Unknown => "Unknown",
1217                Self::Safe => "Safe",
1218                Self::Warning => "Warning",
1219                Self::Critical => "Critical",
1220                Self::NonRecoverable => "Non-recoverable",
1221                Self::None => "Unknown to this standard, check the raw value",
1222            }
1223        )
1224    }
1225}
1226
1227/// Chassis security status data
1228#[derive(Debug, Serialize, Deserialize, Clone)]
1229pub struct ChassisSecurityStatusData {
1230    pub raw: u8,
1231    pub value: ChassisSecurityStatus,
1232}
1233
1234impl From<smbioslib::ChassisSecurityStatusData> for ChassisSecurityStatusData {
1235    fn from(value: smbioslib::ChassisSecurityStatusData) -> Self {
1236        Self {
1237            raw: value.raw,
1238            value: ChassisSecurityStatus::from(value.value),
1239        }
1240    }
1241}
1242
1243/// Chassis security status
1244#[derive(Debug, Serialize, Deserialize, Clone)]
1245pub enum ChassisSecurityStatus {
1246    Other,
1247    Unknown,
1248    StatusNone,
1249    ExternalInterfaceLockedOut,
1250    ExternalInterfaceEnabled,
1251    None,
1252}
1253
1254impl From<smbioslib::ChassisSecurityStatus> for ChassisSecurityStatus {
1255    fn from(value: smbioslib::ChassisSecurityStatus) -> Self {
1256        match value {
1257            smbioslib::ChassisSecurityStatus::Other => Self::Other,
1258            smbioslib::ChassisSecurityStatus::Unknown => Self::Unknown,
1259            smbioslib::ChassisSecurityStatus::StatusNone => Self::StatusNone,
1260            smbioslib::ChassisSecurityStatus::ExternalInterfaceLockedOut => {
1261                Self::ExternalInterfaceLockedOut
1262            }
1263            smbioslib::ChassisSecurityStatus::ExternalInterfaceEnabled => {
1264                Self::ExternalInterfaceEnabled
1265            }
1266            smbioslib::ChassisSecurityStatus::None => Self::None,
1267        }
1268    }
1269}
1270
1271impl Display for ChassisSecurityStatus {
1272    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1273        write!(
1274            f,
1275            "{}",
1276            match self {
1277                Self::Other => "Other",
1278                Self::Unknown => "Unknown",
1279                Self::StatusNone => "None",
1280                Self::ExternalInterfaceLockedOut => "External interface locked out",
1281                Self::ExternalInterfaceEnabled => "External interface enabled",
1282                Self::None => "Unknown to this standard, check the raw value",
1283            }
1284        )
1285    }
1286}
1287
1288/// Chassis height
1289#[derive(Debug, Serialize, Deserialize, Clone)]
1290pub enum ChassisHeight {
1291    Unspecified,
1292    U(u8),
1293    SpecifiedInRackHeight,
1294}
1295
1296impl From<smbioslib::ChassisHeight> for ChassisHeight {
1297    fn from(value: smbioslib::ChassisHeight) -> Self {
1298        match value {
1299            smbioslib::ChassisHeight::Unspecified => Self::Unspecified,
1300            smbioslib::ChassisHeight::U(u) => Self::U(u),
1301            smbioslib::ChassisHeight::SpecifiedInRackHeight => Self::SpecifiedInRackHeight,
1302        }
1303    }
1304}
1305
1306impl Display for ChassisHeight {
1307    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1308        write!(
1309            f,
1310            "{}",
1311            match self {
1312                Self::Unspecified => format!("Unspecified"),
1313                Self::U(u) => format!("{u} U (1 U = 1.75 inch or 4.445 cm)"),
1314                Self::SpecifiedInRackHeight => "Height is specified in the Rack Height".to_string(),
1315            }
1316        )
1317    }
1318}
1319
1320/// Number of Power Cords
1321#[derive(Debug, Serialize, Deserialize, Clone)]
1322pub enum PowerCords {
1323    Unspecified,
1324    Count(u8),
1325}
1326
1327impl From<smbioslib::PowerCords> for PowerCords {
1328    fn from(value: smbioslib::PowerCords) -> Self {
1329        match value {
1330            smbioslib::PowerCords::Unspecified => Self::Unspecified,
1331            smbioslib::PowerCords::Count(cnt) => Self::Count(cnt),
1332        }
1333    }
1334}
1335
1336impl Display for PowerCords {
1337    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1338        write!(
1339            f,
1340            "{}",
1341            match self {
1342                Self::Unspecified => format!("Unspecified"),
1343                Self::Count(cnt) => format!("{cnt}"),
1344            }
1345        )
1346    }
1347}
1348
1349/// Information about system enclosure or chassis
1350#[derive(Debug, Serialize, Deserialize, Clone)]
1351pub struct Chassis {
1352    /// Enclosure/chassis manufacturer
1353    pub manufacturer: Option<String>,
1354
1355    /// Chassis type
1356    pub chassis_type: Option<ChassisTypeData>,
1357
1358    /// Version
1359    pub version: Option<String>,
1360
1361    /// Serial number
1362    pub serial_number: Option<String>,
1363
1364    /// Asset tag number
1365    pub asset_tag_number: Option<String>,
1366
1367    /// State of the enclosure whet it was last booted
1368    pub bootup_state: Option<ChassisStateData>,
1369
1370    /// State of the enclosure's power supply when last booted
1371    pub power_supply_state: Option<ChassisStateData>,
1372
1373    /// Thermal state of the enclosure when last booted
1374    pub thermal_state: Option<ChassisStateData>,
1375
1376    /// Physical security status of the enclosure when last booted
1377    pub security_status: Option<ChassisSecurityStatusData>,
1378
1379    /// OEM- or BIOS vendor-specific information
1380    pub oem_defined: Option<u32>,
1381
1382    /// Height of the enclosure, in 'U's
1383    ///
1384    /// A U is a standard unit of measure for the height of a rack
1385    /// or rack-mountable component and is equal to 1.75 inches or
1386    /// 4.445 cm
1387    pub height: Option<ChassisHeight>,
1388
1389    /// Number of power cords associated with the enclosure/chassis
1390    pub number_of_power_cords: Option<PowerCords>,
1391
1392    /// Number of Contained Element records that follow, in the
1393    /// range 0 to 255 Each Contained Element group comprises m
1394    /// bytes, as specified by the Contained Element Record Length
1395    /// field that follows. If no Contained Elements are included,
1396    /// this field is set to 0.
1397    pub contained_element_count: Option<u8>,
1398
1399    /// Byte length of eact Contained Element record that follows,
1400    /// in the range 0 to 255. If no Contained Elements are included,
1401    /// this field is set to 0
1402    pub contained_element_record_length: Option<u8>,
1403
1404    // TODO: this struct doesn't included ContainedElements<'_> iter!
1405    /// Chassis or enclosure SKU number
1406    pub sku_number: Option<String>,
1407}
1408
1409impl Chassis {
1410    /// Creates a new instance of `Self`
1411    ///
1412    /// It is usually not required, since an instance of this
1413    /// structure will be created using the method
1414    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
1415    /// [`DMITable::new()`].
1416    pub fn new() -> Result<Self> {
1417        let table = smbioslib::table_load_from_device()?;
1418        Self::new_from_table(&table)
1419    }
1420
1421    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
1422        let t = table
1423            .find_map(|f: smbioslib::SMBiosSystemChassisInformation| Some(f))
1424            .ok_or(anyhow!(
1425                "Failed to get information about system enclosure/chassis (type 3)!"
1426            ))?;
1427
1428        Ok(Self {
1429            manufacturer: t.manufacturer().ok(),
1430            chassis_type: match t.chassis_type() {
1431                Some(ct) => Some(ChassisTypeData::from(ct)),
1432                None => None,
1433            },
1434            version: t.version().ok(),
1435            serial_number: t.serial_number().ok(),
1436            asset_tag_number: t.asset_tag_number().ok(),
1437            bootup_state: match t.bootup_state() {
1438                Some(bs) => Some(ChassisStateData::from(bs)),
1439                None => None,
1440            },
1441            power_supply_state: match t.power_supply_state() {
1442                Some(pss) => Some(ChassisStateData::from(pss)),
1443                None => None,
1444            },
1445            thermal_state: match t.thermal_state() {
1446                Some(ts) => Some(ChassisStateData::from(ts)),
1447                None => None,
1448            },
1449            security_status: match t.security_status() {
1450                Some(ss) => Some(ChassisSecurityStatusData::from(ss)),
1451                None => None,
1452            },
1453            oem_defined: t.oem_defined(),
1454            height: match t.height() {
1455                Some(h) => Some(ChassisHeight::from(h)),
1456                None => None,
1457            },
1458            number_of_power_cords: match t.number_of_power_cords() {
1459                Some(npc) => Some(PowerCords::from(npc)),
1460                None => None,
1461            },
1462            contained_element_count: t.contained_element_count(),
1463            contained_element_record_length: t.contained_element_record_length(),
1464            sku_number: t.sku_number().ok(),
1465        })
1466    }
1467}
1468
1469impl ToJson for Chassis {}
1470
1471/// Information about processor
1472#[derive(Debug, Serialize, Deserialize, Clone)]
1473pub struct Processor {
1474    /// Socket reference designation
1475    pub socked_designation: Option<String>,
1476
1477    /// Processor type
1478    pub processor_type: Option<ProcessorTypeData>,
1479
1480    /// Processor family
1481    pub processor_family: Option<ProcessorFamilyData>,
1482
1483    /// Processor manufacturer
1484    pub processor_manufacturer: Option<String>,
1485
1486    /// Raw processor identification data
1487    pub processor_id: Option<[u8; 8]>,
1488
1489    /// Processor version
1490    pub processor_version: Option<String>,
1491
1492    /// Processor voltage
1493    pub voltage: Option<ProcessorVoltage>,
1494
1495    /// External clock frequency, MHz. If the value is unknown,
1496    /// the field is set to 0
1497    pub external_clock: Option<ProcessorExternalClock>,
1498
1499    /// Maximum CPU speed (in MHz) supported *by the system* for this
1500    /// processor socket
1501    pub max_speed: Option<ProcessorSpeed>,
1502
1503    /// Current speed
1504    ///
1505    /// This field identifies the processor's speed at system boot;
1506    /// the processor may support more than one speed
1507    pub current_speed: Option<ProcessorSpeed>,
1508
1509    /// Status bit field
1510    pub status: Option<ProcessorStatus>,
1511
1512    /// Processor upgrade
1513    pub processor_upgrade: Option<ProcessorUpgradeData>,
1514
1515    /// Attributes of the primary (Level 1) cache for this processor
1516    pub l1cache_handle: Option<Handle>,
1517
1518    /// Attributes of the primary (Level 2) cache for this processor
1519    pub l2cache_handle: Option<Handle>,
1520
1521    /// Attributes of the primary (Level 3) cache for this processor
1522    pub l3cache_handle: Option<Handle>,
1523
1524    /// Serial number of this processor
1525    pub serial_number: Option<String>,
1526
1527    /// Asset tag of this proc
1528    pub asset_tag: Option<String>,
1529
1530    /// Part number of this processor
1531    pub part_number: Option<String>,
1532
1533    /// Number of cores per processor socket
1534    pub core_count: Option<CoreCount>,
1535
1536    /// Number of enabled cores per processor socket
1537    pub cores_enabled: Option<CoresEnabled>,
1538
1539    /// Number of threads per processor socket
1540    pub thread_count: Option<ThreadCount>,
1541
1542    /// Function that processor supports
1543    pub processors_characteristics: Option<ProcessorCharacteristics>,
1544
1545    /// Processor family 2
1546    pub processor_family_2: Option<ProcessorFamilyData2>,
1547
1548    /// Number of cores per proc socket (if cores > 255)
1549    pub core_count_2: Option<CoreCount2>,
1550
1551    /// Number of enabled cores per proc socket (if ecores > 255)
1552    pub cores_enabled_2: Option<CoresEnabled2>,
1553
1554    /// Number of threads per proc socket (if threads > 255)
1555    pub thread_count_2: Option<ThreadCount2>,
1556
1557    /// Number of threads the BIOS has enabled and available for
1558    /// OS use
1559    pub thread_enabled: Option<ThreadEnabled>,
1560}
1561
1562impl Processor {
1563    /// Creates a new instance of `Self`
1564    ///
1565    /// It is usually not required, since an instance of this
1566    /// structure will be created using the method
1567    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
1568    /// [`DMITable::new()`].
1569    pub fn new() -> Result<Self> {
1570        let table = smbioslib::table_load_from_device()?;
1571        Self::new_from_table(&table)
1572    }
1573
1574    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
1575        let t = table
1576            .find_map(|f: smbioslib::SMBiosProcessorInformation| Some(f))
1577            .ok_or(anyhow!("Failed to get information about CPU (type 4)!"))?;
1578
1579        Ok(Self {
1580            socked_designation: t.socket_designation().ok(),
1581            processor_type: match t.processor_type() {
1582                Some(pt) => Some(ProcessorTypeData::from(pt)),
1583                None => None,
1584            },
1585            processor_family: match t.processor_family() {
1586                Some(pf) => Some(ProcessorFamilyData::from(pf)),
1587                None => None,
1588            },
1589            processor_manufacturer: t.processor_manufacturer().ok(),
1590            processor_id: match t.processor_id() {
1591                Some(p_id) => Some(*p_id),
1592                None => None,
1593            },
1594            processor_version: t.processor_version().ok(),
1595            voltage: match t.voltage() {
1596                Some(v) => Some(ProcessorVoltage::from(v)),
1597                None => None,
1598            },
1599            external_clock: match t.external_clock() {
1600                Some(ec) => Some(ProcessorExternalClock::from(ec)),
1601                None => None,
1602            },
1603            max_speed: match t.max_speed() {
1604                Some(ms) => Some(ProcessorSpeed::from(ms)),
1605                None => None,
1606            },
1607            current_speed: match t.current_speed() {
1608                Some(cs) => Some(ProcessorSpeed::from(cs)),
1609                None => None,
1610            },
1611            status: match t.status() {
1612                Some(s) => Some(ProcessorStatus::from(s)),
1613                None => None,
1614            },
1615            processor_upgrade: match t.processor_upgrade() {
1616                Some(pu) => Some(ProcessorUpgradeData::from(pu)),
1617                None => None,
1618            },
1619            l1cache_handle: Handle::from_opt(t.l1cache_handle()),
1620            l2cache_handle: Handle::from_opt(t.l2cache_handle()),
1621            l3cache_handle: Handle::from_opt(t.l3cache_handle()),
1622            serial_number: t.serial_number().ok(),
1623            asset_tag: t.asset_tag().ok(),
1624            part_number: t.part_number().ok(),
1625            core_count: match t.core_count() {
1626                Some(cc) => Some(CoreCount::from(cc)),
1627                None => None,
1628            },
1629            cores_enabled: match t.cores_enabled() {
1630                Some(ce) => Some(CoresEnabled::from(ce)),
1631                None => None,
1632            },
1633            thread_count: match t.thread_count() {
1634                Some(tc) => Some(ThreadCount::from(tc)),
1635                None => None,
1636            },
1637            processors_characteristics: match t.processor_characteristics() {
1638                Some(pc) => Some(ProcessorCharacteristics::from(pc)),
1639                None => None,
1640            },
1641            processor_family_2: match t.processor_family_2() {
1642                Some(pf2) => Some(ProcessorFamilyData2::from(pf2)),
1643                None => None,
1644            },
1645            core_count_2: match t.core_count_2() {
1646                Some(cc2) => Some(CoreCount2::from(cc2)),
1647                None => None,
1648            },
1649            cores_enabled_2: match t.cores_enabled_2() {
1650                Some(ce2) => Some(CoresEnabled2::from(ce2)),
1651                None => None,
1652            },
1653            thread_count_2: match t.thread_count_2() {
1654                Some(tc2) => Some(ThreadCount2::from(tc2)),
1655                None => None,
1656            },
1657            thread_enabled: match t.thread_enabled() {
1658                Some(te) => Some(ThreadEnabled::from(te)),
1659                None => None,
1660            },
1661        })
1662    }
1663}
1664
1665impl ToJson for Processor {}
1666
1667/// Defines which functions the processor supports
1668#[derive(Debug, Serialize, Deserialize, Clone)]
1669pub struct ProcessorCharacteristics {
1670    /// Bit 1 unknown
1671    pub unknown: bool,
1672
1673    /// 64-bit capable
1674    pub bit_64capable: bool,
1675
1676    /// Multi-core
1677    pub multi_core: bool,
1678
1679    /// Hardware thread
1680    pub hardware_thread: bool,
1681
1682    /// Execute protection
1683    pub execute_protection: bool,
1684
1685    /// Enhanced Virtualization
1686    pub enhanced_virtualization: bool,
1687
1688    /// Power/perfomance control
1689    pub power_perfomance_control: bool,
1690
1691    /// 128-bit capable
1692    pub bit_128capable: bool,
1693
1694    /// Arm64 SoC ID
1695    pub arm_64soc_id: bool,
1696}
1697
1698impl From<smbioslib::ProcessorCharacteristics> for ProcessorCharacteristics {
1699    fn from(value: smbioslib::ProcessorCharacteristics) -> Self {
1700        Self {
1701            unknown: value.unknown(),
1702            bit_64capable: value.bit_64capable(),
1703            multi_core: value.multi_core(),
1704            hardware_thread: value.hardware_thread(),
1705            execute_protection: value.execute_protection(),
1706            enhanced_virtualization: value.enhanced_virtualization(),
1707            power_perfomance_control: value.power_performance_control(),
1708            bit_128capable: value.bit_128capable(),
1709            arm_64soc_id: value.arm_64soc_id(),
1710        }
1711    }
1712}
1713impl ToJson for ProcessorCharacteristics {}
1714#[derive(Debug, Deserialize, Serialize, Clone)]
1715pub struct ProcessorTypeData {
1716    pub raw: u8,
1717    pub value: ProcessorType,
1718}
1719
1720impl From<smbioslib::ProcessorTypeData> for ProcessorTypeData {
1721    fn from(value: smbioslib::ProcessorTypeData) -> Self {
1722        Self {
1723            raw: value.raw,
1724            value: ProcessorType::from(value.value),
1725        }
1726    }
1727}
1728
1729#[derive(Debug, Deserialize, Serialize, Clone)]
1730pub enum ProcessorType {
1731    Other,
1732    Unknown,
1733    CentralProcessor,
1734    MathProcessor,
1735    DspProcessor,
1736    VideoProcessor,
1737    None,
1738}
1739
1740impl Display for ProcessorType {
1741    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1742        write!(
1743            f,
1744            "{}",
1745            match self {
1746                Self::Other => "Other",
1747                Self::Unknown => "Unknown",
1748                Self::CentralProcessor => "Central Processor",
1749                Self::MathProcessor => "Math Processor",
1750                Self::DspProcessor => "DSP Processor",
1751                Self::VideoProcessor => "Video Processor",
1752                Self::None => "A value unknown for this standard, check the raw value",
1753            }
1754        )
1755    }
1756}
1757
1758impl From<smbioslib::ProcessorType> for ProcessorType {
1759    fn from(value: smbioslib::ProcessorType) -> Self {
1760        match value {
1761            smbioslib::ProcessorType::Other => Self::Other,
1762            smbioslib::ProcessorType::Unknown => Self::Unknown,
1763            smbioslib::ProcessorType::CentralProcessor => Self::CentralProcessor,
1764            smbioslib::ProcessorType::MathProcessor => Self::MathProcessor,
1765            smbioslib::ProcessorType::DspProcessor => Self::DspProcessor,
1766            smbioslib::ProcessorType::VideoProcessor => Self::VideoProcessor,
1767            smbioslib::ProcessorType::None => Self::None,
1768        }
1769    }
1770}
1771
1772#[derive(Debug, Deserialize, Serialize, Clone)]
1773pub struct ProcessorFamilyData {
1774    pub raw: u8,
1775    pub value: ProcessorFamily,
1776}
1777
1778impl From<smbioslib::ProcessorFamilyData> for ProcessorFamilyData {
1779    fn from(value: smbioslib::ProcessorFamilyData) -> Self {
1780        Self {
1781            raw: value.raw,
1782            value: ProcessorFamily::from(value.value),
1783        }
1784    }
1785}
1786
1787#[derive(Debug, Deserialize, Serialize, Clone)]
1788pub enum ProcessorFamily {
1789    Other,
1790    Unknown,
1791    IntelPentiumProcessor,
1792    PentiumProProcessor,
1793    PentiumIIProcessor,
1794    PentiumprocessorwithMMXtechnology,
1795    IntelCeleronProcessor,
1796    PentiumIIXeonProcessor,
1797    PentiumIIIProcessor,
1798    M1Family,
1799    M2Family,
1800    IntelCeleronMProcessor,
1801    IntelPentium4HTProcessor,
1802    AMDDuronProcessorFamily,
1803    K5Family,
1804    K6Family,
1805    K62,
1806    K63,
1807    AMDAthlonProcessorFamily,
1808    AMD29000Family,
1809    K62Plus,
1810    IntelCoreDuoProcessor,
1811    IntelCoreDuomobileProcessor,
1812    IntelCoreSolomobileProcessor,
1813    IntelAtomProcessor,
1814    IntelCoreMProcessor,
1815    IntelCorem3Processor,
1816    IntelCorem5Processor,
1817    IntelCorem7Processor,
1818    AMDTurionIIUltraDualCoreMobileMProcessorFamily,
1819    AMDTurionIIDualCoreMobileMProcessorFamily,
1820    AMDAthlonIIDualCoreMProcessorFamily,
1821    AMDOpteron6100SeriesProcessor,
1822    AMDOpteron4100SeriesProcessor,
1823    AMDOpteron6200SeriesProcessor,
1824    AMDOpteron4200SeriesProcessor,
1825    AMDFXSeriesProcessor,
1826    AMDCSeriesProcessor,
1827    AMDESeriesProcessor,
1828    AMDASeriesProcessor,
1829    AMDGSeriesProcessor,
1830    AMDZSeriesProcessor,
1831    AMDRSeriesProcessor,
1832    AMDOpteron4300SeriesProcessor,
1833    AMDOpteron6300SeriesProcessor,
1834    AMDOpteron3300SeriesProcessor,
1835    AMDFireProSeriesProcessor,
1836    AMDAthlonX4QuadCoreProcessorFamily,
1837    AMDOpteronX1000SeriesProcessor,
1838    AMDOpteronX2000SeriesAPU,
1839    AMDOpteronASeriesProcessor,
1840    AMDOpteronX3000SeriesAPU,
1841    AMDZenProcessorFamily,
1842    Itaniumprocessor,
1843    AMDAthlon64ProcessorFamily,
1844    AMDOpteronProcessorFamily,
1845    AMDSempronProcessorFamily,
1846    AMDTurion64MobileTechnology,
1847    DualCoreAMDOpteronProcessorFamily,
1848    AMDAthlon64X2DualCoreProcessorFamily,
1849    AMDTurion64X2MobileTechnology,
1850    QuadCoreAMDOpteronProcessorFamily,
1851    ThirdGenerationAMDOpteronProcessorFamily,
1852    AMDPhenomFXQuadCoreProcessorFamily,
1853    AMDPhenomX4QuadCoreProcessorFamily,
1854    AMDPhenomX2DualCoreProcessorFamily,
1855    AMDAthlonX2DualCoreProcessorFamily,
1856    QuadCoreIntelXeonProcessor3200Series,
1857    DualCoreIntelXeonProcessor3000Series,
1858    QuadCoreIntelXeonProcessor5300Series,
1859    DualCoreIntelXeonProcessor5100Series,
1860    DualCoreIntelXeonProcessor5000Series,
1861    DualCoreIntelXeonProcessorLV,
1862    DualCoreIntelXeonProcessorULV,
1863    DualCoreIntelXeonProcessor7100Series,
1864    QuadCoreIntelXeonProcessor5400Series,
1865    QuadCoreIntelXeonProcessor,
1866    DualCoreIntelXeonProcessor5200Series,
1867    DualCoreIntelXeonProcessor7200Series,
1868    QuadCoreIntelXeonProcessor7300Series,
1869    QuadCoreIntelXeonProcessor7400Series,
1870    MultiCoreIntelXeonProcessor7400Series,
1871    PentiumIIIXeonProcessor,
1872    PentiumIIIProcessorwithIntelSpeedStepTechnology,
1873    Pentium4Processor,
1874    IntelXeonProcessor,
1875    IntelXeonProcessorMP,
1876    AMDAthlonXPProcessorFamily,
1877    AMDAthlonMPProcessorFamily,
1878    IntelItanium2Processor,
1879    IntelPentiumMProcessor,
1880    IntelCeleronDProcessor,
1881    IntelPentiumDProcessor,
1882    IntelPentiumProcessorExtremeEdition,
1883    IntelCoreSoloProcessor,
1884    IntelCore2DuoProcessor,
1885    IntelCore2SoloProcessor,
1886    IntelCore2ExtremeProcessor,
1887    IntelCore2QuadProcessor,
1888    IntelCore2ExtremeMobileProcessor,
1889    IntelCore2DuoMobileProcessor,
1890    IntelCore2SoloMobileProcessor,
1891    IntelCorei7Processor,
1892    DualCoreIntelCeleronProcessor,
1893    IntelCorei5processor,
1894    IntelCorei3processor,
1895    IntelCorei9processor,
1896    MultiCoreIntelXeonProcessor,
1897    DualCoreIntelXeonProcessor3xxxSeries,
1898    QuadCoreIntelXeonProcessor3xxxSeries,
1899    DualCoreIntelXeonProcessor5xxxSeries,
1900    QuadCoreIntelXeonProcessor5xxxSeries,
1901    DualCoreIntelXeonProcessor7xxxSeries,
1902    QuadCoreIntelXeonProcessor7xxxSeries,
1903    MultiCoreIntelXeonProcessor7xxxSeries,
1904    MultiCoreIntelXeonProcessor3400Series,
1905    AMDOpteron3000SeriesProcessor,
1906    AMDSempronIIProcessor,
1907    EmbeddedAMDOpteronQuadCoreProcessorFamily,
1908    AMDPhenomTripleCoreProcessorFamily,
1909    AMDTurionUltraDualCoreMobileProcessorFamily,
1910    AMDTurionDualCoreMobileProcessorFamily,
1911    AMDAthlonDualCoreProcessorFamily,
1912    AMDSempronSIProcessorFamily,
1913    AMDPhenomIIProcessorFamily,
1914    AMDAthlonIIProcessorFamily,
1915    SixCoreAMDOpteronProcessorFamily,
1916    AMDSempronMProcessorFamily,
1917    SeeProcessorFamily2,
1918    ARMv7,
1919    ARMv8,
1920    ARMv9,
1921    ARM,
1922    StrongARM,
1923    VideoProcessor,
1924    None,
1925}
1926
1927impl Display for ProcessorFamily {
1928    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1929        write!(
1930            f,
1931            "{}",
1932            match self {
1933                Self::Other => "Other",
1934                Self::Unknown => "Unknown",
1935                Self::IntelPentiumProcessor => "Intel® Pentium® processor",
1936                Self::PentiumProProcessor => "Intel® Pentium® Pro processor",
1937                Self::PentiumIIProcessor => "Pentium® II processor",
1938                Self::PentiumprocessorwithMMXtechnology =>
1939                    "Pentium® processor with MMX™ technology",
1940                Self::IntelCeleronProcessor => "Intel® Celeron® processor",
1941                Self::PentiumIIXeonProcessor => "Pentium® II Xeon™ processor",
1942                Self::PentiumIIIProcessor => "Pentium® III processor",
1943                Self::M1Family => "M1 Family",
1944                Self::M2Family => "M2 Family",
1945                Self::IntelCeleronMProcessor => "Intel® Celeron® M processor",
1946                Self::IntelPentium4HTProcessor => "Intel® Pentium® 4 HT processor",
1947                Self::AMDDuronProcessorFamily => "AMD Duron™ Processor Family",
1948                Self::K5Family => "K5 Family",
1949                Self::K6Family => "K6 Family",
1950                Self::K62 => "K6-2",
1951                Self::K63 => "K6-3",
1952                Self::AMDAthlonProcessorFamily => "AMD Athlon™ Processor Family",
1953                Self::AMD29000Family => "AMD29000 Family",
1954                Self::K62Plus => "K6-2+",
1955                Self::IntelCoreDuoProcessor => "Intel® Core™ Duo processor",
1956                Self::IntelCoreDuomobileProcessor => "Intel® Core™ Duo mobile processor",
1957                Self::IntelCoreSolomobileProcessor => "Intel® Core™ Solo mobile processor",
1958                Self::IntelAtomProcessor => "Intel® Atom™ processor",
1959                Self::IntelCoreMProcessor => "Intel® Core™ M processor",
1960                Self::IntelCorem3Processor => "Intel® Core™ m3 processor",
1961                Self::IntelCorem5Processor => "Intel® Core™ m5 processor",
1962                Self::IntelCorem7Processor => "Intel® Core™ m7 processor",
1963                Self::AMDTurionIIUltraDualCoreMobileMProcessorFamily =>
1964                    "AMD Turion™ II Ultra Dual-Core Mobile M Processor Family",
1965                Self::AMDTurionIIDualCoreMobileMProcessorFamily =>
1966                    "AMD Turion™ II Dual-Core Mobile M Processor Family",
1967                Self::AMDAthlonIIDualCoreMProcessorFamily =>
1968                    "AMD Athlon™ II Dual-Core M Processor Family",
1969                Self::AMDOpteron6100SeriesProcessor => "AMD Opteron™ 6100 Series Processor",
1970                Self::AMDOpteron4100SeriesProcessor => "AMD Opteron™ 4100 Series Processor",
1971                Self::AMDOpteron6200SeriesProcessor => "AMD Opteron™ 6200 Series Processor",
1972                Self::AMDOpteron4200SeriesProcessor => "AMD Opteron™ 4200 Series Processor",
1973                Self::AMDFXSeriesProcessor => "AMD FX™ Series Processor",
1974                Self::AMDCSeriesProcessor => "AMD C-Series Processor",
1975                Self::AMDESeriesProcessor => "AMD E-Series Processor",
1976                Self::AMDASeriesProcessor => "AMD A-Series Processor",
1977                Self::AMDGSeriesProcessor => "AMD G-Series Processor",
1978                Self::AMDZSeriesProcessor => "AMD Z-Series Processor",
1979                Self::AMDRSeriesProcessor => "AMD R-Series Processor",
1980                Self::AMDOpteron4300SeriesProcessor => "AMD Opteron™ 4300 Series Processor",
1981                Self::AMDOpteron6300SeriesProcessor => "AMD Opteron™ 6300 Series Processor",
1982                Self::AMDOpteron3300SeriesProcessor => "AMD Opteron™ 3300 Series Processor",
1983                Self::AMDFireProSeriesProcessor => "AMD FirePro™ Series Processor",
1984                Self::AMDAthlonX4QuadCoreProcessorFamily =>
1985                    "AMD Athlon(TM) X4 Quad-Core Processor Family",
1986                Self::AMDOpteronX1000SeriesProcessor => "AMD Opteron(TM) X1000 Series Processor",
1987                Self::AMDOpteronX2000SeriesAPU => "AMD Opteron(TM) X2000 Series APU",
1988                Self::AMDOpteronASeriesProcessor => "AMD Opteron(TM) A-Series Processor",
1989                Self::AMDOpteronX3000SeriesAPU => "AMD Opteron(TM) X3000 Series APU",
1990                Self::AMDZenProcessorFamily => "AMD Zen Processor Family",
1991                Self::Itaniumprocessor => "Itanium™ processor",
1992                Self::AMDAthlon64ProcessorFamily => "AMD Athlon™ 64 Processor Family",
1993                Self::AMDOpteronProcessorFamily => "AMD Opteron™ Processor Family",
1994                Self::AMDSempronProcessorFamily => "AMD Sempron™ Processor Family",
1995                Self::AMDTurion64MobileTechnology => "AMD Turion™ 64 Mobile Technology",
1996                Self::DualCoreAMDOpteronProcessorFamily =>
1997                    "Dual-Core AMD Opteron™ Processor Family",
1998                Self::AMDAthlon64X2DualCoreProcessorFamily =>
1999                    "AMD Athlon™ 64 X2 Dual-Core Processor Family",
2000                Self::AMDTurion64X2MobileTechnology => "AMD Turion™ 64 X2 Mobile Technology",
2001                Self::QuadCoreAMDOpteronProcessorFamily =>
2002                    "Quad-Core AMD Opteron™ Processor Family",
2003                Self::ThirdGenerationAMDOpteronProcessorFamily =>
2004                    "Third-Generation AMD Opteron™ Processor Family",
2005                Self::AMDPhenomFXQuadCoreProcessorFamily =>
2006                    "AMD Phenom™ FX Quad-Core Processor Family",
2007                Self::AMDPhenomX4QuadCoreProcessorFamily =>
2008                    "AMD Phenom™ X4 Quad-Core Processor Family",
2009                Self::AMDPhenomX2DualCoreProcessorFamily =>
2010                    "AMD Phenom™ X2 Dual-Core Processor Family",
2011                Self::AMDAthlonX2DualCoreProcessorFamily =>
2012                    "AMD Athlon™ X2 Dual-Core Processor Family",
2013                Self::QuadCoreIntelXeonProcessor3200Series =>
2014                    "Quad-Core Intel® Xeon® processor 3200 Series",
2015                Self::DualCoreIntelXeonProcessor3000Series =>
2016                    "Dual-Core Intel® Xeon® processor 3000 Series",
2017                Self::QuadCoreIntelXeonProcessor5300Series =>
2018                    "Quad-Core Intel® Xeon® processor 5300 Series",
2019                Self::DualCoreIntelXeonProcessor5100Series =>
2020                    "Dual-Core Intel® Xeon® processor 5100 Series",
2021                Self::DualCoreIntelXeonProcessor5000Series =>
2022                    "Dual-Core Intel® Xeon® processor 5000 Series",
2023                Self::DualCoreIntelXeonProcessorLV => "Dual-Core Intel® Xeon® processor LV",
2024                Self::DualCoreIntelXeonProcessorULV => "Dual-Core Intel® Xeon® processor ULV",
2025                Self::DualCoreIntelXeonProcessor7100Series =>
2026                    "Dual-Core Intel® Xeon® processor 7100 Series",
2027                Self::QuadCoreIntelXeonProcessor5400Series =>
2028                    "Quad-Core Intel® Xeon® processor 5400 Series",
2029                Self::QuadCoreIntelXeonProcessor => "Quad-Core Intel® Xeon® processor",
2030                Self::DualCoreIntelXeonProcessor5200Series =>
2031                    "Dual-Core Intel® Xeon® processor 5200 Series",
2032                Self::DualCoreIntelXeonProcessor7200Series =>
2033                    "Dual-Core Intel® Xeon® processor 7200 Series",
2034                Self::QuadCoreIntelXeonProcessor7300Series =>
2035                    "Quad-Core Intel® Xeon® processor 7300 Series",
2036                Self::QuadCoreIntelXeonProcessor7400Series =>
2037                    "Quad-Core Intel® Xeon® processor 7400 Series",
2038                Self::MultiCoreIntelXeonProcessor7400Series =>
2039                    "Multi-Core Intel® Xeon® processor 7400 Series",
2040                Self::PentiumIIIXeonProcessor => "Pentium® III Xeon™ processor",
2041                Self::PentiumIIIProcessorwithIntelSpeedStepTechnology =>
2042                    "Pentium® III Processor with Intel® SpeedStep™ Technology",
2043                Self::Pentium4Processor => "Pentium® 4 Processor",
2044                Self::IntelXeonProcessor => "Intel® Xeon® processor",
2045                Self::IntelXeonProcessorMP => "Intel® Xeon™ processor MP",
2046                Self::AMDAthlonXPProcessorFamily => "AMD Athlon™ XP Processor Family",
2047                Self::AMDAthlonMPProcessorFamily => "AMD Athlon™ MP Processor Family",
2048                Self::IntelItanium2Processor => "Intel® Itanium® 2 processor",
2049                Self::IntelPentiumMProcessor => "Intel® Pentium® M processor",
2050                Self::IntelCeleronDProcessor => "Intel® Celeron® D processor",
2051                Self::IntelPentiumDProcessor => "Intel® Pentium® D processor",
2052                Self::IntelPentiumProcessorExtremeEdition =>
2053                    "Intel® Pentium® Processor Extreme Edition",
2054                Self::IntelCoreSoloProcessor => "Intel® Core™ Solo Processor",
2055                Self::IntelCore2DuoProcessor => "Intel® Core™ 2 Duo Processor",
2056                Self::IntelCore2SoloProcessor => "Intel® Core™ 2 Solo processor",
2057                Self::IntelCore2ExtremeProcessor => "Intel® Core™ 2 Extreme processor",
2058                Self::IntelCore2QuadProcessor => "Intel® Core™ 2 Quad processor",
2059                Self::IntelCore2ExtremeMobileProcessor => "Intel® Core™ 2 Extreme mobile processor",
2060                Self::IntelCore2DuoMobileProcessor => "Intel® Core™ 2 Duo mobile processor",
2061                Self::IntelCore2SoloMobileProcessor => "Intel® Core™ 2 Solo mobile processor",
2062                Self::IntelCorei7Processor => "Intel® Core™ i7 processor",
2063                Self::DualCoreIntelCeleronProcessor => "Dual-Core Intel® Celeron® processor",
2064                Self::IntelCorei5processor => "Intel® Core™ i5 processor",
2065                Self::IntelCorei3processor => "Intel® Core™ i3 processor",
2066                Self::IntelCorei9processor => "Intel® Core™ i9 processor",
2067                Self::MultiCoreIntelXeonProcessor => "Multi-Core Intel® Xeon® processor",
2068                Self::DualCoreIntelXeonProcessor3xxxSeries =>
2069                    "Dual-Core Intel® Xeon® processor 3xxx Series",
2070                Self::QuadCoreIntelXeonProcessor3xxxSeries =>
2071                    "Quad-Core Intel® Xeon® processor 3xxx Series",
2072                Self::DualCoreIntelXeonProcessor5xxxSeries =>
2073                    "Dual-Core Intel® Xeon® processor 5xxx Series",
2074                Self::QuadCoreIntelXeonProcessor5xxxSeries =>
2075                    "Quad-Core Intel® Xeon® processor 5xxx Series",
2076                Self::DualCoreIntelXeonProcessor7xxxSeries =>
2077                    "Dual-Core Intel® Xeon® processor 7xxx Series",
2078                Self::QuadCoreIntelXeonProcessor7xxxSeries =>
2079                    "Quad-Core Intel® Xeon® processor 7xxx Series",
2080                Self::MultiCoreIntelXeonProcessor7xxxSeries =>
2081                    "Multi-Core Intel® Xeon® processor 7xxx Series",
2082                Self::MultiCoreIntelXeonProcessor3400Series =>
2083                    "Multi-Core Intel® Xeon® processor 3400 Series",
2084                Self::AMDOpteron3000SeriesProcessor => "AMD Opteron™ 3000 Series Processor",
2085                Self::AMDSempronIIProcessor => "AMD Sempron™ II Processor",
2086                Self::EmbeddedAMDOpteronQuadCoreProcessorFamily =>
2087                    "Embedded AMD Opteron™ Quad-Core Processor Family",
2088                Self::AMDPhenomTripleCoreProcessorFamily =>
2089                    "AMD Phenom™ Triple-Core Processor Family",
2090                Self::AMDTurionUltraDualCoreMobileProcessorFamily =>
2091                    "AMD Turion™ Ultra Dual-Core Mobile Processor Family",
2092                Self::AMDTurionDualCoreMobileProcessorFamily =>
2093                    "AMD Turion™ Dual-Core Mobile Processor Family",
2094                Self::AMDAthlonDualCoreProcessorFamily => "AMD Athlon™ Dual-Core Processor Family",
2095                Self::AMDSempronSIProcessorFamily => "AMD Sempron™ SI Processor Family",
2096                Self::AMDPhenomIIProcessorFamily => "AMD Phenom™ II Processor Family",
2097                Self::AMDAthlonIIProcessorFamily => "AMD Athlon™ II Processor Family",
2098                Self::SixCoreAMDOpteronProcessorFamily => "Six-Core AMD Opteron™ Processor Family",
2099                Self::AMDSempronMProcessorFamily => "AMD Sempron™ M Processor Family",
2100                Self::SeeProcessorFamily2 => "See the next processor family field",
2101                Self::ARMv7 => "ARMv7",
2102                Self::ARMv8 => "ARMv8",
2103                Self::ARMv9 => "ARMv9",
2104                Self::ARM => "ARM",
2105                Self::StrongARM => "StrongARM",
2106                Self::VideoProcessor => "Video Processor",
2107                Self::None => "A value unknown to this standard, check the raw value",
2108            }
2109        )
2110    }
2111}
2112
2113impl From<smbioslib::ProcessorFamily> for ProcessorFamily {
2114    fn from(value: smbioslib::ProcessorFamily) -> Self {
2115        match value {
2116            smbioslib::ProcessorFamily::Other => Self::Other,
2117            smbioslib::ProcessorFamily::Unknown => Self::Unknown,
2118            smbioslib::ProcessorFamily::IntelPentiumProcessor => Self::IntelPentiumProcessor,
2119            smbioslib::ProcessorFamily::PentiumProProcessor => Self::PentiumProProcessor,
2120            smbioslib::ProcessorFamily::PentiumIIProcessor => Self::PentiumIIProcessor,
2121            smbioslib::ProcessorFamily::PentiumprocessorwithMMXtechnology => {
2122                Self::PentiumprocessorwithMMXtechnology
2123            }
2124            smbioslib::ProcessorFamily::IntelCeleronProcessor => Self::IntelCeleronProcessor,
2125            smbioslib::ProcessorFamily::PentiumIIXeonProcessor => Self::PentiumIIXeonProcessor,
2126            smbioslib::ProcessorFamily::PentiumIIIProcessor => Self::PentiumIIIProcessor,
2127            smbioslib::ProcessorFamily::M1Family => Self::M1Family,
2128            smbioslib::ProcessorFamily::M2Family => Self::M2Family,
2129            smbioslib::ProcessorFamily::IntelCeleronMProcessor => Self::IntelCeleronMProcessor,
2130            smbioslib::ProcessorFamily::IntelPentium4HTProcessor => Self::IntelPentium4HTProcessor,
2131            smbioslib::ProcessorFamily::AMDDuronProcessorFamily => Self::AMDDuronProcessorFamily,
2132            smbioslib::ProcessorFamily::K5Family => Self::K5Family,
2133            smbioslib::ProcessorFamily::K6Family => Self::K6Family,
2134            smbioslib::ProcessorFamily::K62 => Self::K62,
2135            smbioslib::ProcessorFamily::K63 => Self::K63,
2136            smbioslib::ProcessorFamily::AMDAthlonProcessorFamily => Self::AMDAthlonProcessorFamily,
2137            smbioslib::ProcessorFamily::AMD29000Family => Self::AMD29000Family,
2138            smbioslib::ProcessorFamily::K62Plus => Self::K62Plus,
2139            smbioslib::ProcessorFamily::IntelCoreDuoProcessor => Self::IntelCoreDuoProcessor,
2140            smbioslib::ProcessorFamily::IntelCoreDuomobileProcessor => {
2141                Self::IntelCoreDuomobileProcessor
2142            }
2143            smbioslib::ProcessorFamily::IntelCoreSolomobileProcessor => {
2144                Self::IntelCoreSolomobileProcessor
2145            }
2146            smbioslib::ProcessorFamily::IntelAtomProcessor => Self::IntelAtomProcessor,
2147            smbioslib::ProcessorFamily::IntelCoreMProcessor => Self::IntelCoreMProcessor,
2148            smbioslib::ProcessorFamily::IntelCorem3Processor => Self::IntelCorem3Processor,
2149            smbioslib::ProcessorFamily::IntelCorem5Processor => Self::IntelCorem5Processor,
2150            smbioslib::ProcessorFamily::IntelCorem7Processor => Self::IntelCorem7Processor,
2151            smbioslib::ProcessorFamily::AMDTurionIIUltraDualCoreMobileMProcessorFamily => {
2152                Self::AMDTurionIIUltraDualCoreMobileMProcessorFamily
2153            }
2154            smbioslib::ProcessorFamily::AMDTurionIIDualCoreMobileMProcessorFamily => {
2155                Self::AMDTurionIIDualCoreMobileMProcessorFamily
2156            }
2157            smbioslib::ProcessorFamily::AMDAthlonIIDualCoreMProcessorFamily => {
2158                Self::AMDAthlonIIDualCoreMProcessorFamily
2159            }
2160            smbioslib::ProcessorFamily::AMDOpteron6100SeriesProcessor => {
2161                Self::AMDOpteron6100SeriesProcessor
2162            }
2163            smbioslib::ProcessorFamily::AMDOpteron4100SeriesProcessor => {
2164                Self::AMDOpteron4100SeriesProcessor
2165            }
2166            smbioslib::ProcessorFamily::AMDOpteron6200SeriesProcessor => {
2167                Self::AMDOpteron6200SeriesProcessor
2168            }
2169            smbioslib::ProcessorFamily::AMDOpteron4200SeriesProcessor => {
2170                Self::AMDOpteron4200SeriesProcessor
2171            }
2172            smbioslib::ProcessorFamily::AMDFXSeriesProcessor => Self::AMDFXSeriesProcessor,
2173            smbioslib::ProcessorFamily::AMDCSeriesProcessor => Self::AMDCSeriesProcessor,
2174            smbioslib::ProcessorFamily::AMDESeriesProcessor => Self::AMDESeriesProcessor,
2175            smbioslib::ProcessorFamily::AMDASeriesProcessor => Self::AMDASeriesProcessor,
2176            smbioslib::ProcessorFamily::AMDGSeriesProcessor => Self::AMDGSeriesProcessor,
2177            smbioslib::ProcessorFamily::AMDZSeriesProcessor => Self::AMDZSeriesProcessor,
2178            smbioslib::ProcessorFamily::AMDRSeriesProcessor => Self::AMDRSeriesProcessor,
2179            smbioslib::ProcessorFamily::AMDOpteron4300SeriesProcessor => {
2180                Self::AMDOpteron4300SeriesProcessor
2181            }
2182            smbioslib::ProcessorFamily::AMDOpteron6300SeriesProcessor => {
2183                Self::AMDOpteron6300SeriesProcessor
2184            }
2185            smbioslib::ProcessorFamily::AMDOpteron3300SeriesProcessor => {
2186                Self::AMDOpteron3300SeriesProcessor
2187            }
2188            smbioslib::ProcessorFamily::AMDFireProSeriesProcessor => {
2189                Self::AMDFireProSeriesProcessor
2190            }
2191            smbioslib::ProcessorFamily::AMDAthlonX4QuadCoreProcessorFamily => {
2192                Self::AMDAthlonX4QuadCoreProcessorFamily
2193            }
2194            smbioslib::ProcessorFamily::AMDOpteronX1000SeriesProcessor => {
2195                Self::AMDOpteronX1000SeriesProcessor
2196            }
2197            smbioslib::ProcessorFamily::AMDOpteronX2000SeriesAPU => Self::AMDOpteronX2000SeriesAPU,
2198            smbioslib::ProcessorFamily::AMDOpteronASeriesProcessor => {
2199                Self::AMDOpteronASeriesProcessor
2200            }
2201            smbioslib::ProcessorFamily::AMDOpteronX3000SeriesAPU => Self::AMDOpteronX3000SeriesAPU,
2202            smbioslib::ProcessorFamily::AMDZenProcessorFamily => Self::AMDZenProcessorFamily,
2203            smbioslib::ProcessorFamily::Itaniumprocessor => Self::Itaniumprocessor,
2204            smbioslib::ProcessorFamily::AMDAthlon64ProcessorFamily => {
2205                Self::AMDAthlon64ProcessorFamily
2206            }
2207            smbioslib::ProcessorFamily::AMDOpteronProcessorFamily => {
2208                Self::AMDOpteronProcessorFamily
2209            }
2210            smbioslib::ProcessorFamily::AMDSempronProcessorFamily => {
2211                Self::AMDSempronProcessorFamily
2212            }
2213            smbioslib::ProcessorFamily::AMDTurion64MobileTechnology => {
2214                Self::AMDTurion64MobileTechnology
2215            }
2216            smbioslib::ProcessorFamily::DualCoreAMDOpteronProcessorFamily => {
2217                Self::DualCoreAMDOpteronProcessorFamily
2218            }
2219            smbioslib::ProcessorFamily::AMDAthlon64X2DualCoreProcessorFamily => {
2220                Self::AMDAthlon64X2DualCoreProcessorFamily
2221            }
2222            smbioslib::ProcessorFamily::AMDTurion64X2MobileTechnology => {
2223                Self::AMDTurion64X2MobileTechnology
2224            }
2225            smbioslib::ProcessorFamily::QuadCoreAMDOpteronProcessorFamily => {
2226                Self::QuadCoreAMDOpteronProcessorFamily
2227            }
2228            smbioslib::ProcessorFamily::ThirdGenerationAMDOpteronProcessorFamily => {
2229                Self::ThirdGenerationAMDOpteronProcessorFamily
2230            }
2231            smbioslib::ProcessorFamily::AMDPhenomFXQuadCoreProcessorFamily => {
2232                Self::AMDPhenomFXQuadCoreProcessorFamily
2233            }
2234            smbioslib::ProcessorFamily::AMDPhenomX4QuadCoreProcessorFamily => {
2235                Self::AMDPhenomX4QuadCoreProcessorFamily
2236            }
2237            smbioslib::ProcessorFamily::AMDPhenomX2DualCoreProcessorFamily => {
2238                Self::AMDPhenomX2DualCoreProcessorFamily
2239            }
2240            smbioslib::ProcessorFamily::AMDAthlonX2DualCoreProcessorFamily => {
2241                Self::AMDAthlonX2DualCoreProcessorFamily
2242            }
2243            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor3200Series => {
2244                Self::QuadCoreIntelXeonProcessor3200Series
2245            }
2246            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor3000Series => {
2247                Self::DualCoreIntelXeonProcessor3000Series
2248            }
2249            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor5300Series => {
2250                Self::QuadCoreIntelXeonProcessor5300Series
2251            }
2252            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor5100Series => {
2253                Self::DualCoreIntelXeonProcessor5100Series
2254            }
2255            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor5000Series => {
2256                Self::DualCoreIntelXeonProcessor5000Series
2257            }
2258            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessorLV => {
2259                Self::DualCoreIntelXeonProcessorLV
2260            }
2261            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessorULV => {
2262                Self::DualCoreIntelXeonProcessorULV
2263            }
2264            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor7100Series => {
2265                Self::DualCoreIntelXeonProcessor7100Series
2266            }
2267            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor5400Series => {
2268                Self::QuadCoreIntelXeonProcessor5400Series
2269            }
2270            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor => {
2271                Self::QuadCoreIntelXeonProcessor
2272            }
2273            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor5200Series => {
2274                Self::DualCoreIntelXeonProcessor5200Series
2275            }
2276            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor7200Series => {
2277                Self::DualCoreIntelXeonProcessor7200Series
2278            }
2279            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor7300Series => {
2280                Self::QuadCoreIntelXeonProcessor7300Series
2281            }
2282            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor7400Series => {
2283                Self::QuadCoreIntelXeonProcessor7400Series
2284            }
2285            smbioslib::ProcessorFamily::MultiCoreIntelXeonProcessor7400Series => {
2286                Self::MultiCoreIntelXeonProcessor7400Series
2287            }
2288            smbioslib::ProcessorFamily::PentiumIIIXeonProcessor => Self::PentiumIIIXeonProcessor,
2289            smbioslib::ProcessorFamily::PentiumIIIProcessorwithIntelSpeedStepTechnology => {
2290                Self::PentiumIIIProcessorwithIntelSpeedStepTechnology
2291            }
2292            smbioslib::ProcessorFamily::Pentium4Processor => Self::Pentium4Processor,
2293            smbioslib::ProcessorFamily::IntelXeonProcessor => Self::IntelXeonProcessor,
2294            smbioslib::ProcessorFamily::IntelXeonProcessorMP => Self::IntelXeonProcessorMP,
2295            smbioslib::ProcessorFamily::AMDAthlonXPProcessorFamily => {
2296                Self::AMDAthlonXPProcessorFamily
2297            }
2298            smbioslib::ProcessorFamily::AMDAthlonMPProcessorFamily => {
2299                Self::AMDAthlonMPProcessorFamily
2300            }
2301            smbioslib::ProcessorFamily::IntelItanium2Processor => Self::IntelItanium2Processor,
2302            smbioslib::ProcessorFamily::IntelPentiumMProcessor => Self::IntelPentiumMProcessor,
2303            smbioslib::ProcessorFamily::IntelCeleronDProcessor => Self::IntelCeleronDProcessor,
2304            smbioslib::ProcessorFamily::IntelPentiumDProcessor => Self::IntelPentiumDProcessor,
2305            smbioslib::ProcessorFamily::IntelPentiumProcessorExtremeEdition => {
2306                Self::IntelPentiumProcessorExtremeEdition
2307            }
2308            smbioslib::ProcessorFamily::IntelCoreSoloProcessor => Self::IntelCoreSoloProcessor,
2309            smbioslib::ProcessorFamily::IntelCore2DuoProcessor => Self::IntelCore2DuoProcessor,
2310            smbioslib::ProcessorFamily::IntelCore2SoloProcessor => Self::IntelCore2SoloProcessor,
2311            smbioslib::ProcessorFamily::IntelCore2ExtremeProcessor => {
2312                Self::IntelCore2ExtremeProcessor
2313            }
2314            smbioslib::ProcessorFamily::IntelCore2QuadProcessor => Self::IntelCore2QuadProcessor,
2315            smbioslib::ProcessorFamily::IntelCore2ExtremeMobileProcessor => {
2316                Self::IntelCore2ExtremeMobileProcessor
2317            }
2318            smbioslib::ProcessorFamily::IntelCore2DuoMobileProcessor => {
2319                Self::IntelCore2DuoMobileProcessor
2320            }
2321            smbioslib::ProcessorFamily::IntelCore2SoloMobileProcessor => {
2322                Self::IntelCore2SoloMobileProcessor
2323            }
2324            smbioslib::ProcessorFamily::IntelCorei7Processor => Self::IntelCorei7Processor,
2325            smbioslib::ProcessorFamily::DualCoreIntelCeleronProcessor => {
2326                Self::DualCoreIntelCeleronProcessor
2327            }
2328            smbioslib::ProcessorFamily::IntelCorei5processor => Self::IntelCorei5processor,
2329            smbioslib::ProcessorFamily::IntelCorei3processor => Self::IntelCorei3processor,
2330            smbioslib::ProcessorFamily::IntelCorei9processor => Self::IntelCorei9processor,
2331            smbioslib::ProcessorFamily::MultiCoreIntelXeonProcessor => {
2332                Self::MultiCoreIntelXeonProcessor
2333            }
2334            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor3xxxSeries => {
2335                Self::DualCoreIntelXeonProcessor3xxxSeries
2336            }
2337            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor3xxxSeries => {
2338                Self::QuadCoreIntelXeonProcessor3xxxSeries
2339            }
2340            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor5xxxSeries => {
2341                Self::DualCoreIntelXeonProcessor5xxxSeries
2342            }
2343            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor5xxxSeries => {
2344                Self::QuadCoreIntelXeonProcessor5xxxSeries
2345            }
2346            smbioslib::ProcessorFamily::DualCoreIntelXeonProcessor7xxxSeries => {
2347                Self::DualCoreIntelXeonProcessor7xxxSeries
2348            }
2349            smbioslib::ProcessorFamily::QuadCoreIntelXeonProcessor7xxxSeries => {
2350                Self::QuadCoreIntelXeonProcessor7xxxSeries
2351            }
2352            smbioslib::ProcessorFamily::MultiCoreIntelXeonProcessor7xxxSeries => {
2353                Self::MultiCoreIntelXeonProcessor7xxxSeries
2354            }
2355            smbioslib::ProcessorFamily::MultiCoreIntelXeonProcessor3400Series => {
2356                Self::MultiCoreIntelXeonProcessor3400Series
2357            }
2358            smbioslib::ProcessorFamily::AMDOpteron3000SeriesProcessor => {
2359                Self::AMDOpteron3000SeriesProcessor
2360            }
2361            smbioslib::ProcessorFamily::AMDSempronIIProcessor => Self::AMDSempronIIProcessor,
2362            smbioslib::ProcessorFamily::EmbeddedAMDOpteronQuadCoreProcessorFamily => {
2363                Self::EmbeddedAMDOpteronQuadCoreProcessorFamily
2364            }
2365            smbioslib::ProcessorFamily::AMDPhenomTripleCoreProcessorFamily => {
2366                Self::AMDPhenomTripleCoreProcessorFamily
2367            }
2368            smbioslib::ProcessorFamily::AMDTurionUltraDualCoreMobileProcessorFamily => {
2369                Self::AMDTurionUltraDualCoreMobileProcessorFamily
2370            }
2371            smbioslib::ProcessorFamily::AMDTurionDualCoreMobileProcessorFamily => {
2372                Self::AMDTurionDualCoreMobileProcessorFamily
2373            }
2374            smbioslib::ProcessorFamily::AMDAthlonDualCoreProcessorFamily => {
2375                Self::AMDAthlonDualCoreProcessorFamily
2376            }
2377            smbioslib::ProcessorFamily::AMDSempronSIProcessorFamily => {
2378                Self::AMDSempronSIProcessorFamily
2379            }
2380            smbioslib::ProcessorFamily::AMDPhenomIIProcessorFamily => {
2381                Self::AMDPhenomIIProcessorFamily
2382            }
2383            smbioslib::ProcessorFamily::AMDAthlonIIProcessorFamily => {
2384                Self::AMDAthlonIIProcessorFamily
2385            }
2386            smbioslib::ProcessorFamily::SixCoreAMDOpteronProcessorFamily => {
2387                Self::SixCoreAMDOpteronProcessorFamily
2388            }
2389            smbioslib::ProcessorFamily::AMDSempronMProcessorFamily => {
2390                Self::AMDSempronMProcessorFamily
2391            }
2392            smbioslib::ProcessorFamily::SeeProcessorFamily2 => Self::SeeProcessorFamily2,
2393            smbioslib::ProcessorFamily::ARMv7 => Self::ARMv7,
2394            smbioslib::ProcessorFamily::ARMv8 => Self::ARMv8,
2395            smbioslib::ProcessorFamily::ARMv9 => Self::ARMv9,
2396            smbioslib::ProcessorFamily::ARM => Self::ARM,
2397            smbioslib::ProcessorFamily::StrongARM => Self::StrongARM,
2398            smbioslib::ProcessorFamily::VideoProcessor => Self::VideoProcessor,
2399            smbioslib::ProcessorFamily::None => Self::None,
2400            _ => Self::Unknown,
2401        }
2402    }
2403}
2404
2405#[derive(Debug, Deserialize, Serialize, Clone)]
2406pub struct ProcessorFamilyData2 {
2407    pub raw: u16,
2408    pub value: ProcessorFamily,
2409}
2410
2411impl From<smbioslib::ProcessorFamilyData2> for ProcessorFamilyData2 {
2412    fn from(value: smbioslib::ProcessorFamilyData2) -> Self {
2413        Self {
2414            raw: value.raw,
2415            value: ProcessorFamily::from(value.value),
2416        }
2417    }
2418}
2419
2420#[derive(Debug, Deserialize, Serialize, Clone)]
2421pub enum ProcessorVoltage {
2422    CurrentVolts(f32),
2423    SupportedVolts(ProcessorSupportedVoltages),
2424}
2425
2426impl From<smbioslib::ProcessorVoltage> for ProcessorVoltage {
2427    fn from(value: smbioslib::ProcessorVoltage) -> Self {
2428        match value {
2429            smbioslib::ProcessorVoltage::CurrentVolts(volts) => Self::CurrentVolts(volts),
2430            smbioslib::ProcessorVoltage::SupportedVolts(volts) => {
2431                Self::SupportedVolts(ProcessorSupportedVoltages::from(volts))
2432            }
2433        }
2434    }
2435}
2436
2437#[derive(Debug, Deserialize, Serialize, Clone)]
2438pub struct ProcessorSupportedVoltages {
2439    pub volts_5_0: bool,
2440    pub volts_3_3: bool,
2441    pub volts_2_9: bool,
2442    pub voltages: Vec<f32>,
2443}
2444
2445impl From<smbioslib::ProcessorSupportedVoltages> for ProcessorSupportedVoltages {
2446    fn from(value: smbioslib::ProcessorSupportedVoltages) -> Self {
2447        Self {
2448            volts_5_0: value.volts_5_0(),
2449            volts_3_3: value.volts_3_3(),
2450            volts_2_9: value.volts_2_9(),
2451            voltages: value.voltages(),
2452        }
2453    }
2454}
2455
2456#[derive(Debug, Deserialize, Serialize, Clone)]
2457pub enum ProcessorExternalClock {
2458    Unknown,
2459    MHz(u16),
2460}
2461
2462impl Display for ProcessorExternalClock {
2463    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2464        match self {
2465            Self::Unknown => write!(f, "Unknown"),
2466            Self::MHz(mhz) => write!(f, "{} MHz", mhz),
2467        }
2468    }
2469}
2470
2471impl From<smbioslib::ProcessorExternalClock> for ProcessorExternalClock {
2472    fn from(value: smbioslib::ProcessorExternalClock) -> Self {
2473        match value {
2474            smbioslib::ProcessorExternalClock::Unknown => Self::Unknown,
2475            smbioslib::ProcessorExternalClock::MHz(mhz) => Self::MHz(mhz),
2476        }
2477    }
2478}
2479
2480#[derive(Debug, Deserialize, Serialize, Clone)]
2481pub enum ProcessorSpeed {
2482    Unknown,
2483    MHz(u16),
2484}
2485
2486impl Display for ProcessorSpeed {
2487    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2488        match self {
2489            Self::Unknown => write!(f, "Unknown"),
2490            Self::MHz(mhz) => write!(f, "{} MHz", mhz),
2491        }
2492    }
2493}
2494
2495impl From<smbioslib::ProcessorSpeed> for ProcessorSpeed {
2496    fn from(value: smbioslib::ProcessorSpeed) -> Self {
2497        match value {
2498            smbioslib::ProcessorSpeed::Unknown => Self::Unknown,
2499            smbioslib::ProcessorSpeed::MHz(mhz) => Self::MHz(mhz),
2500        }
2501    }
2502}
2503
2504/// Processor Socket and CPU Status
2505#[derive(Debug, Deserialize, Serialize, Clone)]
2506pub struct ProcessorStatus {
2507    pub raw: u8,
2508
2509    /// CPU Socket Populated
2510    pub socket_populated: bool,
2511
2512    /// CPU Status
2513    pub cpu_status: CpuStatus,
2514}
2515
2516impl From<smbioslib::ProcessorStatus> for ProcessorStatus {
2517    fn from(value: smbioslib::ProcessorStatus) -> Self {
2518        Self {
2519            raw: value.raw,
2520            socket_populated: value.socket_populated(),
2521            cpu_status: CpuStatus::from(value.cpu_status()),
2522        }
2523    }
2524}
2525
2526#[derive(Debug, Deserialize, Serialize, Clone)]
2527pub enum CpuStatus {
2528    Unknown,
2529    Enabled,
2530    UserDisabled,
2531    BiosDisabled,
2532    Idle,
2533    Other,
2534    None,
2535}
2536
2537impl Display for CpuStatus {
2538    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2539        write!(
2540            f,
2541            "{}",
2542            match self {
2543                Self::Unknown => "Unknown",
2544                Self::Enabled => "CPU Enabled",
2545                Self::UserDisabled => "CPU disabled by user through BIOS Setup",
2546                Self::BiosDisabled => "CPU disabled by BIOS (POST Error)",
2547                Self::Idle => "CPU is Idle, waiting to be enabled",
2548                Self::Other => "Other",
2549                Self::None => "A value unknown to this standard, check the raw value",
2550            }
2551        )
2552    }
2553}
2554
2555impl From<smbioslib::CpuStatus> for CpuStatus {
2556    fn from(value: smbioslib::CpuStatus) -> Self {
2557        match value {
2558            smbioslib::CpuStatus::Unknown => Self::Unknown,
2559            smbioslib::CpuStatus::Enabled => Self::Enabled,
2560            smbioslib::CpuStatus::UserDisabled => Self::UserDisabled,
2561            smbioslib::CpuStatus::BiosDisabled => Self::BiosDisabled,
2562            smbioslib::CpuStatus::Idle => Self::Idle,
2563            smbioslib::CpuStatus::Other => Self::Other,
2564            smbioslib::CpuStatus::None => Self::None,
2565        }
2566    }
2567}
2568
2569#[derive(Debug, Deserialize, Serialize, Clone)]
2570pub struct ProcessorUpgradeData {
2571    pub raw: u8,
2572    pub value: ProcessorUpgrade,
2573}
2574
2575impl From<smbioslib::ProcessorUpgradeData> for ProcessorUpgradeData {
2576    fn from(value: smbioslib::ProcessorUpgradeData) -> Self {
2577        Self {
2578            raw: value.raw,
2579            value: ProcessorUpgrade::from(value.value),
2580        }
2581    }
2582}
2583
2584#[derive(Debug, Deserialize, Serialize, Clone)]
2585pub enum ProcessorUpgrade {
2586    Other,
2587    Unknown,
2588    DaughterBoard,
2589    ZIFSocket,
2590    ReplaceablePiggyBack,
2591    NoUpgrade,
2592    LIFSocket,
2593    Slot1,
2594    Slot2,
2595    PinSocket370,
2596    SlotA,
2597    SlotM,
2598    Socket423,
2599    SocketASocket462,
2600    Socket478,
2601    Socket754,
2602    Socket940,
2603    Socket939,
2604    SocketmPGA604,
2605    SocketLGA771,
2606    SocketLGA775,
2607    SocketS1,
2608    SocketAM2,
2609    SocketF1207,
2610    SocketLGA1366,
2611    SocketG34,
2612    SocketAM3,
2613    SocketC32,
2614    SocketLGA1156,
2615    SocketLGA1567,
2616    SocketPGA988A,
2617    SocketBGA1288,
2618    SocketrPGA988B,
2619    SocketBGA1023,
2620    SocketBGA1224,
2621    SocketLGA1155,
2622    SocketLGA1356,
2623    SocketLGA2011,
2624    SocketFS1,
2625    SocketFS2,
2626    SocketFM1,
2627    SocketFM2,
2628    SocketLGA2011_3,
2629    SocketLGA1356_3,
2630    SocketLGA1150,
2631    SocketBGA1168,
2632    SocketBGA1234,
2633    SocketBGA1364,
2634    SocketAM4,
2635    SocketLGA1151,
2636    SocketBGA1356,
2637    SocketBGA1440,
2638    SocketBGA1515,
2639    SocketLGA3647_1,
2640    SocketSP3,
2641    SocketSP3r23,
2642    SocketLGA2066,
2643    SocketBGA1392,
2644    SocketBGA1510,
2645    SocketBGA1528,
2646    SocketLGA4189,
2647    SocketLGA1200,
2648    SocketLGA4677,
2649    SocketLGA1700,
2650    SocketBGA1744,
2651    SocketBGA1781,
2652    SocketBGA1211,
2653    SocketBGA2422,
2654    SocketLGA1211,
2655    SocketLGA2422,
2656    SocketLGA5773,
2657    SocketBGA5773,
2658    SocketAM5,
2659    SocketSP5,
2660    SocketSP6,
2661    SocketBGA883,
2662    SocketBGA1190,
2663    SocketBGA4129,
2664    SocketLGA4710,
2665    SocketLGA7529,
2666    SocketBGA1964,
2667    SocketBGA1792,
2668    SocketBGA2049,
2669    SocketBGA2551,
2670    SocketBGA2114,
2671    SocketBGA2833,
2672    SocketLGA1851,
2673    SeeSocketType,
2674    None,
2675}
2676
2677impl Display for ProcessorUpgrade {
2678    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2679        write!(
2680            f,
2681            "{}",
2682            match self {
2683                Self::Other => "Other",
2684                Self::Unknown => "Unknown",
2685                Self::DaughterBoard => "Daughter Board",
2686                Self::ZIFSocket => "ZIF Socket",
2687                Self::ReplaceablePiggyBack => "Replaceable Piggy Back",
2688                Self::NoUpgrade => "No Upgrade",
2689                Self::LIFSocket => "LIF Socket",
2690                Self::Slot1 => "Slot #1",
2691                Self::Slot2 => "Slot #2",
2692                Self::SlotA => "Slot A",
2693                Self::SlotM => "Slot M",
2694                Self::PinSocket370 => "370-pin socket",
2695                Self::Socket423 => "Socket 423",
2696                Self::SocketASocket462 => "Socket A (Socket 462)",
2697                Self::Socket478 => "Socket 478",
2698                Self::Socket754 => "Socket 754",
2699                Self::Socket940 => "Socket 940",
2700                Self::Socket939 => "Socket 939",
2701                Self::SocketmPGA604 => "Socket mPGA604",
2702                Self::SocketLGA771 => "Socket LGA771",
2703                Self::SocketLGA775 => "Socket LGA775",
2704                Self::SocketS1 => "Socket S1",
2705                Self::SocketAM2 => "Socket AM2",
2706                Self::SocketF1207 => "Socket F (1207)",
2707                Self::SocketLGA1366 => "Socket LGA1366",
2708                Self::SocketG34 => "Socket G34",
2709                Self::SocketAM3 => "Socket AM3",
2710                Self::SocketC32 => "Socket C32",
2711                Self::SocketLGA1156 => "Socket LGA1156",
2712                Self::SocketLGA1567 => "Socket LGA1567",
2713                Self::SocketPGA988A => "Socket PGA988A",
2714                Self::SocketBGA1288 => "Socket BGA1288",
2715                Self::SocketrPGA988B => "Socket rPGA988B",
2716                Self::SocketBGA1023 => "Socket BGA1023",
2717                Self::SocketBGA1224 => "Socket BGA1224",
2718                Self::SocketLGA1155 => "Socket LGA1155",
2719                Self::SocketLGA1356 => "Socket LGA1356",
2720                Self::SocketLGA2011 => "Socket LGA2011",
2721                Self::SocketFS1 => "Socket FS1",
2722                Self::SocketFS2 => "Socket FS2",
2723                Self::SocketFM1 => "Socket FM1",
2724                Self::SocketFM2 => "Socket FM2",
2725                Self::SocketLGA2011_3 => "Socket LGA2011-3",
2726                Self::SocketLGA1356_3 => "Socket LGA1356-3",
2727                Self::SocketLGA1150 => "Socket LGA1150",
2728                Self::SocketBGA1168 => "Socket BGA1168",
2729                Self::SocketBGA1234 => "Socket BGA1234",
2730                Self::SocketBGA1364 => "Socket BGA1364",
2731                Self::SocketAM4 => "Socket AM4",
2732                Self::SocketLGA1151 => "Socket LGA1151",
2733                Self::SocketBGA1356 => "Socket BGA1356",
2734                Self::SocketBGA1440 => "Socket BGA1440",
2735                Self::SocketBGA1515 => "Socket BGA1515",
2736                Self::SocketLGA3647_1 => "Socket LGA3647-1",
2737                Self::SocketSP3 => "Socket SP3",
2738                Self::SocketSP3r23 => "Socket SP3r2",
2739                Self::SocketLGA2066 => "Socket LGA2066",
2740                Self::SocketBGA1392 => "Socket BGA1392",
2741                Self::SocketBGA1510 => "Socket BGA1510",
2742                Self::SocketBGA1528 => "Socket BGA1528",
2743                Self::SocketLGA4189 => "Socket LGA4189",
2744                Self::SocketLGA1200 => "Socket LGA1200",
2745                Self::SocketLGA4677 => "Socket LGA4677",
2746                Self::SocketLGA1700 => "Socket LGA1700",
2747                Self::SocketBGA1744 => "Socket BGA1744",
2748                Self::SocketBGA1781 => "Socket BGA1781",
2749                Self::SocketBGA1211 => "Socket BGA1211",
2750                Self::SocketBGA2422 => "Socket BGA2422",
2751                Self::SocketLGA1211 => "Socket LGA1211",
2752                Self::SocketLGA2422 => "Socket LGA2422",
2753                Self::SocketLGA5773 => "Socket LGA5773",
2754                Self::SocketBGA5773 => "Socket BGA5773",
2755                Self::SocketAM5 => "Socket AM5",
2756                Self::SocketSP5 => "Socket SP5",
2757                Self::SocketSP6 => "Socket SP6",
2758                Self::SocketBGA883 => "Socket BGA883",
2759                Self::SocketBGA1190 => "Socket BGA1190",
2760                Self::SocketBGA4129 => "Socket BGA4129",
2761                Self::SocketLGA4710 => "Socket LGA4710",
2762                Self::SocketLGA7529 => "Socket LGA7529",
2763                Self::SocketBGA1964 => "Socket BGA1964",
2764                Self::SocketBGA1792 => "Socket BGA1792",
2765                Self::SocketBGA2049 => "Socket BGA2049",
2766                Self::SocketBGA2551 => "Socket BGA2551",
2767                Self::SocketBGA2114 => "Socket BGA2114",
2768                Self::SocketBGA2833 => "Socket BGA2833",
2769                Self::SocketLGA1851 => "Socket LGA1851",
2770                Self::SeeSocketType => "See Socket Type",
2771                Self::None => "A value unknown to this standard, check the raw value",
2772            }
2773        )
2774    }
2775}
2776
2777impl From<smbioslib::ProcessorUpgrade> for ProcessorUpgrade {
2778    fn from(value: smbioslib::ProcessorUpgrade) -> Self {
2779        match value {
2780            smbioslib::ProcessorUpgrade::Other => Self::Other,
2781            smbioslib::ProcessorUpgrade::Unknown => Self::Unknown,
2782            smbioslib::ProcessorUpgrade::DaughterBoard => Self::DaughterBoard,
2783            smbioslib::ProcessorUpgrade::ZIFSocket => Self::ZIFSocket,
2784            smbioslib::ProcessorUpgrade::ReplaceablePiggyBack => Self::ReplaceablePiggyBack,
2785            smbioslib::ProcessorUpgrade::NoUpgrade => Self::NoUpgrade,
2786            smbioslib::ProcessorUpgrade::LIFSocket => Self::LIFSocket,
2787            smbioslib::ProcessorUpgrade::Slot1 => Self::Slot1,
2788            smbioslib::ProcessorUpgrade::Slot2 => Self::Slot2,
2789            smbioslib::ProcessorUpgrade::PinSocket370 => Self::PinSocket370,
2790            smbioslib::ProcessorUpgrade::SlotA => Self::SlotA,
2791            smbioslib::ProcessorUpgrade::SlotM => Self::SlotM,
2792            smbioslib::ProcessorUpgrade::Socket423 => Self::Socket423,
2793            smbioslib::ProcessorUpgrade::SocketASocket462 => Self::SocketASocket462,
2794            smbioslib::ProcessorUpgrade::Socket478 => Self::Socket478,
2795            smbioslib::ProcessorUpgrade::Socket754 => Self::Socket754,
2796            smbioslib::ProcessorUpgrade::Socket940 => Self::Socket940,
2797            smbioslib::ProcessorUpgrade::Socket939 => Self::Socket939,
2798            smbioslib::ProcessorUpgrade::SocketmPGA604 => Self::SocketmPGA604,
2799            smbioslib::ProcessorUpgrade::SocketLGA771 => Self::SocketLGA771,
2800            smbioslib::ProcessorUpgrade::SocketLGA775 => Self::SocketLGA775,
2801            smbioslib::ProcessorUpgrade::SocketS1 => Self::SocketS1,
2802            smbioslib::ProcessorUpgrade::SocketAM2 => Self::SocketAM2,
2803            smbioslib::ProcessorUpgrade::SocketF1207 => Self::SocketF1207,
2804            smbioslib::ProcessorUpgrade::SocketLGA1366 => Self::SocketLGA1366,
2805            smbioslib::ProcessorUpgrade::SocketG34 => Self::SocketG34,
2806            smbioslib::ProcessorUpgrade::SocketAM3 => Self::SocketAM3,
2807            smbioslib::ProcessorUpgrade::SocketC32 => Self::SocketC32,
2808            smbioslib::ProcessorUpgrade::SocketLGA1156 => Self::SocketLGA1156,
2809            smbioslib::ProcessorUpgrade::SocketLGA1567 => Self::SocketLGA1567,
2810            smbioslib::ProcessorUpgrade::SocketPGA988A => Self::SocketPGA988A,
2811            smbioslib::ProcessorUpgrade::SocketBGA1288 => Self::SocketBGA1288,
2812            smbioslib::ProcessorUpgrade::SocketrPGA988B => Self::SocketrPGA988B,
2813            smbioslib::ProcessorUpgrade::SocketBGA1023 => Self::SocketBGA1023,
2814            smbioslib::ProcessorUpgrade::SocketBGA1224 => Self::SocketBGA1224,
2815            smbioslib::ProcessorUpgrade::SocketLGA1155 => Self::SocketLGA1155,
2816            smbioslib::ProcessorUpgrade::SocketLGA1356 => Self::SocketLGA1356,
2817            smbioslib::ProcessorUpgrade::SocketLGA2011 => Self::SocketLGA2011,
2818            smbioslib::ProcessorUpgrade::SocketFS1 => Self::SocketFS1,
2819            smbioslib::ProcessorUpgrade::SocketFS2 => Self::SocketFS2,
2820            smbioslib::ProcessorUpgrade::SocketFM1 => Self::SocketFM1,
2821            smbioslib::ProcessorUpgrade::SocketFM2 => Self::SocketFM2,
2822            smbioslib::ProcessorUpgrade::SocketLGA2011_3 => Self::SocketLGA2011_3,
2823            smbioslib::ProcessorUpgrade::SocketLGA1356_3 => Self::SocketLGA1356_3,
2824            smbioslib::ProcessorUpgrade::SocketLGA1150 => Self::SocketLGA1150,
2825            smbioslib::ProcessorUpgrade::SocketBGA1168 => Self::SocketBGA1168,
2826            smbioslib::ProcessorUpgrade::SocketBGA1234 => Self::SocketBGA1234,
2827            smbioslib::ProcessorUpgrade::SocketBGA1364 => Self::SocketBGA1364,
2828            smbioslib::ProcessorUpgrade::SocketAM4 => Self::SocketAM4,
2829            smbioslib::ProcessorUpgrade::SocketLGA1151 => Self::SocketLGA1151,
2830            smbioslib::ProcessorUpgrade::SocketBGA1356 => Self::SocketBGA1356,
2831            smbioslib::ProcessorUpgrade::SocketBGA1440 => Self::SocketBGA1440,
2832            smbioslib::ProcessorUpgrade::SocketBGA1515 => Self::SocketBGA1515,
2833            smbioslib::ProcessorUpgrade::SocketLGA3647_1 => Self::SocketLGA3647_1,
2834            smbioslib::ProcessorUpgrade::SocketSP3 => Self::SocketSP3,
2835            smbioslib::ProcessorUpgrade::SocketSP3r23 => Self::SocketSP3r23,
2836            smbioslib::ProcessorUpgrade::SocketLGA2066 => Self::SocketLGA2066,
2837            smbioslib::ProcessorUpgrade::SocketBGA1392 => Self::SocketBGA1392,
2838            smbioslib::ProcessorUpgrade::SocketBGA1510 => Self::SocketBGA1510,
2839            smbioslib::ProcessorUpgrade::SocketBGA1528 => Self::SocketBGA1528,
2840            smbioslib::ProcessorUpgrade::SocketLGA4189 => Self::SocketLGA4189,
2841            smbioslib::ProcessorUpgrade::SocketLGA1200 => Self::SocketLGA1200,
2842            smbioslib::ProcessorUpgrade::SocketLGA4677 => Self::SocketLGA4677,
2843            smbioslib::ProcessorUpgrade::SocketLGA1700 => Self::SocketLGA1700,
2844            smbioslib::ProcessorUpgrade::SocketBGA1744 => Self::SocketBGA1744,
2845            smbioslib::ProcessorUpgrade::SocketBGA1781 => Self::SocketBGA1781,
2846            smbioslib::ProcessorUpgrade::SocketBGA1211 => Self::SocketBGA1211,
2847            smbioslib::ProcessorUpgrade::SocketBGA2422 => Self::SocketBGA2422,
2848            smbioslib::ProcessorUpgrade::SocketLGA1211 => Self::SocketLGA1211,
2849            smbioslib::ProcessorUpgrade::SocketLGA2422 => Self::SocketLGA2422,
2850            smbioslib::ProcessorUpgrade::SocketLGA5773 => Self::SocketLGA5773,
2851            smbioslib::ProcessorUpgrade::SocketBGA5773 => Self::SocketBGA5773,
2852            smbioslib::ProcessorUpgrade::SocketAM5 => Self::SocketAM5,
2853            smbioslib::ProcessorUpgrade::SocketSP5 => Self::SocketSP5,
2854            smbioslib::ProcessorUpgrade::SocketSP6 => Self::SocketSP6,
2855            smbioslib::ProcessorUpgrade::SocketBGA883 => Self::SocketBGA883,
2856            smbioslib::ProcessorUpgrade::SocketBGA1190 => Self::SocketBGA1190,
2857            smbioslib::ProcessorUpgrade::SocketBGA4129 => Self::SocketBGA4129,
2858            smbioslib::ProcessorUpgrade::SocketLGA4710 => Self::SocketLGA4710,
2859            smbioslib::ProcessorUpgrade::SocketLGA7529 => Self::SocketLGA7529,
2860            smbioslib::ProcessorUpgrade::SocketBGA1964 => Self::SocketBGA1964,
2861            smbioslib::ProcessorUpgrade::SocketBGA2049 => Self::SocketBGA2049,
2862            smbioslib::ProcessorUpgrade::SocketBGA1792 => Self::SocketBGA1792,
2863            smbioslib::ProcessorUpgrade::SocketBGA2551 => Self::SocketBGA2551,
2864            smbioslib::ProcessorUpgrade::SocketBGA2114 => Self::SocketBGA2114,
2865            smbioslib::ProcessorUpgrade::SocketBGA2833 => Self::SocketBGA2833,
2866            smbioslib::ProcessorUpgrade::SocketLGA1851 => Self::SocketLGA1851,
2867            smbioslib::ProcessorUpgrade::SeeSocketType => Self::SeeSocketType,
2868            smbioslib::ProcessorUpgrade::None => Self::None,
2869        }
2870    }
2871}
2872
2873#[derive(Debug, Deserialize, Serialize, Clone)]
2874pub enum CoreCount {
2875    Unknown,
2876    Count(u8),
2877    SeeCoreCount2,
2878}
2879
2880impl Display for CoreCount {
2881    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2882        match self {
2883            Self::Unknown => write!(f, "Unknown"),
2884            Self::SeeCoreCount2 => write!(f, "See next core count entry"),
2885            Self::Count(cnt) => write!(f, "{}", cnt),
2886        }
2887    }
2888}
2889
2890impl From<smbioslib::CoreCount> for CoreCount {
2891    fn from(value: smbioslib::CoreCount) -> Self {
2892        match value {
2893            smbioslib::CoreCount::Unknown => Self::Unknown,
2894            smbioslib::CoreCount::SeeCoreCount2 => Self::SeeCoreCount2,
2895            smbioslib::CoreCount::Count(cnt) => Self::Count(cnt),
2896        }
2897    }
2898}
2899
2900#[derive(Debug, Deserialize, Serialize, Clone)]
2901pub enum CoreCount2 {
2902    Unknown,
2903    Count(u16),
2904    Reserved,
2905}
2906
2907impl Display for CoreCount2 {
2908    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2909        match self {
2910            Self::Unknown => write!(f, "Unknown"),
2911            Self::Reserved => write!(f, "Reserved"),
2912            Self::Count(cnt) => write!(f, "{}", cnt),
2913        }
2914    }
2915}
2916
2917impl From<smbioslib::CoreCount2> for CoreCount2 {
2918    fn from(value: smbioslib::CoreCount2) -> Self {
2919        match value {
2920            smbioslib::CoreCount2::Unknown => Self::Unknown,
2921            smbioslib::CoreCount2::Reserved => Self::Reserved,
2922            smbioslib::CoreCount2::Count(cnt) => Self::Count(cnt),
2923        }
2924    }
2925}
2926
2927#[derive(Debug, Deserialize, Serialize, Clone)]
2928pub enum CoresEnabled {
2929    Unknown,
2930    Count(u8),
2931    SeeCoresEnabled2,
2932}
2933
2934impl Display for CoresEnabled {
2935    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2936        match self {
2937            Self::Unknown => write!(f, "Unknown"),
2938            Self::SeeCoresEnabled2 => write!(f, "See next cores enabled entry"),
2939            Self::Count(cnt) => write!(f, "{}", cnt),
2940        }
2941    }
2942}
2943
2944impl From<smbioslib::CoresEnabled> for CoresEnabled {
2945    fn from(value: smbioslib::CoresEnabled) -> Self {
2946        match value {
2947            smbioslib::CoresEnabled::Unknown => Self::Unknown,
2948            smbioslib::CoresEnabled::SeeCoresEnabled2 => Self::SeeCoresEnabled2,
2949            smbioslib::CoresEnabled::Count(cnt) => Self::Count(cnt),
2950        }
2951    }
2952}
2953
2954#[derive(Debug, Deserialize, Serialize, Clone)]
2955pub enum CoresEnabled2 {
2956    Unknown,
2957    Count(u16),
2958    Reserved,
2959}
2960
2961impl Display for CoresEnabled2 {
2962    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2963        match self {
2964            Self::Unknown => write!(f, "Unknown"),
2965            Self::Reserved => write!(f, "Reserved"),
2966            Self::Count(cnt) => write!(f, "{}", cnt),
2967        }
2968    }
2969}
2970
2971impl From<smbioslib::CoresEnabled2> for CoresEnabled2 {
2972    fn from(value: smbioslib::CoresEnabled2) -> Self {
2973        match value {
2974            smbioslib::CoresEnabled2::Unknown => Self::Unknown,
2975            smbioslib::CoresEnabled2::Reserved => Self::Reserved,
2976            smbioslib::CoresEnabled2::Count(cnt) => Self::Count(cnt),
2977        }
2978    }
2979}
2980
2981#[derive(Debug, Deserialize, Serialize, Clone)]
2982pub enum ThreadCount {
2983    Unknown,
2984    Count(u8),
2985    SeeThreadCount2,
2986}
2987
2988impl Display for ThreadCount {
2989    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2990        match self {
2991            Self::Unknown => write!(f, "Unknown"),
2992            Self::SeeThreadCount2 => write!(f, "See next thread enabled entry"),
2993            Self::Count(cnt) => write!(f, "{}", cnt),
2994        }
2995    }
2996}
2997
2998impl From<smbioslib::ThreadCount> for ThreadCount {
2999    fn from(value: smbioslib::ThreadCount) -> Self {
3000        match value {
3001            smbioslib::ThreadCount::SeeThreadCount2 => Self::SeeThreadCount2,
3002            smbioslib::ThreadCount::Unknown => Self::Unknown,
3003            smbioslib::ThreadCount::Count(cnt) => Self::Count(cnt),
3004        }
3005    }
3006}
3007
3008#[derive(Debug, Deserialize, Serialize, Clone)]
3009pub enum ThreadCount2 {
3010    Unknown,
3011    Count(u16),
3012    Reserved,
3013}
3014
3015impl Display for ThreadCount2 {
3016    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3017        match self {
3018            Self::Unknown => write!(f, "Unknown"),
3019            Self::Reserved => write!(f, "Reserved"),
3020            Self::Count(cnt) => write!(f, "{}", cnt),
3021        }
3022    }
3023}
3024
3025impl From<smbioslib::ThreadCount2> for ThreadCount2 {
3026    fn from(value: smbioslib::ThreadCount2) -> Self {
3027        match value {
3028            smbioslib::ThreadCount2::Reserved => Self::Reserved,
3029            smbioslib::ThreadCount2::Unknown => Self::Unknown,
3030            smbioslib::ThreadCount2::Count(cnt) => Self::Count(cnt),
3031        }
3032    }
3033}
3034
3035#[derive(Debug, Deserialize, Serialize, Clone)]
3036pub enum ThreadEnabled {
3037    Unknown,
3038    Count(u16),
3039    Reserved,
3040}
3041
3042impl Display for ThreadEnabled {
3043    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3044        match self {
3045            Self::Unknown => write!(f, "Unknown"),
3046            Self::Reserved => write!(f, "Reserved"),
3047            Self::Count(cnt) => write!(f, "{}", cnt),
3048        }
3049    }
3050}
3051
3052impl From<smbioslib::ThreadEnabled> for ThreadEnabled {
3053    fn from(value: smbioslib::ThreadEnabled) -> Self {
3054        match value {
3055            smbioslib::ThreadEnabled::Reserved => Self::Reserved,
3056            smbioslib::ThreadEnabled::Unknown => Self::Unknown,
3057            smbioslib::ThreadEnabled::Count(cnt) => Self::Count(cnt),
3058        }
3059    }
3060}
3061
3062/// Attributes of each CPU cache device in the system
3063#[derive(Debug, Serialize)]
3064pub struct Caches {
3065    pub caches: Vec<Cache>,
3066}
3067
3068impl Caches {
3069    /// Creates a new instance of `Self`
3070    ///
3071    /// It is usually not required, since an instance of this
3072    /// structure will be created using the method
3073    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
3074    /// [`DMITable::new()`].
3075    pub fn new() -> Result<Self> {
3076        let table = smbioslib::table_load_from_device()?;
3077        Self::new_from_table(&table)
3078    }
3079
3080    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
3081        let mut caches = vec![];
3082
3083        for cache_device in table.collect::<smbioslib::SMBiosCacheInformation>() {
3084            caches.push(Cache::from(cache_device));
3085        }
3086
3087        Ok(Self { caches })
3088    }
3089}
3090
3091impl ToJson for Caches {}
3092
3093// struct_migrate!(CacheConfiguration, smbioslib::CacheConfiguaration, {
3094//     raw: u16,
3095// });
3096
3097#[derive(Debug, Serialize)]
3098pub struct CacheConfiguaration {
3099    pub raw: u16,
3100}
3101
3102/// This structure defines the attributes of CPU cache device in the
3103/// system. One structure is specified for each such device, whether
3104/// the device is internal to or external to the CPU module.
3105#[derive(Debug, Serialize)]
3106pub struct Cache {
3107    /// String number for reference designation
3108    pub socket_designation: Option<String>,
3109
3110    /// Bit fields describing the cache configuration
3111    pub cache_configuration: Option<CacheConfiguaration>,
3112
3113    /// Maximum size that can be installed
3114    pub maximum_cache_size: Option<smbioslib::CacheMemorySize>,
3115
3116    /// Same format as Max Cache Size field; set 0 if no cache
3117    /// is installed.
3118    pub installed_size: Option<smbioslib::CacheMemorySize>,
3119
3120    /// Supported SRAM type
3121    pub supported_sram_type: Option<smbioslib::SramTypes>,
3122
3123    /// Current SRAM type
3124    pub current_sram_type: Option<smbioslib::SramTypes>,
3125
3126    /// Cache module speed, in nanosecs. The value is 0 if the
3127    /// speed is unknown
3128    pub cache_speed: Option<u8>,
3129
3130    /// Error-correction scheme supported by this cache component
3131    pub error_correction_type: Option<smbioslib::ErrorCorrectionTypeData>,
3132
3133    /// Logical type of cache
3134    pub system_cache_type: Option<smbioslib::SystemCacheTypeData>,
3135
3136    /// Associativity of the cache
3137    pub associativity: Option<smbioslib::CacheAssociativityData>,
3138
3139    /// Maximum cache size
3140    pub maximum_cache_size_2: Option<smbioslib::CacheMemorySize>,
3141
3142    /// Installed cache size
3143    pub installed_cache_size_2: Option<smbioslib::CacheMemorySize>,
3144}
3145
3146impl<'a> From<smbioslib::SMBiosCacheInformation<'a>> for Cache {
3147    fn from(value: smbioslib::SMBiosCacheInformation) -> Self {
3148        Self {
3149            socket_designation: value.socket_designation().ok(),
3150            cache_configuration: match value.cache_configuration() {
3151                Some(conf) => Some(CacheConfiguaration { raw: conf.raw }),
3152                None => None,
3153            },
3154            maximum_cache_size: value.maximum_cache_size(),
3155            installed_size: value.installed_size(),
3156            supported_sram_type: value.supported_sram_type(),
3157            current_sram_type: value.current_sram_type(),
3158            cache_speed: value.cache_speed(),
3159            error_correction_type: value.error_correction_type(),
3160            system_cache_type: value.system_cache_type(),
3161            associativity: value.associativity(),
3162            maximum_cache_size_2: value.maximum_cache_size_2(),
3163            installed_cache_size_2: value.installed_cache_size_2(),
3164        }
3165    }
3166}
3167impl ToJson for Cache {}
3168
3169/// Attributes of a system port connectors
3170#[derive(Debug, Serialize)]
3171pub struct PortConnectors {
3172    pub ports: Vec<Port>,
3173}
3174
3175impl PortConnectors {
3176    /// Creates a new instance of `Self`
3177    ///
3178    /// It is usually not required, since an instance of this
3179    /// structure will be created using the method
3180    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
3181    /// [`DMITable::new()`].
3182    pub fn new() -> Result<Self> {
3183        let table = smbioslib::table_load_from_device()?;
3184        Self::new_from_table(&table)
3185    }
3186
3187    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
3188        let mut ports = vec![];
3189
3190        for port in table.collect::<smbioslib::SMBiosPortConnectorInformation>() {
3191            ports.push(Port::from(port));
3192        }
3193
3194        Ok(Self { ports })
3195    }
3196}
3197
3198impl ToJson for PortConnectors {}
3199
3200/// Attributes of a system port connector (serial, parallel,
3201/// keyboard or mouse ports)
3202#[derive(Debug, Serialize)]
3203pub struct Port {
3204    /// Internal reference designator, that is, internal to the
3205    /// system enclosure
3206    pub internal_reference_designator: Option<String>,
3207
3208    /// Internal connector type
3209    pub internal_connector_type: Option<smbioslib::PortInformationConnectorTypeData>,
3210
3211    /// External reference designation, external to the system
3212    /// enclosure
3213    pub external_reference_designator: Option<String>,
3214
3215    /// External connector type
3216    pub external_connector_type: Option<smbioslib::PortInformationConnectorTypeData>,
3217
3218    /// Function of the port
3219    pub port_type: Option<smbioslib::PortInformationPortTypeData>,
3220}
3221
3222impl<'a> From<smbioslib::SMBiosPortConnectorInformation<'a>> for Port {
3223    fn from(value: smbioslib::SMBiosPortConnectorInformation) -> Self {
3224        Self {
3225            internal_reference_designator: value.internal_reference_designator().ok(),
3226            internal_connector_type: value.internal_connector_type(),
3227            external_reference_designator: value.external_reference_designator().ok(),
3228            external_connector_type: value.external_connector_type(),
3229            port_type: value.port_type(),
3230        }
3231    }
3232}
3233impl ToJson for Port {}
3234
3235/// Collection of memory devices that operate together to form a memory address space
3236#[derive(Debug, Serialize)]
3237pub struct MemoryArray {
3238    /// Physical location of the Memory Array, whether on the system
3239    /// board or an add-in board
3240    pub location: Option<smbioslib::MemoryArrayLocationData>,
3241
3242    /// Which the array is used
3243    pub usage: Option<smbioslib::MemoryArrayUseData>,
3244
3245    /// Primary hardware error correction or detection method
3246    /// supported by this memory array
3247    pub memory_error_correction: Option<smbioslib::MemoryArrayErrorCorrectionData>,
3248
3249    /// Maximum memory capacity, in kbytes, for this array
3250    pub maximum_capacity: Option<smbioslib::MaximumMemoryCapacity>,
3251
3252    /// Handle, or instance number, associated with any error that
3253    /// was previously detected for the array
3254    pub memory_error_information_handle: Option<smbioslib::Handle>,
3255
3256    /// Number of slots/sockets available for memory devices in
3257    /// this array
3258    pub number_of_memory_devices: Option<u16>,
3259
3260    /// Maximum memory capacity, in bytes, for this array. This
3261    /// field is only valid when the Maximum Capacity field
3262    /// contains 8000 0000h.
3263    pub extended_maximum_capacity: Option<u64>,
3264}
3265
3266impl MemoryArray {
3267    /// Creates a new instance of `Self`
3268    ///
3269    /// It is usually not required, since an instance of this
3270    /// structure will be created using the method
3271    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
3272    /// [`DMITable::new()`].
3273    pub fn new() -> Result<Self> {
3274        let table = smbioslib::table_load_from_device()?;
3275        Self::new_from_table(&table)
3276    }
3277
3278    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
3279        let t = table
3280            .find_map(|f: smbioslib::SMBiosPhysicalMemoryArray| Some(f))
3281            .ok_or(anyhow!(
3282                "Failed to get information about memory array (type 16)!"
3283            ))?;
3284
3285        Ok(Self {
3286            location: t.location(),
3287            usage: t.usage(),
3288            memory_error_correction: t.memory_error_correction(),
3289            maximum_capacity: t.maximum_capacity(),
3290            memory_error_information_handle: t.memory_error_information_handle(),
3291            number_of_memory_devices: t.number_of_memory_devices(),
3292            extended_maximum_capacity: t.extended_maximum_capacity(),
3293        })
3294    }
3295}
3296
3297impl ToJson for MemoryArray {}
3298
3299/// Information about all installed memory devices
3300#[derive(Debug, Serialize, Deserialize, Clone)]
3301pub struct MemoryDevices {
3302    pub memory: Vec<MemoryDevice>,
3303}
3304
3305impl MemoryDevices {
3306    /// Creates a new instance of `Self`
3307    ///
3308    /// It is usually not required, since an instance of this
3309    /// structure will be created using the method
3310    /// `Self::new_from_table(table: &SMBiosData)` in the constructor
3311    /// [`DMITable::new()`].
3312    pub fn new() -> Result<Self> {
3313        let table = smbioslib::table_load_from_device()?;
3314        Self::new_from_table(&table)
3315    }
3316
3317    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
3318        let mut memory = vec![];
3319
3320        for mem in table.collect::<smbioslib::SMBiosMemoryDevice>() {
3321            memory.push(MemoryDevice::from(mem));
3322        }
3323
3324        Ok(Self { memory })
3325    }
3326}
3327
3328impl ToJson for MemoryDevices {}
3329
3330/// Information about single memory device
3331#[derive(Debug, Serialize, Deserialize, Clone)]
3332pub struct MemoryDevice {
3333    /// Handle or instance number, associated with the physical
3334    /// memory array to which this device belongs
3335    pub physical_memory_array_handle: Option<Handle>,
3336
3337    /// Handle or instance number, associated with any error that
3338    /// was previously detected for the device. If the system does
3339    /// not provide the error information structure, the field
3340    /// containes FFFEH
3341    pub memory_error_information_handle: Option<Handle>,
3342
3343    /// Total width, in bits, of this memory device, including any
3344    /// check or error-correction bits
3345    pub total_width: Option<u16>,
3346
3347    /// Data width, in bits, of this memory device
3348    pub data_width: Option<u16>,
3349
3350    /// Size of memory device
3351    pub size: Option<MemorySize>,
3352
3353    /// Form factor for this memory device
3354    pub form_factor: Option<MemoryFormFactorData>,
3355
3356    /// Identifies when the Memory Device is one of a set of
3357    /// Memory Devices that must be populated with all devices
3358    /// of the same type and size, and the set to which this
3359    /// device belongs A value of 0 indicates that the device
3360    /// is not part of a set; a value of FFh indicates that the
3361    /// attribute is unknown
3362    pub device_set: Option<u8>,
3363
3364    /// Physically-labeled socket or board position where the
3365    /// memory device is located
3366    pub device_locator: Option<String>,
3367
3368    /// Physically-labeled bank where the memory device is located
3369    pub bank_locator: Option<String>,
3370
3371    /// Type of memory used in this device
3372    pub memory_type: Option<MemoryDeviceTypeData>,
3373
3374    /// Additional detail on the memory device type
3375    pub type_detail: Option<MemoryTypeDetails>,
3376
3377    /// The maximum capable speed of the device (MT/s)
3378    pub speed: Option<MemorySpeed>,
3379
3380    /// Manufacturer of this memory device
3381    pub manufacturer: Option<String>,
3382
3383    /// Serial number of this memory device
3384    pub serial_number: Option<String>,
3385
3386    /// Asset tag of this memory device
3387    pub asset_tag: Option<String>,
3388
3389    /// Part number of this memory device
3390    pub part_number: Option<String>,
3391
3392    /// Bits 7-4: reserved Bits 3-0: rank Value=0 for unknown rank information
3393    pub attributes: Option<u8>,
3394
3395    /// Extended suze of the memory device in MB
3396    pub extended_size: Option<MemorySizeExtended>,
3397
3398    /// Configured speed of the memory device, in megatransfers per second (MT/s)
3399    pub configured_memory_speed: Option<MemorySpeed>,
3400
3401    /// Minimum operating voltage for this device, in millivolts
3402    pub minimum_voltage: Option<u16>,
3403
3404    /// Maximum operating voltage for this device, in millivolts
3405    pub maximum_voltage: Option<u16>,
3406
3407    /// Configured voltage for this device, in millivolts
3408    pub configured_voltage: Option<u16>,
3409
3410    /// Memory technology type for this memory device
3411    pub memory_technology: Option<MemoryDeviceTechnologyData>,
3412
3413    /// The operating modes supported by this memory device
3414    pub memory_operating_mode_capability: Option<MemoryOperatingModeCapabilities>,
3415
3416    /// Firmware version of this memory device
3417    pub firmware_version: Option<String>,
3418
3419    /// Two-byte module manufacturer ID found in the SPD of this
3420    /// memory device; LSB first
3421    pub module_manufacturer_id: Option<u16>,
3422
3423    /// Two-byte module product id found in the SPD of this memory
3424    /// device; LSB first
3425    pub module_product_id: Option<u16>,
3426
3427    /// Two-byte memory subsystem controller manufacturer ID found
3428    /// in the SPD of this memory device; LSB first
3429    pub memory_subsystem_controller_manufacturer_id: Option<u16>,
3430
3431    /// Two-byte memory subsystem controller product ID found in
3432    /// the SPD of this memory device; LSB first
3433    pub memory_subsystem_controller_product_id: Option<u16>,
3434
3435    /// Size of the Non-volatile portion of the memory device in
3436    /// Bytes, if any
3437    pub non_volatile_size: Option<MemoryIndicatedSize>,
3438
3439    /// Size of the Volatile portion of the memory device in
3440    /// Bytes, if any
3441    pub volatile_size: Option<MemoryIndicatedSize>,
3442
3443    /// Size of the Cache portion of the memory device in Bytes,
3444    /// if any
3445    pub cache_size: Option<MemoryIndicatedSize>,
3446
3447    /// Size of the Logical memory device in Bytes
3448    pub logical_size: Option<MemoryIndicatedSize>,
3449
3450    /// Extended speed of the memory device (complements the
3451    /// Speed field at offset 15h). Identifies the maximum capable
3452    /// speed of the device, in MT/s
3453    pub extended_speed: Option<MemorySpeedExtended>,
3454
3455    /// Extended configured memory speed of the memory device
3456    /// (complements the `configure_memory_speed` field at offset
3457    /// 20h). Identifies the configured speed of the memory device,
3458    /// in MT/s
3459    pub extended_configured_speed: Option<MemorySpeedExtended>,
3460
3461    /// Two-byte PMIC0 manufacturer ID found in the SPD of this
3462    /// memory device; LSB first
3463    pub pmic0_manufacturer_id: Option<u16>,
3464
3465    /// PMIC 0 Revision Number found in the SPD of this memory
3466    /// device
3467    pub pmic0_revision_number: Option<u16>,
3468
3469    /// Two-byte RCD manufacturer ID found in the SPD of this
3470    /// memory device; LSB first
3471    pub rcd_manufacturer_id: Option<u16>,
3472
3473    /// RCD 0 Revision Number found in the SPD of this memory
3474    /// device
3475    pub rcd_revision_number: Option<u16>,
3476}
3477
3478impl<'a> From<smbioslib::SMBiosMemoryDevice<'a>> for MemoryDevice {
3479    fn from(value: smbioslib::SMBiosMemoryDevice) -> Self {
3480        Self {
3481            physical_memory_array_handle: Handle::from_opt(value.physical_memory_array_handle()),
3482            memory_error_information_handle: Handle::from_opt(
3483                value.memory_error_information_handle(),
3484            ),
3485            total_width: value.total_width(),
3486            data_width: value.data_width(),
3487            size: value.size().map(|s| MemorySize::from(s)),
3488            form_factor: match value.form_factor() {
3489                Some(ff) => Some(MemoryFormFactorData::from(ff)),
3490                _ => None,
3491            },
3492            device_set: value.device_set(),
3493            device_locator: value.device_locator().ok(),
3494            bank_locator: value.bank_locator().ok(),
3495            memory_type: value.memory_type().map(|mt| MemoryDeviceTypeData::from(mt)),
3496            type_detail: value.type_detail().map(|td| MemoryTypeDetails::from(td)),
3497            speed: value.speed().map(|s| MemorySpeed::from(s)),
3498            manufacturer: value.manufacturer().ok(),
3499            serial_number: value.serial_number().ok(),
3500            asset_tag: value.asset_tag().ok(),
3501            part_number: value.part_number().ok(),
3502            attributes: value.attributes(),
3503            extended_size: value.extended_size().map(|es| MemorySizeExtended::from(es)),
3504            configured_memory_speed: value
3505                .configured_memory_speed()
3506                .map(|cms| MemorySpeed::from(cms)),
3507            minimum_voltage: value.minimum_voltage(),
3508            maximum_voltage: value.maximum_voltage(),
3509            configured_voltage: value.configured_voltage(),
3510            memory_technology: value
3511                .memory_technology()
3512                .map(|mt| MemoryDeviceTechnologyData::from(mt)),
3513            memory_operating_mode_capability: value
3514                .memory_operating_mode_capability()
3515                .map(|momc| MemoryOperatingModeCapabilities::from(momc)),
3516            firmware_version: value.firmware_version().ok(),
3517            module_manufacturer_id: value.module_manufacturer_id(),
3518            module_product_id: value.module_product_id(),
3519            memory_subsystem_controller_manufacturer_id: value
3520                .memory_subsystem_controller_manufacturer_id(),
3521            memory_subsystem_controller_product_id: value.memory_subsystem_controller_product_id(),
3522            non_volatile_size: value
3523                .non_volatile_size()
3524                .map(|n| MemoryIndicatedSize::from(n)),
3525            volatile_size: value.volatile_size().map(|n| MemoryIndicatedSize::from(n)),
3526            cache_size: value.cache_size().map(|n| MemoryIndicatedSize::from(n)),
3527            logical_size: value.logical_size().map(|n| MemoryIndicatedSize::from(n)),
3528            extended_speed: value
3529                .extended_speed()
3530                .map(|es| MemorySpeedExtended::from(es)),
3531            extended_configured_speed: value
3532                .extended_speed()
3533                .map(|ecs| MemorySpeedExtended::from(ecs)),
3534            pmic0_manufacturer_id: value.pmic0_manufacturer_id(),
3535            pmic0_revision_number: value.pmic0_revision_number(),
3536            rcd_manufacturer_id: value.rcd_manufacturer_id(),
3537            rcd_revision_number: value.rcd_revision_number(),
3538        }
3539    }
3540}
3541
3542impl ToJson for MemoryDevice {}
3543
3544#[derive(Debug, Deserialize, Serialize, Clone)]
3545pub enum MemorySize {
3546    NotInstalled,
3547    Unknown,
3548    SeeExtendedSize,
3549    Kilobytes(u16),
3550    Megabytes(u16),
3551}
3552
3553impl From<smbioslib::MemorySize> for MemorySize {
3554    fn from(value: smbioslib::MemorySize) -> Self {
3555        match value {
3556            smbioslib::MemorySize::NotInstalled => Self::NotInstalled,
3557            smbioslib::MemorySize::Unknown => Self::Unknown,
3558            smbioslib::MemorySize::SeeExtendedSize => Self::SeeExtendedSize,
3559            smbioslib::MemorySize::Kilobytes(kb) => Self::Kilobytes(kb),
3560            smbioslib::MemorySize::Megabytes(mb) => Self::Megabytes(mb),
3561        }
3562    }
3563}
3564
3565impl Display for MemorySize {
3566    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3567        write!(
3568            f,
3569            "{}",
3570            match self {
3571                Self::NotInstalled => "Not installed".to_string(),
3572                Self::Unknown => "Unknown".to_string(),
3573                Self::SeeExtendedSize => "See Extended Size".to_string(),
3574                Self::Kilobytes(n) => format!("{n} KB"),
3575                Self::Megabytes(n) => format!("{n} MB"),
3576            }
3577        )
3578    }
3579}
3580
3581#[derive(Debug, Deserialize, Serialize, Clone)]
3582pub enum MemorySizeExtended {
3583    Megabytes(u32),
3584    SeeSize,
3585}
3586
3587impl From<smbioslib::MemorySizeExtended> for MemorySizeExtended {
3588    fn from(value: smbioslib::MemorySizeExtended) -> Self {
3589        match value {
3590            smbioslib::MemorySizeExtended::Megabytes(mb) => Self::Megabytes(mb),
3591            smbioslib::MemorySizeExtended::SeeSize => Self::SeeSize,
3592        }
3593    }
3594}
3595
3596impl Display for MemorySizeExtended {
3597    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3598        write!(
3599            f,
3600            "{}",
3601            match self {
3602                Self::Megabytes(n) => format!("{n} MB"),
3603                Self::SeeSize => "See Size".to_string(),
3604            }
3605        )
3606    }
3607}
3608
3609#[derive(Debug, Clone, Deserialize, Serialize)]
3610pub struct MemoryFormFactorData {
3611    pub raw: u8,
3612    pub value: MemoryFormFactor,
3613}
3614
3615impl From<smbioslib::MemoryFormFactorData> for MemoryFormFactorData {
3616    fn from(value: smbioslib::MemoryFormFactorData) -> Self {
3617        Self {
3618            raw: value.raw,
3619            value: MemoryFormFactor::from(value.value),
3620        }
3621    }
3622}
3623
3624#[derive(Debug, Clone, Deserialize, Serialize)]
3625pub enum MemoryFormFactor {
3626    Other,
3627    Unknown,
3628    Simm,
3629    Sip,
3630    Chip,
3631    Dip,
3632    Zip,
3633    ProprietaryCard,
3634    Dimm,
3635    Tsop,
3636    RowOfChips,
3637    Rimm,
3638    Sodimm,
3639    Srimm,
3640    Fbdimm,
3641    Die,
3642    Camm,
3643    Cudimm,
3644    Csodimm,
3645    None,
3646}
3647
3648impl From<smbioslib::MemoryFormFactor> for MemoryFormFactor {
3649    fn from(value: smbioslib::MemoryFormFactor) -> Self {
3650        match value {
3651            smbioslib::MemoryFormFactor::Other => Self::Other,
3652            smbioslib::MemoryFormFactor::Unknown => Self::Unknown,
3653            smbioslib::MemoryFormFactor::Simm => Self::Simm,
3654            smbioslib::MemoryFormFactor::Sip => Self::Sip,
3655            smbioslib::MemoryFormFactor::Chip => Self::Chip,
3656            smbioslib::MemoryFormFactor::Dip => Self::Dip,
3657            smbioslib::MemoryFormFactor::Zip => Self::Zip,
3658            smbioslib::MemoryFormFactor::ProprietaryCard => Self::ProprietaryCard,
3659            smbioslib::MemoryFormFactor::Dimm => Self::Dimm,
3660            smbioslib::MemoryFormFactor::Tsop => Self::Tsop,
3661            smbioslib::MemoryFormFactor::RowOfChips => Self::RowOfChips,
3662            smbioslib::MemoryFormFactor::Rimm => Self::Rimm,
3663            smbioslib::MemoryFormFactor::Sodimm => Self::Sodimm,
3664            smbioslib::MemoryFormFactor::Srimm => Self::Srimm,
3665            smbioslib::MemoryFormFactor::Fbdimm => Self::Fbdimm,
3666            smbioslib::MemoryFormFactor::Die => Self::Dip,
3667            smbioslib::MemoryFormFactor::Camm => Self::Camm,
3668            smbioslib::MemoryFormFactor::Cudimm => Self::Cudimm,
3669            smbioslib::MemoryFormFactor::Csodimm => Self::Csodimm,
3670            smbioslib::MemoryFormFactor::None => Self::None,
3671        }
3672    }
3673}
3674
3675impl Display for MemoryFormFactor {
3676    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3677        write!(
3678            f,
3679            "{}",
3680            match self {
3681                Self::Other => "Other",
3682                Self::Unknown => "Unknown",
3683                Self::Simm => "SIMM",
3684                Self::Sip => "SIP",
3685                Self::Chip => "Chip",
3686                Self::Dip => "DIP",
3687                Self::Zip => "ZIP",
3688                Self::ProprietaryCard => "Proprietary Card",
3689                Self::Dimm => "DIMM",
3690                Self::Tsop => "TSOP",
3691                Self::RowOfChips => "Row of chips",
3692                Self::Rimm => "RIMM",
3693                Self::Sodimm => "SODIMM",
3694                Self::Srimm => "SRIMM",
3695                Self::Fbdimm => "FB-DIMM",
3696                Self::Die => "Die",
3697                Self::Camm => "CAMM",
3698                Self::Cudimm => "CUDIMM",
3699                Self::Csodimm => "CSODIMM",
3700                Self::None => "None",
3701            }
3702        )
3703    }
3704}
3705
3706#[derive(Debug, Clone, Deserialize, Serialize)]
3707pub struct MemoryDeviceTypeData {
3708    pub raw: u8,
3709    pub value: MemoryDeviceType,
3710}
3711
3712impl From<smbioslib::MemoryDeviceTypeData> for MemoryDeviceTypeData {
3713    fn from(value: smbioslib::MemoryDeviceTypeData) -> Self {
3714        Self {
3715            raw: value.raw,
3716            value: MemoryDeviceType::from(value.value),
3717        }
3718    }
3719}
3720
3721#[derive(Debug, Clone, Deserialize, Serialize)]
3722pub enum MemoryDeviceType {
3723    Other,
3724    Unknown,
3725    Dram,
3726    Edram,
3727    Vram,
3728    Sram,
3729    Ram,
3730    Rom,
3731    Flash,
3732    Eeprom,
3733    Feprom,
3734    Eprom,
3735    Cdram,
3736    ThreeDram,
3737    Sdram,
3738    Sgram,
3739    Rdram,
3740    Ddr,
3741    Ddr2,
3742    Ddr2Fbdimm,
3743    Ddr3,
3744    Fbd2,
3745    Ddr4,
3746    Lpddr,
3747    Lpddr2,
3748    Lpddr3,
3749    Lpddr4,
3750    LogicalNonVolatileDevice,
3751    Hbm,
3752    Hbm2,
3753    Ddr5,
3754    Lpddr5,
3755    Hbm3,
3756    Mrdimm,
3757    None,
3758}
3759
3760impl From<smbioslib::MemoryDeviceType> for MemoryDeviceType {
3761    fn from(value: smbioslib::MemoryDeviceType) -> Self {
3762        match value {
3763            smbioslib::MemoryDeviceType::Other => Self::Other,
3764            smbioslib::MemoryDeviceType::Unknown => Self::Unknown,
3765            smbioslib::MemoryDeviceType::Dram => Self::Dram,
3766            smbioslib::MemoryDeviceType::Edram => Self::Edram,
3767            smbioslib::MemoryDeviceType::Vram => Self::Vram,
3768            smbioslib::MemoryDeviceType::Sram => Self::Sram,
3769            smbioslib::MemoryDeviceType::Ram => Self::Ram,
3770            smbioslib::MemoryDeviceType::Rom => Self::Rom,
3771            smbioslib::MemoryDeviceType::Flash => Self::Flash,
3772            smbioslib::MemoryDeviceType::Eeprom => Self::Eeprom,
3773            smbioslib::MemoryDeviceType::Feprom => Self::Feprom,
3774            smbioslib::MemoryDeviceType::Eprom => Self::Eprom,
3775            smbioslib::MemoryDeviceType::Cdram => Self::Cdram,
3776            smbioslib::MemoryDeviceType::ThreeDram => Self::ThreeDram,
3777            smbioslib::MemoryDeviceType::Sdram => Self::Sdram,
3778            smbioslib::MemoryDeviceType::Sgram => Self::Sgram,
3779            smbioslib::MemoryDeviceType::Rdram => Self::Rdram,
3780            smbioslib::MemoryDeviceType::Ddr => Self::Ddr,
3781            smbioslib::MemoryDeviceType::Ddr2 => Self::Ddr2,
3782            smbioslib::MemoryDeviceType::Ddr2Fbdimm => Self::Ddr2Fbdimm,
3783            smbioslib::MemoryDeviceType::Ddr3 => Self::Ddr3,
3784            smbioslib::MemoryDeviceType::Fbd2 => Self::Fbd2,
3785            smbioslib::MemoryDeviceType::Ddr4 => Self::Ddr4,
3786            smbioslib::MemoryDeviceType::Lpddr => Self::Lpddr,
3787            smbioslib::MemoryDeviceType::Lpddr2 => Self::Lpddr2,
3788            smbioslib::MemoryDeviceType::Lpddr3 => Self::Lpddr3,
3789            smbioslib::MemoryDeviceType::Lpddr4 => Self::Lpddr4,
3790            smbioslib::MemoryDeviceType::LogicalNonVolatileDevice => Self::LogicalNonVolatileDevice,
3791            smbioslib::MemoryDeviceType::Hbm => Self::Hbm,
3792            smbioslib::MemoryDeviceType::Hbm2 => Self::Hbm2,
3793            smbioslib::MemoryDeviceType::Ddr5 => Self::Ddr5,
3794            smbioslib::MemoryDeviceType::Lpddr5 => Self::Lpddr5,
3795            smbioslib::MemoryDeviceType::Hbm3 => Self::Hbm3,
3796            smbioslib::MemoryDeviceType::Mrdimm => Self::Mrdimm,
3797            smbioslib::MemoryDeviceType::None => Self::None,
3798        }
3799    }
3800}
3801
3802impl Display for MemoryDeviceType {
3803    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3804        write!(
3805            f,
3806            "{}",
3807            match self {
3808                Self::Other => "Other",
3809                Self::Unknown => "Unknown",
3810                Self::Dram => "DRAM",
3811                Self::Edram => "EDRAM",
3812                Self::Vram => "VRAM",
3813                Self::Sram => "SRAM",
3814                Self::Ram => "RAM",
3815                Self::Rom => "ROM",
3816                Self::Flash => "Flash",
3817                Self::Eeprom => "EEPROM",
3818                Self::Feprom => "FEPROM",
3819                Self::Eprom => "EPROM",
3820                Self::Cdram => "CDRAM",
3821                Self::ThreeDram => "3DRAM",
3822                Self::Sdram => "SDRAM",
3823                Self::Sgram => "SGRAM",
3824                Self::Rdram => "RDRAM",
3825                Self::Ddr => "DDR",
3826                Self::Ddr2 => "DDR2",
3827                Self::Ddr2Fbdimm => "DDR2 FB-DIMM",
3828                Self::Ddr3 => "DDR3",
3829                Self::Fbd2 => "FBD2",
3830                Self::Ddr4 => "DDR4",
3831                Self::Lpddr => "LPDDR",
3832                Self::Lpddr2 => "LPDDR2",
3833                Self::Lpddr3 => "LPDDR3",
3834                Self::Lpddr4 => "LPDDR4",
3835                Self::LogicalNonVolatileDevice => "Logical non-volatile device",
3836                Self::Hbm => "HBM (High Bandwidth Memory)",
3837                Self::Hbm2 => "HBM2 (High Bandwidth Memory Generation 2)",
3838                Self::Ddr5 => "DDR5",
3839                Self::Lpddr5 => "LPDDR5",
3840                Self::Hbm3 => "HBM3",
3841                Self::Mrdimm => "MRDIMM",
3842                Self::None => "A value unknown to this standard",
3843            }
3844        )
3845    }
3846}
3847
3848#[derive(Debug, Serialize, Deserialize, Clone)]
3849pub struct MemoryTypeDetails {
3850    /// Raw value
3851    pub raw: u16,
3852
3853    /// Bit 1 other
3854    pub other: bool,
3855
3856    /// But 2 unknown
3857    pub unknown: bool,
3858
3859    /// Bit 3 fast-paged
3860    pub fast_paged: bool,
3861
3862    /// Bit 4 static column
3863    pub static_column: bool,
3864
3865    /// Bit 5 pseudo-static
3866    pub pseudo_static: bool,
3867
3868    /// Bit 6 RAMBUS
3869    pub ram_bus: bool,
3870
3871    /// Bit 7 synchronous
3872    pub synchronous: bool,
3873
3874    /// Bit 8 CMOS
3875    pub cmos: bool,
3876
3877    /// Bit 9 EDO
3878    pub edo: bool,
3879
3880    /// Bit 10 Window DRAM
3881    pub window_dram: bool,
3882
3883    /// Bit 11 Cache DRAM
3884    pub cache_dram: bool,
3885
3886    // Bit 12 non-volatile
3887    pub non_volatile: bool,
3888
3889    /// Bit 13 Registered (Buffered)
3890    pub registered: bool,
3891
3892    /// Bit 14 Unbuffered (Unregistered)
3893    pub unbuffered: bool,
3894
3895    /// Bit 15 LRDIMM
3896    pub lrdimm: bool,
3897}
3898
3899impl From<smbioslib::MemoryTypeDetails> for MemoryTypeDetails {
3900    fn from(v: smbioslib::MemoryTypeDetails) -> Self {
3901        Self {
3902            raw: v.raw,
3903            other: v.other(),
3904            unknown: v.unknown(),
3905            fast_paged: v.fast_paged(),
3906            static_column: v.static_column(),
3907            pseudo_static: v.pseudo_static(),
3908            ram_bus: v.ram_bus(),
3909            synchronous: v.synchronous(),
3910            cmos: v.cmos(),
3911            edo: v.edo(),
3912            window_dram: v.window_dram(),
3913            cache_dram: v.cache_dram(),
3914            non_volatile: v.non_volatile(),
3915            registered: v.registered(),
3916            unbuffered: v.unbuffered(),
3917            lrdimm: v.lrdimm(),
3918        }
3919    }
3920}
3921
3922#[derive(Debug, Serialize, Deserialize, Clone)]
3923pub enum MemorySpeed {
3924    Unknown,
3925    SeeExtendedSpeed,
3926    MTs(u16),
3927}
3928
3929impl From<smbioslib::MemorySpeed> for MemorySpeed {
3930    fn from(value: smbioslib::MemorySpeed) -> Self {
3931        match value {
3932            smbioslib::MemorySpeed::Unknown => Self::Unknown,
3933            smbioslib::MemorySpeed::SeeExtendedSpeed => Self::SeeExtendedSpeed,
3934            smbioslib::MemorySpeed::MTs(mts) => Self::MTs(mts),
3935        }
3936    }
3937}
3938
3939impl Display for MemorySpeed {
3940    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3941        match self {
3942            Self::Unknown => write!(f, "Unknown"),
3943            Self::SeeExtendedSpeed => write!(f, "See Extended Speed"),
3944            Self::MTs(mts) => write!(f, "{mts} MT/s"),
3945        }
3946    }
3947}
3948
3949#[derive(Debug, Serialize, Deserialize, Clone)]
3950pub enum MemorySpeedExtended {
3951    MTs(u32),
3952    SeeSpeed,
3953}
3954
3955impl From<smbioslib::MemorySpeedExtended> for MemorySpeedExtended {
3956    fn from(value: smbioslib::MemorySpeedExtended) -> Self {
3957        match value {
3958            smbioslib::MemorySpeedExtended::MTs(mts) => Self::MTs(mts),
3959            smbioslib::MemorySpeedExtended::SeeSpeed => Self::SeeSpeed,
3960        }
3961    }
3962}
3963
3964impl Display for MemorySpeedExtended {
3965    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3966        match self {
3967            Self::MTs(mts) => write!(f, "{mts} MT/s"),
3968            Self::SeeSpeed => write!(f, "See Speed"),
3969        }
3970    }
3971}
3972
3973#[derive(Debug, Serialize, Deserialize, Clone)]
3974pub struct MemoryDeviceTechnologyData {
3975    pub raw: u8,
3976    pub value: MemoryDeviceTechnology,
3977}
3978
3979impl From<smbioslib::MemoryDeviceTechnologyData> for MemoryDeviceTechnologyData {
3980    fn from(value: smbioslib::MemoryDeviceTechnologyData) -> Self {
3981        Self {
3982            raw: value.raw,
3983            value: MemoryDeviceTechnology::from(value.value),
3984        }
3985    }
3986}
3987
3988#[derive(Debug, Serialize, Deserialize, Clone)]
3989pub enum MemoryDeviceTechnology {
3990    Other,
3991    Unknown,
3992    Dram,
3993    NvidimmN,
3994    NvidimmF,
3995    NvidimmP,
3996    IntelOptaneDcPersistentMemory,
3997    Mrdimm,
3998    None,
3999}
4000
4001impl From<smbioslib::MemoryDeviceTechnology> for MemoryDeviceTechnology {
4002    fn from(value: smbioslib::MemoryDeviceTechnology) -> Self {
4003        match value {
4004            smbioslib::MemoryDeviceTechnology::Other => Self::Other,
4005            smbioslib::MemoryDeviceTechnology::Unknown => Self::Unknown,
4006            smbioslib::MemoryDeviceTechnology::Dram => Self::Dram,
4007            smbioslib::MemoryDeviceTechnology::NvdimmN => Self::NvidimmN,
4008            smbioslib::MemoryDeviceTechnology::NvdimmF => Self::NvidimmF,
4009            smbioslib::MemoryDeviceTechnology::NvdimmP => Self::NvidimmP,
4010            smbioslib::MemoryDeviceTechnology::IntelOptaneDcPersistentMemory => {
4011                Self::IntelOptaneDcPersistentMemory
4012            }
4013            smbioslib::MemoryDeviceTechnology::Mrdimm => Self::Mrdimm,
4014            smbioslib::MemoryDeviceTechnology::None => Self::None,
4015        }
4016    }
4017}
4018
4019impl Display for MemoryDeviceTechnology {
4020    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4021        write!(
4022            f,
4023            "{}",
4024            match self {
4025                Self::Other => "Other",
4026                Self::Unknown => "Unknown",
4027                Self::Dram => "DRAM",
4028                Self::NvidimmN => "NVIDIMM-N",
4029                Self::NvidimmF => "NVIDIMM-F",
4030                Self::NvidimmP => "NVIDIMM-P",
4031                Self::IntelOptaneDcPersistentMemory => "Intel® Optane™ persistent memory",
4032                Self::Mrdimm => "MRDIMM (Deprecated)",
4033                Self::None => "???",
4034            }
4035        )
4036    }
4037}
4038
4039#[derive(Debug, Serialize, Deserialize, Clone)]
4040pub struct MemoryOperatingModeCapabilities {
4041    /// Raw value
4042    pub raw: u16,
4043
4044    /// Other
4045    pub other: bool,
4046
4047    /// Unknown
4048    pub unknown: bool,
4049
4050    /// Volatile memory
4051    pub volatile_memory: bool,
4052
4053    /// Byte-accessible persistent memory
4054    pub byte_accessible_persistent_memory: bool,
4055
4056    /// Block-accessible persistent memory
4057    pub block_accessible_persistent_memory: bool,
4058}
4059
4060impl From<smbioslib::MemoryOperatingModeCapabilities> for MemoryOperatingModeCapabilities {
4061    fn from(v: smbioslib::MemoryOperatingModeCapabilities) -> Self {
4062        Self {
4063            raw: v.raw,
4064            other: v.other(),
4065            unknown: v.unknown(),
4066            volatile_memory: v.volatile_memory(),
4067            byte_accessible_persistent_memory: v.byte_accessible_persistent_memory(),
4068            block_accessible_persistent_memory: v.block_accessible_persistent_memory(),
4069        }
4070    }
4071}
4072
4073#[derive(Debug, Serialize, Deserialize, Clone)]
4074pub enum MemoryIndicatedSize {
4075    Unknown,
4076    Bytes(u64),
4077}
4078
4079impl From<smbioslib::MemoryIndicatedSize> for MemoryIndicatedSize {
4080    fn from(value: smbioslib::MemoryIndicatedSize) -> Self {
4081        match value {
4082            smbioslib::MemoryIndicatedSize::Unknown => Self::Unknown,
4083            smbioslib::MemoryIndicatedSize::Bytes(b) => Self::Bytes(b),
4084        }
4085    }
4086}
4087
4088impl Display for MemoryIndicatedSize {
4089    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4090        write!(
4091            f,
4092            "{}",
4093            match self {
4094                Self::Unknown => "Unknown".to_string(),
4095                Self::Bytes(n) => format!("{n} B"),
4096            }
4097        )
4098    }
4099}
4100
4101#[derive(Debug, Deserialize, Serialize, Clone)]
4102pub struct CoolingDevice {
4103    /// Handle, or instance number, of the temperature probe monitoring this
4104    /// cooling device. A value of 0xFFFF indicates that no probe is provided.
4105    pub temperature_probe_handle: Option<Handle>,
4106
4107    /// Cooling device type and status.
4108    pub device_type_and_status: Option<CoolingDeviceTypeAndStatus>,
4109
4110    pub cooling_unit_group: Option<u8>,
4111
4112    pub oem_defined: Option<u32>,
4113    pub rotational_speed: Option<RotationalSpeed>,
4114    pub description: String,
4115}
4116
4117impl CoolingDevice {
4118    pub fn new() -> Result<Self> {
4119        let table = smbioslib::table_load_from_device()?;
4120        Self::new_from_table(&table)
4121    }
4122
4123    pub fn new_from_table(table: &SMBiosData) -> Result<Self> {
4124        let t = table
4125            .find_map(|f: smbioslib::SMBiosCoolingDevice| Some(f))
4126            .ok_or(anyhow!(
4127                "Failed to get information about cooling device (type 27)!"
4128            ))?;
4129
4130        Ok(Self {
4131            temperature_probe_handle: t.temperature_probe_handle().map(|h| Handle::from(h)),
4132            device_type_and_status: t
4133                .device_type_and_status()
4134                .map(|d| CoolingDeviceTypeAndStatus::from(d)),
4135            cooling_unit_group: t.cooling_unit_group(),
4136            oem_defined: t.oem_defined(),
4137            rotational_speed: t.nominal_speed().map(|r| RotationalSpeed::from(r)),
4138            description: t.description().to_string(),
4139        })
4140    }
4141}
4142
4143#[derive(Debug, Deserialize, Serialize, Clone)]
4144pub struct CoolingDeviceTypeAndStatus {
4145    /// Raw value
4146    pub raw: u8,
4147
4148    /// Device status
4149    pub device_status: CoolingDeviceStatus,
4150
4151    /// Device type
4152    pub device_type: CoolingDeviceType,
4153}
4154
4155impl From<smbioslib::CoolingDeviceTypeAndStatus> for CoolingDeviceTypeAndStatus {
4156    fn from(value: smbioslib::CoolingDeviceTypeAndStatus) -> Self {
4157        Self {
4158            raw: value.raw,
4159            device_status: CoolingDeviceStatus::from(value.device_status),
4160            device_type: CoolingDeviceType::from(value.device_type),
4161        }
4162    }
4163}
4164
4165#[derive(Debug, Deserialize, Serialize, Clone)]
4166pub enum CoolingDeviceStatus {
4167    Other,
4168    Unknown,
4169    OK,
4170    NonCritical,
4171    Critical,
4172    NonRecoverable,
4173    None,
4174}
4175
4176impl From<smbioslib::CoolingDeviceStatus> for CoolingDeviceStatus {
4177    fn from(value: smbioslib::CoolingDeviceStatus) -> Self {
4178        match value {
4179            smbioslib::CoolingDeviceStatus::Other => Self::Other,
4180            smbioslib::CoolingDeviceStatus::Unknown => Self::Unknown,
4181            smbioslib::CoolingDeviceStatus::OK => Self::OK,
4182            smbioslib::CoolingDeviceStatus::Critical => Self::Critical,
4183            smbioslib::CoolingDeviceStatus::NonCritical => Self::NonCritical,
4184            smbioslib::CoolingDeviceStatus::NonRecoverable => Self::NonRecoverable,
4185            smbioslib::CoolingDeviceStatus::None => Self::None,
4186        }
4187    }
4188}
4189
4190impl Display for CoolingDeviceStatus {
4191    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4192        write!(
4193            f,
4194            "{}",
4195            match self {
4196                Self::Other => "Other",
4197                Self::Unknown => "Unknown",
4198                Self::OK => "OK",
4199                Self::NonCritical => "Non-critical",
4200                Self::Critical => "Critical",
4201                Self::NonRecoverable => "Non-recoverable",
4202                Self::None => "None",
4203            }
4204        )
4205    }
4206}
4207
4208#[derive(Debug, Deserialize, Serialize, Clone)]
4209pub enum CoolingDeviceType {
4210    Other,
4211    Unknown,
4212    Fan,
4213    CentrifugalBlower,
4214    ChipFan,
4215    CabinetFan,
4216    PowerSupplyFan,
4217    HeatPipe,
4218    IntegratedRefrigeration,
4219    ActiveCooling,
4220    PassiveCooling,
4221    None,
4222}
4223
4224impl From<smbioslib::CoolingDeviceType> for CoolingDeviceType {
4225    fn from(value: smbioslib::CoolingDeviceType) -> Self {
4226        match value {
4227            smbioslib::CoolingDeviceType::Other => Self::Other,
4228            smbioslib::CoolingDeviceType::Unknown => Self::Unknown,
4229            smbioslib::CoolingDeviceType::Fan => Self::Fan,
4230            smbioslib::CoolingDeviceType::CentrifugalBlower => Self::CentrifugalBlower,
4231            smbioslib::CoolingDeviceType::ChipFan => Self::ChipFan,
4232            smbioslib::CoolingDeviceType::CabinetFan => Self::CabinetFan,
4233            smbioslib::CoolingDeviceType::PowerSupplyFan => Self::PowerSupplyFan,
4234            smbioslib::CoolingDeviceType::HeatPipe => Self::HeatPipe,
4235            smbioslib::CoolingDeviceType::IntegratedRefrigeration => Self::IntegratedRefrigeration,
4236            smbioslib::CoolingDeviceType::ActiveCooling => Self::ActiveCooling,
4237            smbioslib::CoolingDeviceType::PassiveCooling => Self::PassiveCooling,
4238            smbioslib::CoolingDeviceType::None => Self::None,
4239        }
4240    }
4241}
4242
4243impl Display for CoolingDeviceType {
4244    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4245        write!(
4246            f,
4247            "{}",
4248            match self {
4249                Self::Other => "Other",
4250                Self::Unknown => "Unknown",
4251                Self::Fan => "FAN",
4252                Self::CentrifugalBlower => "Cetrifugal Blower",
4253                Self::ChipFan => "Chip FAN",
4254                Self::CabinetFan => "Cabinet FAN",
4255                Self::PowerSupplyFan => "Power Supply FAN",
4256                Self::HeatPipe => "Heat Pipe",
4257                Self::IntegratedRefrigeration => "Integrated Refrigeration",
4258                Self::ActiveCooling => "Active Cooling",
4259                Self::PassiveCooling => "Passive Cooling",
4260                Self::None => "None",
4261            }
4262        )
4263    }
4264}
4265
4266#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
4267pub enum RotationalSpeed {
4268    Rpm(u16),
4269    Unknown,
4270}
4271
4272impl From<smbioslib::RotationalSpeed> for RotationalSpeed {
4273    fn from(value: smbioslib::RotationalSpeed) -> Self {
4274        match value {
4275            smbioslib::RotationalSpeed::Rpm(rpm) => Self::Rpm(rpm),
4276            smbioslib::RotationalSpeed::Unknown => Self::Unknown,
4277        }
4278    }
4279}
4280
4281impl Display for RotationalSpeed {
4282    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4283        match self {
4284            Self::Rpm(rpm) => write!(f, "{} RPM", rpm),
4285            Self::Unknown => write!(f, "Unknown"),
4286        }
4287    }
4288}