qemu_command_builder/
smbios.rs

1use std::path::PathBuf;
2
3use bon::Builder;
4
5use crate::common::OnOff;
6use crate::to_command::{ToArg, ToCommand};
7
8/// Load SMBIOS entry from binary file.
9#[derive(Default, Builder)]
10pub struct SmbiosFile {
11    path: PathBuf,
12}
13
14impl ToCommand for SmbiosFile {
15    fn to_command(&self) -> Vec<String> {
16        let mut cmd = vec![];
17        cmd.push("-smbios".to_string());
18        cmd.push(format!("file={}", self.path.display()));
19        cmd
20    }
21}
22
23/// Specify SMBIOS type 0 fields
24#[derive(Default, Builder)]
25pub struct SmbiosType0 {
26    vendor: Option<String>,
27    version: Option<String>,
28    date: Option<String>,
29    release: Option<(usize, usize)>,
30    uefi: Option<OnOff>,
31}
32
33impl ToCommand for SmbiosType0 {
34    fn to_command(&self) -> Vec<String> {
35        let mut cmd = vec![];
36        cmd.push("-smbios".to_string());
37        let mut args = vec!["type=0".to_string()];
38        if let Some(vendor) = &self.vendor {
39            args.push(format!("vendor={}", vendor));
40        }
41        if let Some(version) = &self.version {
42            args.push(format!("version={}", version));
43        }
44        if let Some(date) = &self.date {
45            args.push(format!("date={}", date));
46        }
47        if let Some(release) = &self.release {
48            args.push(format!("release={}.{}", release.0, release.1));
49        }
50        if let Some(uefi) = &self.uefi {
51            args.push(format!("uefi={}", uefi.to_arg()));
52        }
53        cmd.push(args.join(","));
54        cmd
55    }
56}
57
58/// Specify SMBIOS type 1 fields
59#[derive(Default, Builder)]
60pub struct SmbiosType1 {
61    manufacturer: Option<String>,
62    product: Option<String>,
63    version: Option<String>,
64    serial: Option<String>,
65    uuid: Option<String>,
66    sku: Option<String>,
67    family: Option<String>,
68}
69
70impl ToCommand for SmbiosType1 {
71    fn to_command(&self) -> Vec<String> {
72        let mut cmd = vec![];
73        cmd.push("-smbios".to_string());
74        let mut args = vec!["type=1".to_string()];
75        if let Some(manufacturer) = &self.manufacturer {
76            args.push(format!("manufacturer={}", manufacturer));
77        }
78        if let Some(product) = &self.product {
79            args.push(format!("product={}", product));
80        }
81        if let Some(version) = &self.version {
82            args.push(format!("version={}", version));
83        }
84        if let Some(serial) = &self.serial {
85            args.push(format!("serial={}", serial));
86        }
87        if let Some(uuid) = &self.uuid {
88            args.push(format!("uuid={}", uuid));
89        }
90        if let Some(sku) = &self.sku {
91            args.push(format!("sku={}", sku));
92        }
93        if let Some(family) = &self.family {
94            args.push(format!("family={}", family));
95        }
96        cmd.push(args.join(","));
97        cmd
98    }
99}
100
101/// Specify SMBIOS type 2 fields
102#[derive(Default, Builder)]
103pub struct SmbiosType2 {
104    manufacturer: Option<String>,
105    product: Option<String>,
106    version: Option<String>,
107    serial: Option<String>,
108    asset: Option<String>,
109    location: Option<String>,
110}
111
112impl ToCommand for SmbiosType2 {
113    fn to_command(&self) -> Vec<String> {
114        let mut cmd = vec![];
115        cmd.push("-smbios".to_string());
116        let mut args = vec!["type=2".to_string()];
117        if let Some(manufacturer) = &self.manufacturer {
118            args.push(format!("manufacturer={}", manufacturer));
119        }
120        if let Some(product) = &self.product {
121            args.push(format!("product={}", product));
122        }
123        if let Some(version) = &self.version {
124            args.push(format!("version={}", version));
125        }
126        if let Some(serial) = &self.serial {
127            args.push(format!("serial={}", serial));
128        }
129        if let Some(asset) = &self.asset {
130            args.push(format!("asset={}", asset));
131        }
132        if let Some(location) = &self.location {
133            args.push(format!("location={}", location));
134        }
135        cmd.push(args.join(","));
136        cmd
137    }
138}
139
140/// Specify SMBIOS type 3 fields
141#[derive(Default, Builder)]
142pub struct SmbiosType3 {
143    manufacturer: Option<String>,
144    version: Option<String>,
145    serial: Option<String>,
146    asset: Option<String>,
147    sku: Option<String>,
148}
149
150impl ToCommand for SmbiosType3 {
151    fn to_command(&self) -> Vec<String> {
152        let mut cmd = vec![];
153        cmd.push("-smbios".to_string());
154        let mut args = vec!["type=3".to_string()];
155        if let Some(manufacturer) = &self.manufacturer {
156            args.push(format!("manufacturer={}", manufacturer));
157        }
158        if let Some(version) = &self.version {
159            args.push(format!("version={}", version));
160        }
161        if let Some(serial) = &self.serial {
162            args.push(format!("serial={}", serial));
163        }
164        if let Some(asset) = &self.asset {
165            args.push(format!("asset={}", asset));
166        }
167        if let Some(sku) = &self.sku {
168            args.push(format!("sku={}", sku));
169        }
170        cmd.push(args.join(","));
171        cmd
172    }
173}
174/// Specify SMBIOS type 4 fields
175#[derive(Default, Builder)]
176pub struct SmbiosType4 {
177    sock_pfx: Option<String>,
178    manufacturer: Option<String>,
179    version: Option<String>,
180    serial: Option<String>,
181    asset: Option<String>,
182    part: Option<String>,
183    max_speed: Option<usize>,
184    current_speed: Option<usize>,
185    processor_family: Option<usize>,
186    processor_id: Option<usize>,
187}
188
189impl ToCommand for SmbiosType4 {
190    fn to_command(&self) -> Vec<String> {
191        let mut cmd = vec![];
192        cmd.push("-smbios".to_string());
193        let mut args = vec!["type=4".to_string()];
194        if let Some(sock_pfx) = &self.sock_pfx {
195            args.push(format!("sock_pfx={}", sock_pfx));
196        }
197        if let Some(manufacturer) = &self.manufacturer {
198            args.push(format!("manufacturer={}", manufacturer));
199        }
200        if let Some(version) = &self.version {
201            args.push(format!("version={}", version));
202        }
203        if let Some(serial) = &self.serial {
204            args.push(format!("serial={}", serial));
205        }
206        if let Some(asset) = &self.asset {
207            args.push(format!("asset={}", asset));
208        }
209        if let Some(part) = &self.part {
210            args.push(format!("part={}", part));
211        }
212        if let Some(max_speed) = &self.max_speed {
213            args.push(format!("max-speed={}", max_speed));
214        }
215        if let Some(current_speed) = &self.current_speed {
216            args.push(format!("current-speed={}", current_speed));
217        }
218        if let Some(processor_family) = &self.processor_family {
219            args.push(format!("processor-family={}", processor_family));
220        }
221        if let Some(processor_id) = &self.processor_id {
222            args.push(format!("processor-id={}", processor_id));
223        }
224        cmd.push(args.join(","));
225        cmd
226    }
227}
228
229/// Specify SMBIOS type 8 fields
230#[derive(Default, Builder)]
231pub struct SmbiosType8 {
232    external_reference: Option<String>,
233    internal_reference: Option<String>,
234    connector_type: Option<usize>,
235    port_type: Option<usize>,
236}
237
238impl ToCommand for SmbiosType8 {
239    fn to_command(&self) -> Vec<String> {
240        let mut cmd = vec![];
241        cmd.push("-smbios".to_string());
242        let mut args = vec!["type=8".to_string()];
243        if let Some(external_reference) = &self.external_reference {
244            args.push(format!("external_reference={}", external_reference));
245        }
246        if let Some(internal_reference) = &self.internal_reference {
247            args.push(format!("internal_reference={}", internal_reference));
248        }
249        if let Some(connector_type) = &self.connector_type {
250            args.push(format!("connector_type={}", connector_type));
251        }
252        if let Some(port_type) = &self.port_type {
253            args.push(format!("port_type={}", port_type));
254        }
255        cmd.push(args.join(","));
256        cmd
257    }
258}
259
260/// Specify SMBIOS type 11 fields
261#[derive(Default, Builder)]
262pub struct SmbiosType11 {
263    value: Option<String>,
264    path: Option<String>,
265}
266
267impl ToCommand for SmbiosType11 {
268    fn to_command(&self) -> Vec<String> {
269        let mut cmd = vec![];
270        cmd.push("-smbios".to_string());
271        let mut args = vec!["type=11".to_string()];
272        if let Some(value) = &self.value {
273            args.push(format!("value={}", value));
274        }
275        if let Some(path) = &self.path {
276            args.push(format!("path={}", path));
277        }
278        cmd.push(args.join(","));
279        cmd
280    }
281}
282
283/// Specify SMBIOS type 17 fields
284#[derive(Default, Builder)]
285pub struct SmbiosType17 {
286    loc_pfx: Option<String>,
287    bank: Option<String>,
288    manufacturer: Option<String>,
289    serial: Option<String>,
290    asset: Option<String>,
291    part: Option<String>,
292    speed: Option<usize>,
293}
294
295impl ToCommand for SmbiosType17 {
296    fn to_command(&self) -> Vec<String> {
297        let mut cmd = vec![];
298        cmd.push("-smbios".to_string());
299        let mut args = vec!["type=17".to_string()];
300
301        if let Some(loc_pfx) = &self.loc_pfx {
302            args.push(format!("loc_pfx={}", loc_pfx));
303        }
304        if let Some(bank) = &self.bank {
305            args.push(format!("bank={}", bank));
306        }
307        if let Some(manufacturer) = &self.manufacturer {
308            args.push(format!("manufacturer={}", manufacturer));
309        }
310        if let Some(serial) = &self.serial {
311            args.push(format!("serial={}", serial));
312        }
313        if let Some(asset) = &self.asset {
314            args.push(format!("asset={}", asset));
315        }
316        if let Some(part) = &self.part {
317            args.push(format!("part={}", part));
318        }
319        if let Some(speed) = &self.speed {
320            args.push(format!("speed={}", speed));
321        }
322        cmd.push(args.join(","));
323        cmd
324    }
325}
326
327/// Specify SMBIOS type 41 fields
328#[derive(Default, Builder)]
329pub struct SmbiosType41 {
330    designation: Option<String>,
331    kind: Option<String>,
332    instance: Option<usize>,
333    pcidev: Option<String>,
334}
335
336impl ToCommand for SmbiosType41 {
337    fn to_command(&self) -> Vec<String> {
338        let mut cmd = vec![];
339        cmd.push("-smbios".to_string());
340        let mut args = vec!["type=41".to_string()];
341
342        if let Some(designation) = &self.designation {
343            args.push(format!("designation={}", designation));
344        }
345        if let Some(kind) = &self.kind {
346            args.push(format!("kind={}", kind));
347        }
348        if let Some(instance) = self.instance {
349            args.push(format!("instance={}", instance));
350        }
351        if let Some(pcidev) = &self.pcidev {
352            args.push(format!("pcidev={}", pcidev));
353        }
354        cmd.push(args.join(","));
355        cmd
356    }
357}
358
359pub enum Smbios {
360    File(SmbiosFile),
361    Type0(SmbiosType0),
362    Type1(SmbiosType1),
363    Type2(SmbiosType2),
364    Type3(SmbiosType3),
365    Type4(SmbiosType4),
366    Type8(SmbiosType8),
367    Type11(SmbiosType11),
368    Type41(SmbiosType41),
369}
370
371impl ToCommand for Smbios {
372    fn to_command(&self) -> Vec<String> {
373        let mut cmd = vec![];
374        match self {
375            Smbios::File(file) => {
376                cmd.append(file.to_command().as_mut());
377            }
378            Smbios::Type0(type0) => {
379                cmd.append(type0.to_command().as_mut());
380            }
381            Smbios::Type1(type1) => {
382                cmd.append(type1.to_command().as_mut());
383            }
384            Smbios::Type2(type2) => {
385                cmd.append(type2.to_command().as_mut());
386            }
387            Smbios::Type3(type3) => {
388                cmd.append(type3.to_command().as_mut());
389            }
390            Smbios::Type4(type4) => {
391                cmd.append(type4.to_command().as_mut());
392            }
393            Smbios::Type8(type8) => {
394                cmd.append(type8.to_command().as_mut());
395            }
396            Smbios::Type11(type11) => {
397                cmd.append(type11.to_command().as_mut());
398            }
399            Smbios::Type41(type41) => {
400                cmd.append(type41.to_command().as_mut());
401            }
402        }
403        cmd
404    }
405}