1use serde::{ser::SerializeStruct, Serialize, Serializer};
2use std::{convert::TryInto, fmt, ops::Deref, str::FromStr};
3
4#[derive(Serialize, PartialEq, Eq)]
11pub struct Handle(pub u16);
12
13impl Handle {
14 pub const SIZE: usize = 2usize;
16}
17
18impl fmt::Debug for Handle {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 write!(f, "{}", &self.0)
21 }
22}
23
24impl fmt::Display for Handle {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 write!(f, "{}", &self.0)
27 }
28}
29
30impl Deref for Handle {
31 type Target = u16;
32
33 fn deref(&self) -> &Self::Target {
34 &self.0
35 }
36}
37
38impl FromStr for Handle {
39 type Err = std::num::ParseIntError;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 Ok(Handle(if s.starts_with("0x") && s.len() > 2 {
43 u16::from_str_radix(&s[2..], 16)?
44 } else {
45 u16::from_str(s)?
46 }))
47 }
48}
49
50#[derive(Serialize)]
56pub struct SMBiosType(pub u8);
57
58impl Deref for SMBiosType {
59 type Target = u8;
60
61 fn deref(&self) -> &Self::Target {
62 &self.0
63 }
64}
65
66impl fmt::Debug for SMBiosType {
67 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
68 fmt.debug_struct(std::any::type_name::<SMBiosType>())
69 .field("type", &self.0)
70 .finish()
71 }
72}
73
74pub struct Header([u8; 4]);
78
79impl fmt::Debug for Header {
80 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
81 fmt.debug_struct(std::any::type_name::<Header>())
82 .field("struct_type", &self.struct_type())
83 .field("length", &self.length())
84 .field("handle", &self.handle())
85 .finish()
86 }
87}
88
89impl Serialize for Header {
90 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
91 where
92 S: Serializer,
93 {
94 let mut state = serializer.serialize_struct("Header", 3)?;
95 state.serialize_field("struct_type", &self.struct_type())?;
96 state.serialize_field("length", &self.length())?;
97 state.serialize_field("handle", &self.handle())?;
98 state.end()
99 }
100}
101
102impl Header {
103 pub const SIZE: usize = 4;
110
111 pub const STRUCT_TYPE_OFFSET: usize = 0;
113
114 pub const LENGTH_OFFSET: usize = 1;
116
117 pub const HANDLE_OFFSET: usize = 2;
119
120 pub fn new(data: [u8; 4]) -> Self {
122 Header(data)
123 }
124
125 pub fn struct_type(&self) -> u8 {
127 self.0[Self::STRUCT_TYPE_OFFSET] }
129
130 pub fn length(&self) -> u8 {
132 self.0[Self::LENGTH_OFFSET] }
134
135 pub fn handle(&self) -> Handle {
137 Handle(u16::from_le_bytes(
139 self.0[Self::HANDLE_OFFSET..Self::HANDLE_OFFSET + 2]
140 .try_into()
141 .expect("u16 is 2 bytes"),
142 ))
143 }
144
145 pub fn iter(&self) -> std::slice::Iter<'_, u8> {
147 self.0.iter()
148 }
149}
150
151impl From<[u8; 4]> for Header {
152 fn from(data: [u8; 4]) -> Self {
153 Header(data)
154 }
155}
156
157impl Deref for Header {
158 type Target = [u8; 4];
159
160 fn deref(&self) -> &Self::Target {
161 &self.0
162 }
163}