smbioslib/structs/types/
string_property.rs1use crate::core::{strings::*, Handle, UndefinedStruct};
2use crate::SMBiosStruct;
3use serde::{ser::SerializeStruct, Serialize, Serializer};
4use std::fmt;
5use std::ops::Deref;
6
7pub struct SMBiosStringProperty<'a> {
19 parts: &'a UndefinedStruct,
20}
21
22impl<'a> SMBiosStruct<'a> for SMBiosStringProperty<'a> {
23 const STRUCT_TYPE: u8 = 46u8;
24
25 fn new(parts: &'a UndefinedStruct) -> Self {
26 Self { parts }
27 }
28
29 fn parts(&self) -> &'a UndefinedStruct {
30 self.parts
31 }
32}
33
34impl<'a> SMBiosStringProperty<'a> {
35 pub fn string_property_id(&self) -> Option<StringPropertyIdData> {
37 self.parts
38 .get_field_word(0x04)
39 .map(|raw| StringPropertyIdData::from(raw))
40 }
41
42 pub fn string_property_value(&self) -> SMBiosString {
44 self.parts.get_field_string(0x06)
45 }
46
47 pub fn parent_handle(&self) -> Option<Handle> {
51 self.parts.get_field_handle(0x07)
52 }
53}
54
55impl fmt::Debug for SMBiosStringProperty<'_> {
56 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
57 fmt.debug_struct(std::any::type_name::<SMBiosStringProperty<'_>>())
58 .field("header", &self.parts.header)
59 .field("string_property_id", &self.string_property_id())
60 .field("string_property_value", &self.string_property_value())
61 .field("parent_handle", &self.parent_handle())
62 .finish()
63 }
64}
65
66impl Serialize for SMBiosStringProperty<'_> {
67 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68 where
69 S: Serializer,
70 {
71 let mut state = serializer.serialize_struct("SMBiosStringProperty", 3)?;
72 state.serialize_field("header", &self.parts.header)?;
73 state.serialize_field("string_property_id", &self.string_property_id())?;
74 state.serialize_field("string_property_value", &self.string_property_value())?;
75 state.serialize_field("parent_handle", &self.parent_handle())?;
76 state.end()
77 }
78}
79
80pub struct StringPropertyIdData {
82 pub raw: u16,
89 pub value: StringPropertyId,
91}
92
93impl fmt::Debug for StringPropertyIdData {
94 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
95 fmt.debug_struct(std::any::type_name::<StringPropertyIdData>())
96 .field("raw", &self.raw)
97 .field("value", &self.value)
98 .finish()
99 }
100}
101
102impl Serialize for StringPropertyIdData {
103 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
104 where
105 S: Serializer,
106 {
107 let mut state = serializer.serialize_struct("StringPropertyIdData", 2)?;
108 state.serialize_field("raw", &self.raw)?;
109 state.serialize_field("value", &self.value)?;
110 state.end()
111 }
112}
113
114impl fmt::Display for StringPropertyIdData {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 match &self.value {
117 StringPropertyId::None => write!(f, "{}", &self.raw),
118 _ => write!(f, "{:?}", &self.value),
119 }
120 }
121}
122
123impl Deref for StringPropertyIdData {
124 type Target = StringPropertyId;
125
126 fn deref(&self) -> &Self::Target {
127 &self.value
128 }
129}
130
131impl From<u16> for StringPropertyIdData {
132 fn from(raw: u16) -> Self {
133 StringPropertyIdData {
134 value: match raw {
135 0x0001 => StringPropertyId::UefiDevicePath,
136 _ => match raw & 0b1000_0000_0000_0000 {
137 0b1000_0000_0000_0000 => match raw & 0b1100_0000_0000_0000 {
139 0b1100_0000_0000_0000 => StringPropertyId::OemSpecific, _ => StringPropertyId::VendorSpecific, },
143 _ => StringPropertyId::None,
144 },
145 },
146 raw,
147 }
148 }
149}
150
151#[derive(Serialize, Debug, PartialEq, Eq)]
153pub enum StringPropertyId {
154 UefiDevicePath,
159 VendorSpecific,
161 OemSpecific,
163 None,
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn unit_test() {
173 let struct_type46 = vec![
174 0x2E, 0x09, 0x10, 0x00,
176 0x01, 0x00, 0x01, 0x08, 0x00, b'A', b'b', b'c', b'd', 0x00, 0x00,
179 ];
180
181 let parts = UndefinedStruct::new(&struct_type46);
182 let test_struct = SMBiosStringProperty::new(&parts);
183
184 assert_eq!(
185 test_struct.string_property_id().unwrap().value,
186 StringPropertyId::UefiDevicePath
187 );
188
189 assert_eq!(test_struct.string_property_value().to_string(), "Abcd");
190
191 assert_eq!(*test_struct.parent_handle().unwrap(), 8u16);
192 }
193}