1use crate::{SMBiosStruct, UndefinedStruct};
2use serde::{ser::SerializeStruct, Serialize, Serializer};
3use std::fmt;
4use std::ops::Deref;
5
6pub struct SMBiosBuiltInPointingDevice<'a> {
17 parts: &'a UndefinedStruct,
18}
19
20impl<'a> SMBiosStruct<'a> for SMBiosBuiltInPointingDevice<'a> {
21 const STRUCT_TYPE: u8 = 21u8;
22
23 fn new(parts: &'a UndefinedStruct) -> Self {
24 Self { parts }
25 }
26
27 fn parts(&self) -> &'a UndefinedStruct {
28 self.parts
29 }
30}
31
32impl<'a> SMBiosBuiltInPointingDevice<'a> {
33 pub fn device_type(&self) -> Option<PointingDeviceTypeData> {
35 self.parts
36 .get_field_byte(0x04)
37 .map(|raw| PointingDeviceTypeData::from(raw))
38 }
39
40 pub fn interface(&self) -> Option<PointingDeviceInterfaceData> {
42 self.parts
43 .get_field_byte(0x05)
44 .map(|raw| PointingDeviceInterfaceData::from(raw))
45 }
46
47 pub fn number_of_buttons(&self) -> Option<u8> {
50 self.parts.get_field_byte(0x06)
51 }
52}
53
54impl fmt::Debug for SMBiosBuiltInPointingDevice<'_> {
55 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
56 fmt.debug_struct(std::any::type_name::<SMBiosBuiltInPointingDevice<'_>>())
57 .field("header", &self.parts.header)
58 .field("device_type", &self.device_type())
59 .field("interface", &self.interface())
60 .field("number_of_buttons", &self.number_of_buttons())
61 .finish()
62 }
63}
64
65impl Serialize for SMBiosBuiltInPointingDevice<'_> {
66 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67 where
68 S: Serializer,
69 {
70 let mut state = serializer.serialize_struct("SMBiosBuiltInPointingDevice", 4)?;
71 state.serialize_field("header", &self.parts.header)?;
72 state.serialize_field("device_type", &self.device_type())?;
73 state.serialize_field("interface", &self.interface())?;
74 state.serialize_field("number_of_buttons", &self.number_of_buttons())?;
75 state.end()
76 }
77}
78
79pub struct PointingDeviceTypeData {
81 pub raw: u8,
88 pub value: PointingDeviceType,
90}
91
92impl fmt::Debug for PointingDeviceTypeData {
93 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
94 fmt.debug_struct(std::any::type_name::<PointingDeviceTypeData>())
95 .field("raw", &self.raw)
96 .field("value", &self.value)
97 .finish()
98 }
99}
100
101impl Serialize for PointingDeviceTypeData {
102 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103 where
104 S: Serializer,
105 {
106 let mut state = serializer.serialize_struct("PointingDeviceTypeData", 2)?;
107 state.serialize_field("raw", &self.raw)?;
108 state.serialize_field("value", &self.value)?;
109 state.end()
110 }
111}
112
113impl fmt::Display for PointingDeviceTypeData {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match &self.value {
116 PointingDeviceType::None => write!(f, "{}", &self.raw),
117 _ => write!(f, "{:?}", &self.value),
118 }
119 }
120}
121
122impl Deref for PointingDeviceTypeData {
123 type Target = PointingDeviceType;
124
125 fn deref(&self) -> &Self::Target {
126 &self.value
127 }
128}
129
130#[derive(Serialize, Debug, PartialEq, Eq)]
132pub enum PointingDeviceType {
133 Other,
135 Unknown,
137 Mouse,
139 TrackBall,
141 TrackPoint,
143 GlidePoint,
145 TouchPad,
147 TouchScreen,
149 OpticalSensor,
151 None,
153}
154
155impl From<u8> for PointingDeviceTypeData {
156 fn from(raw: u8) -> Self {
157 PointingDeviceTypeData {
158 value: match raw {
159 0x01 => PointingDeviceType::Other,
160 0x02 => PointingDeviceType::Unknown,
161 0x03 => PointingDeviceType::Mouse,
162 0x04 => PointingDeviceType::TrackBall,
163 0x05 => PointingDeviceType::TrackPoint,
164 0x06 => PointingDeviceType::GlidePoint,
165 0x07 => PointingDeviceType::TouchPad,
166 0x08 => PointingDeviceType::TouchScreen,
167 0x09 => PointingDeviceType::OpticalSensor,
168 _ => PointingDeviceType::None,
169 },
170 raw,
171 }
172 }
173}
174
175pub struct PointingDeviceInterfaceData {
177 pub raw: u8,
184 pub value: PointingDeviceInterface,
186}
187
188impl fmt::Debug for PointingDeviceInterfaceData {
189 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
190 fmt.debug_struct(std::any::type_name::<PointingDeviceInterfaceData>())
191 .field("raw", &self.raw)
192 .field("value", &self.value)
193 .finish()
194 }
195}
196
197impl Serialize for PointingDeviceInterfaceData {
198 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
199 where
200 S: Serializer,
201 {
202 let mut state = serializer.serialize_struct("PointingDeviceInterfaceData", 2)?;
203 state.serialize_field("raw", &self.raw)?;
204 state.serialize_field("value", &self.value)?;
205 state.end()
206 }
207}
208
209impl Deref for PointingDeviceInterfaceData {
210 type Target = PointingDeviceInterface;
211
212 fn deref(&self) -> &Self::Target {
213 &self.value
214 }
215}
216
217#[derive(Serialize, Debug, PartialEq, Eq)]
219pub enum PointingDeviceInterface {
220 Other,
222 Unknown,
224 Serial,
226 PS2,
228 Infrared,
230 HpHil,
232 BusMouse,
234 Adb,
236 BusMouseDB9,
238 BusMouseMicroDin,
240 USB,
242 I2C,
246 SPI,
250 None,
252}
253
254impl From<u8> for PointingDeviceInterfaceData {
255 fn from(raw: u8) -> Self {
256 PointingDeviceInterfaceData {
257 value: match raw {
258 0x01 => PointingDeviceInterface::Other,
259 0x02 => PointingDeviceInterface::Unknown,
260 0x03 => PointingDeviceInterface::Serial,
261 0x04 => PointingDeviceInterface::PS2,
262 0x05 => PointingDeviceInterface::Infrared,
263 0x06 => PointingDeviceInterface::HpHil,
264 0x07 => PointingDeviceInterface::BusMouse,
265 0x08 => PointingDeviceInterface::Adb,
266 0xA0 => PointingDeviceInterface::BusMouseDB9,
267 0xA1 => PointingDeviceInterface::BusMouseMicroDin,
268 0xA2 => PointingDeviceInterface::USB,
269 0xA3 => PointingDeviceInterface::I2C,
270 0xA4 => PointingDeviceInterface::SPI,
271 _ => PointingDeviceInterface::None,
272 },
273 raw,
274 }
275 }
276}
277
278#[cfg(test)]
279mod tests {
280 use super::*;
281
282 #[test]
283 fn unit_test() {
284 let struct_type21 = vec![0x15, 0x07, 0x31, 0x00, 0x05, 0x04, 0x03, 0x00, 0x00];
285
286 let parts = UndefinedStruct::new(&struct_type21);
287 let test_struct = SMBiosBuiltInPointingDevice::new(&parts);
288
289 assert_eq!(
290 *test_struct.device_type().unwrap(),
291 PointingDeviceType::TrackPoint
292 );
293 assert_eq!(
294 *test_struct.interface().unwrap(),
295 PointingDeviceInterface::PS2
296 );
297 assert_eq!(test_struct.number_of_buttons(), Some(3));
298 }
299}