smbioslib/core/
smbios_data.rs1use super::header::Handle;
2use super::undefined_struct::{UndefinedStruct, UndefinedStructTable};
3use crate::structs::{DefinedStructTable, SMBiosStruct};
4use serde::{ser::SerializeStruct, Serialize, Serializer};
5use std::io::Error;
6use std::{cmp::Ordering, slice::Iter};
7use std::{fmt, fs::read};
8
9pub struct SMBiosData {
13 table: UndefinedStructTable,
14 pub version: Option<SMBiosVersion>,
16}
17
18impl<'a> SMBiosData {
19 pub fn new(table: UndefinedStructTable, version: Option<SMBiosVersion>) -> Self {
24 Self { table, version }
25 }
26
27 pub fn from_vec_and_version(data: Vec<u8>, version: Option<SMBiosVersion>) -> Self {
32 Self {
33 table: UndefinedStructTable::from(data),
34 version,
35 }
36 }
37
38 pub fn try_load_from_file(
40 filename: &str,
41 version: Option<SMBiosVersion>,
42 ) -> Result<SMBiosData, Error> {
43 let data = read(filename)?;
44 let result = Self {
45 table: UndefinedStructTable::from(data),
46 version,
47 };
48 Ok(result)
49 }
50
51 pub fn iter(&self) -> Iter<'_, UndefinedStruct> {
53 self.table.iter()
54 }
55
56 pub fn defined_struct_iter<T: 'a>(&'a self) -> impl Iterator<Item = T> + 'a
58 where
59 T: SMBiosStruct<'a>,
60 {
61 self.table.defined_struct_iter()
62 }
63
64 pub fn all<T, F>(&'a self, f: F) -> bool
66 where
67 T: SMBiosStruct<'a>,
68 F: FnMut(T) -> bool,
69 {
70 self.table.all(f)
71 }
72
73 pub fn any<T, F>(&'a self, f: F) -> bool
75 where
76 T: SMBiosStruct<'a>,
77 F: FnMut(T) -> bool,
78 {
79 self.table.any(f)
80 }
81
82 pub fn first<T>(&'a self) -> Option<T>
84 where
85 T: SMBiosStruct<'a>,
86 {
87 self.table.first()
88 }
89
90 pub fn find<T, P>(&'a self, predicate: P) -> Option<T>
92 where
93 T: SMBiosStruct<'a>,
94 P: FnMut(&T) -> bool,
95 {
96 self.table.find(predicate)
97 }
98
99 pub fn find_map<A, B, F>(&'a self, f: F) -> Option<B>
101 where
102 A: SMBiosStruct<'a>,
103 F: FnMut(A) -> Option<B>,
104 {
105 self.table.find_map(f)
106 }
107
108 pub fn filter<T: 'a, P: 'a>(&'a self, predicate: P) -> impl Iterator<Item = T> + 'a
110 where
111 T: SMBiosStruct<'a>,
112 P: FnMut(&T) -> bool,
113 {
114 self.table.filter(predicate)
115 }
116
117 pub fn map<A: 'a, B: 'a, F: 'a>(&'a self, f: F) -> impl Iterator<Item = B> + 'a
119 where
120 A: SMBiosStruct<'a>,
121 F: FnMut(A) -> B,
122 {
123 self.table.map(f)
124 }
125
126 pub fn filter_map<A: 'a, B: 'a, F: 'a>(&'a self, f: F) -> impl Iterator<Item = B> + 'a
128 where
129 A: SMBiosStruct<'a>,
130 F: FnMut(A) -> Option<B>,
131 {
132 self.table.filter_map(f)
133 }
134
135 pub fn find_by_handle(&'a self, handle: &Handle) -> Option<&UndefinedStruct> {
137 self.table.find_by_handle(handle)
138 }
139
140 pub fn collect<T>(&'a self) -> Vec<T>
142 where
143 T: SMBiosStruct<'a>,
144 {
145 self.table.collect()
146 }
147}
148
149impl IntoIterator for SMBiosData {
150 type Item = UndefinedStruct;
151 type IntoIter = std::vec::IntoIter<Self::Item>;
152
153 fn into_iter(self) -> Self::IntoIter {
154 self.table.into_iter()
155 }
156}
157
158impl fmt::Debug for SMBiosData {
159 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
160 let defined_table: DefinedStructTable<'_> = self.table.iter().collect();
162
163 fmt.debug_struct(std::any::type_name::<SMBiosData>())
164 .field("version", &self.version)
165 .field("table", &defined_table)
166 .finish()
167 }
168}
169
170impl Serialize for SMBiosData {
171 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
172 where
173 S: Serializer,
174 {
175 let defined_table: DefinedStructTable<'_> = self.table.iter().collect();
177
178 let mut state = serializer.serialize_struct("SMBiosData", 2)?;
179 state.serialize_field("version", &self.version)?;
180 state.serialize_field("table", &defined_table)?;
181 state.end()
182 }
183}
184
185#[derive(Debug, Eq, PartialEq, Serialize, Clone, Copy)]
187pub struct SMBiosVersion {
188 pub major: u8,
190 pub minor: u8,
192 pub revision: u8,
194}
195
196impl SMBiosVersion {
197 pub fn new(major: u8, minor: u8, revision: u8) -> SMBiosVersion {
199 SMBiosVersion {
200 major,
201 minor,
202 revision,
203 }
204 }
205}
206
207impl Ord for SMBiosVersion {
208 fn cmp(&self, other: &Self) -> Ordering {
209 if self.major < other.major {
210 Ordering::Less
211 } else if self.major > other.major {
212 Ordering::Greater
213 } else if self.minor < other.minor {
214 Ordering::Less
215 } else if self.minor > other.minor {
216 Ordering::Greater
217 } else if self.revision < other.revision {
218 Ordering::Less
219 } else if self.revision > other.revision {
220 Ordering::Greater
221 } else {
222 Ordering::Equal
223 }
224 }
225}
226
227impl PartialOrd for SMBiosVersion {
228 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
229 Some(self.cmp(other))
230 }
231}