Skip to main content

qemu_command_builder/
lib.rs

1#![recursion_limit = "256"]
2
3pub mod args;
4pub mod common;
5pub mod parser;
6pub mod parsers;
7pub mod shell_path;
8pub mod shell_string;
9pub mod to_command;
10
11use std::path::PathBuf;
12use std::str::FromStr;
13
14use bon::Builder;
15use chrono::{DateTime, TimeZone, Utc};
16use newtype_uuid::{TypedUuidKind, TypedUuidTag};
17use proptest::prelude::{Arbitrary, Just};
18use proptest_derive::Arbitrary;
19
20use crate::args::accel::Accel;
21use crate::args::acpitable::AcpiTable;
22use crate::args::action::{Action, WatchdogAction};
23use crate::args::addfs::AddFd;
24use crate::args::audio::Audio;
25use crate::args::audiodev::AudioDev;
26use crate::args::blockdev::BlockDev;
27use crate::args::boot::Boot;
28use crate::args::chardev::CharDev;
29use crate::args::compact::Compact;
30use crate::args::cpu::{CpuAarch64, CpuX86};
31use crate::args::device::Device;
32use crate::args::display::QemuDisplay;
33use crate::args::drive::Drive;
34use crate::args::fsdev::FsDev;
35use crate::args::fw_cfg::FwCfg;
36use crate::args::g::G;
37use crate::args::global::Global;
38use crate::args::icount::Icount;
39use crate::args::incoming::Incoming;
40use crate::args::iscsi::Iscsi;
41use crate::args::machine::{MachineAarch64, MachineX86_64};
42use crate::args::memory::Memory;
43use crate::args::mon::Mon;
44use crate::args::msg::Msg;
45use crate::args::name::Name;
46use crate::args::netdev::NetDev;
47use crate::args::numa::NUMA;
48use crate::args::object::Object;
49use crate::args::overcommit::Overcommit;
50use crate::args::plugin::Plugin;
51use crate::args::rtc::Rtc;
52use crate::args::runwith::RunWith;
53use crate::args::sandbox::Sandbox;
54use crate::args::serial::SpecialDevice;
55use crate::args::set::Set;
56use crate::args::smbios::Smbios;
57use crate::args::smp::SMP;
58use crate::args::spice::Spice;
59use crate::args::tpmdev::TpmDev;
60use crate::args::trace::Trace;
61use crate::args::usb::USBDevice;
62use crate::args::vga::VGA;
63use crate::args::virtfs::Virtfs;
64use crate::args::vnc::VNC;
65use crate::parsers::{
66    ARG_APPEND, ARG_BIG_D, ARG_BIG_S, ARG_BIOS, ARG_CDROM, ARG_DAEMONIZE, ARG_DEBUGCON, ARG_DFILTER, ARG_DTB, ARG_DUMP_VMSTATE, ARG_ECHR, ARG_ENABLE_KVM, ARG_ENABLE_SYNC_PROFILE, ARG_FDA, ARG_FDB,
67    ARG_FULL_SCREEN, ARG_GDB, ARG_HDA, ARG_HDB, ARG_HDC, ARG_HDD, ARG_INITRD, ARG_JITDUMP, ARG_K, ARG_KERNEL, ARG_L, ARG_LITTLE_D, ARG_LITTLE_S, ARG_LOADVM, ARG_MEM_PATH, ARG_MEM_PREALLOC,
68    ARG_MONITOR, ARG_MTDBLOCK, ARG_NO_FD_BOOTCHK, ARG_NO_REBOOT, ARG_NO_SHUTDOWN, ARG_NO_USER_CONFIG, ARG_NODEFAULTS, ARG_NOGRAPHIC, ARG_ONLY_MIGRATABLE, ARG_OPTION_ROM, ARG_PARALLEL, ARG_PERFMAP,
69    ARG_PFLASH, ARG_PIDFILE, ARG_PRECONFIG, ARG_QMP, ARG_QMP_PRETTY, ARG_READCONFIG, ARG_SD, ARG_SEED, ARG_SERIAL, ARG_SHIM, ARG_SNAPSHOT, ARG_USB, ARG_UUID, ARG_WIN2K_HACK, ARG_XEN_ATTACH,
70    ARG_XEN_DOMID_RESTRICT, ARG_XEN_ID, DELIM_COMMA,
71};
72use crate::shell_string::ShellString;
73use crate::to_command::{ToArg, ToCommand};
74
75/// QEMU binary name for x86_64
76const QEMU_BIN_X86_64: &str = "qemu-system-x86_64";
77
78/// QEMU binary name for aarch64
79const QEMU_BIN_AARCH64: &str = "qemu-system-aarch64";
80
81#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder, Arbitrary)]
82pub struct QemuInstanceBase<Machine, Cpu> {
83    pub qemu_binary: PathBuf,
84
85    pub machine: Option<Machine>,
86    pub cpu: Option<Cpu>,
87
88    pub accel: Option<Accel>,
89    pub smp: Option<SMP>,
90    pub numa: Option<Vec<NUMA>>,
91    pub add_fd: Option<AddFd>,
92    pub set: Option<Vec<Set>>,
93    pub global: Option<Vec<Global>>,
94    pub boot: Option<Boot>,
95    pub m: Option<Memory>,
96    pub mem_path: Option<PathBuf>,
97    pub mem_prealloc: Option<bool>,
98    pub k: Option<String>,
99    pub audio: Option<Audio>,
100    pub audiodev: Option<AudioDev>,
101    pub device: Option<Vec<Device>>,
102    pub name: Option<Name>,
103    pub uuid: Option<newtype_uuid::TypedUuid<QUuid>>,
104    pub fda: Option<PathBuf>,
105    pub fdb: Option<PathBuf>,
106    pub hda: Option<PathBuf>,
107    pub hdb: Option<PathBuf>,
108    pub hdc: Option<PathBuf>,
109    pub hdd: Option<PathBuf>,
110    pub cdrom: Option<PathBuf>,
111    pub blockdev: Option<Vec<BlockDev>>,
112    pub drive: Option<Vec<Drive>>,
113    pub mdtblock: Option<PathBuf>,
114    pub sd: Option<PathBuf>,
115    pub snapshot: Option<bool>,
116    pub fsdev: Option<FsDev>,
117    pub virtfs: Option<Virtfs>,
118    pub iscsi: Option<Iscsi>,
119    pub usb: Option<bool>,
120    pub usbdevice: Option<USBDevice>,
121    pub display: Option<QemuDisplay>,
122    pub nographic: Option<bool>,
123    pub spice: Option<Spice>,
124    pub vga: Option<VGA>,
125    pub full_screen: Option<bool>,
126    pub g: Option<G>,
127    pub vnc: Option<VNC>,
128    pub win2k_hack: Option<bool>,
129    pub no_fd_bootchk: Option<bool>,
130    pub acpitable: Option<AcpiTable>,
131    pub smbios: Option<Vec<Smbios>>,
132    pub netdev: Option<Vec<NetDev>>,
133    pub chardev: Option<Vec<CharDev>>,
134    pub tpmdev: Option<TpmDev>,
135    pub bios: Option<PathBuf>,
136    pub pflash: Option<PathBuf>,
137    pub kernel: Option<PathBuf>,
138    pub shim: Option<PathBuf>,
139    pub append: Option<ShellString>,
140    pub initrd: Option<PathBuf>,
141    pub dtb: Option<PathBuf>,
142    pub compact: Option<Compact>,
143    pub fw_cfg: Option<FwCfg>,
144    pub serial: Option<SpecialDevice>,
145    pub parallel: Option<Vec<SpecialDevice>>,
146    pub monitor: Option<SpecialDevice>,
147    pub qmp: Option<SpecialDevice>,
148    pub qmp_pretty: Option<SpecialDevice>,
149    pub mon: Option<Vec<Mon>>,
150    pub debugcon: Option<CharDev>,
151    pub pidfile: Option<PathBuf>,
152    pub preconfig: Option<bool>,
153    pub big_s: Option<bool>,
154    pub overcommit: Option<Overcommit>,
155    pub gdb: Option<SpecialDevice>,
156    pub s: Option<bool>,
157    pub d: Option<Vec<String>>,
158    pub big_d: Option<PathBuf>,
159    pub dfilter: Option<Vec<String>>,
160    pub seed: Option<usize>,
161    pub big_l: Option<PathBuf>,
162    pub enable_kvm: Option<bool>,
163    pub xen_id: Option<String>,
164    pub xen_attach: Option<bool>,
165    pub xen_domid_restrict: Option<bool>,
166    pub no_reboot: Option<bool>,
167    pub no_shutdown: Option<bool>,
168    pub action: Option<Action>,
169    pub loadvm: Option<String>,
170    pub daemonize: Option<bool>,
171    pub option_rom: Option<PathBuf>,
172    pub rtc: Option<Rtc>,
173    pub icount: Option<Icount>,
174    pub watchdog_action: Option<WatchdogAction>,
175    pub echr: Option<String>,
176    pub incoming: Option<Vec<Incoming>>,
177    pub only_migratable: Option<bool>,
178    pub nodefaults: Option<bool>,
179    pub sandbox: Option<Sandbox>,
180    pub readconfig: Option<PathBuf>,
181    pub no_user_config: Option<bool>,
182    pub trace: Option<Trace>,
183    pub plugin: Option<Plugin>,
184    pub run_with: Option<RunWith>,
185    // compat w/ qemu 7.x+
186    pub runas: Option<String>,
187    // compat w/ qemu 7.x+
188    pub chroot: Option<PathBuf>,
189    pub msg: Option<Msg>,
190    pub dump_vmstate: Option<PathBuf>,
191    pub enable_sync_profile: Option<bool>,
192    pub perfmap: Option<PathBuf>,
193    pub jitdump: Option<PathBuf>,
194    pub object: Option<Vec<Object>>,
195}
196
197impl<Machine: ToCommand, Cpu: ToCommand> ToCommand for QemuInstanceBase<Machine, Cpu>
198where
199    QemuInstanceBase<Machine, Cpu>: FromStr,
200{
201    fn command(&self) -> String {
202        self.qemu_binary.display().to_string()
203    }
204
205    fn to_args(&self) -> Vec<String> {
206        let mut cmd = vec![];
207
208        if let Some(machine) = &self.machine {
209            cmd.append(&mut machine.to_command());
210        }
211        if let Some(cpu) = &self.cpu {
212            cmd.append(&mut cpu.to_command());
213        }
214        if let Some(accel) = &self.accel {
215            cmd.append(&mut accel.to_command());
216        }
217        if let Some(smp) = &self.smp {
218            cmd.append(&mut smp.to_command());
219        }
220        if let Some(numas) = &self.numa {
221            for numa in numas {
222                cmd.append(&mut numa.to_command());
223            }
224        }
225        if let Some(add_fd) = &self.add_fd {
226            cmd.append(&mut add_fd.to_command());
227        }
228        if let Some(sets) = &self.set {
229            for set in sets {
230                cmd.append(&mut set.to_command());
231            }
232        }
233        if let Some(globals) = &self.global {
234            for global in globals {
235                cmd.append(&mut global.to_command());
236            }
237        }
238        if let Some(boot) = &self.boot {
239            cmd.append(&mut boot.to_command());
240        }
241        if let Some(m) = &self.m {
242            cmd.append(&mut m.to_command());
243        }
244        if let Some(path) = &self.mem_path {
245            cmd.push(ARG_MEM_PATH.to_string());
246            cmd.push(path.display().to_string());
247        }
248        if let Some(state) = self.mem_prealloc
249            && state
250        {
251            cmd.push(ARG_MEM_PREALLOC.to_string());
252        }
253        if let Some(lang) = &self.k {
254            cmd.push(ARG_K.to_string());
255            cmd.push(lang.to_string());
256        }
257        if let Some(audio) = &self.audio {
258            cmd.append(&mut audio.to_command());
259        }
260        if let Some(audiodev) = &self.audiodev {
261            cmd.append(&mut audiodev.to_command());
262        }
263        if let Some(devices) = &self.device {
264            for device in devices {
265                cmd.append(&mut device.to_command());
266            }
267        }
268        if let Some(name) = &self.name {
269            cmd.append(&mut name.to_command());
270        }
271        if let Some(uuid) = &self.uuid {
272            cmd.push(ARG_UUID.to_string());
273            cmd.push(uuid.to_string());
274        }
275        if let Some(fda) = &self.fda {
276            cmd.push(ARG_FDA.to_string());
277            cmd.push(fda.display().to_string());
278        }
279        if let Some(fdb) = &self.fdb {
280            cmd.push(ARG_FDB.to_string());
281            cmd.push(fdb.display().to_string());
282        }
283        if let Some(hda) = &self.hda {
284            cmd.push(ARG_HDA.to_string());
285            cmd.push(hda.display().to_string());
286        }
287        if let Some(hdb) = &self.hdb {
288            cmd.push(ARG_HDB.to_string());
289            cmd.push(hdb.display().to_string());
290        }
291        if let Some(hdc) = &self.hdc {
292            cmd.push(ARG_HDC.to_string());
293            cmd.push(hdc.display().to_string());
294        }
295        if let Some(hdd) = &self.hdd {
296            cmd.push(ARG_HDD.to_string());
297            cmd.push(hdd.display().to_string());
298        }
299        if let Some(cdrom) = &self.cdrom {
300            cmd.push(ARG_CDROM.to_string());
301            cmd.push(cdrom.display().to_string());
302        }
303        if let Some(blockdevs) = &self.blockdev {
304            for blockdev in blockdevs {
305                cmd.append(&mut blockdev.to_command());
306            }
307        }
308        if let Some(drives) = &self.drive {
309            for drive in drives {
310                cmd.append(&mut drive.to_command());
311            }
312        }
313        if let Some(mdtblock) = &self.mdtblock {
314            cmd.push(ARG_MTDBLOCK.to_string());
315            cmd.push(mdtblock.display().to_string());
316        }
317        if let Some(sd) = &self.sd {
318            cmd.push(ARG_SD.to_string());
319            cmd.push(sd.display().to_string());
320        }
321        if let Some(state) = &self.snapshot
322            && *state
323        {
324            cmd.push(ARG_SNAPSHOT.to_string());
325        }
326        if let Some(fsdev) = &self.fsdev {
327            cmd.append(&mut fsdev.to_command());
328        }
329        if let Some(virtfs) = &self.virtfs {
330            cmd.append(&mut virtfs.to_command());
331        }
332        if let Some(iscsi) = &self.iscsi {
333            cmd.append(&mut iscsi.to_command());
334        }
335        if let Some(state) = &self.usb
336            && *state
337        {
338            cmd.push(ARG_USB.to_string());
339        }
340        if let Some(usbdevice) = &self.usbdevice {
341            cmd.append(&mut usbdevice.to_command());
342        }
343        if let Some(display) = &self.display {
344            cmd.append(&mut display.to_command());
345        }
346        if let Some(state) = &self.nographic
347            && *state
348        {
349            cmd.push(ARG_NOGRAPHIC.to_string());
350        }
351        if let Some(spice) = &self.spice {
352            cmd.append(&mut spice.to_command());
353        }
354        if let Some(vga) = &self.vga {
355            cmd.append(&mut vga.to_command());
356        }
357        if let Some(full_screen) = &self.full_screen
358            && *full_screen
359        {
360            cmd.push(ARG_FULL_SCREEN.to_string());
361        }
362        if let Some(g) = &self.g {
363            cmd.append(&mut g.to_command());
364        }
365        if let Some(vnc) = &self.vnc {
366            cmd.append(&mut vnc.to_command());
367        }
368        if let Some(win2k_hack) = &self.win2k_hack
369            && *win2k_hack
370        {
371            cmd.push(ARG_WIN2K_HACK.to_string());
372        }
373        if let Some(no_fd_bootchk) = &self.no_fd_bootchk
374            && *no_fd_bootchk
375        {
376            cmd.push(ARG_NO_FD_BOOTCHK.to_string());
377        }
378        if let Some(acpitable) = &self.acpitable {
379            cmd.append(&mut acpitable.to_command());
380        }
381        if let Some(smbioss) = &self.smbios {
382            for smbios in smbioss {
383                cmd.append(&mut smbios.to_command());
384            }
385        }
386        if let Some(netdevs) = &self.netdev {
387            for netdev in netdevs {
388                cmd.append(&mut netdev.to_command());
389            }
390        }
391        if let Some(chardevs) = &self.chardev {
392            for chardev in chardevs {
393                cmd.append(&mut chardev.to_command());
394            }
395        }
396        if let Some(tpmdev) = &self.tpmdev {
397            cmd.append(&mut tpmdev.to_command());
398        }
399        if let Some(bios) = &self.bios {
400            cmd.push(ARG_BIOS.to_string());
401            cmd.push(bios.display().to_string());
402        }
403        if let Some(pflash) = &self.pflash {
404            cmd.push(ARG_PFLASH.to_string());
405            cmd.push(pflash.display().to_string());
406        }
407        if let Some(kernel) = &self.kernel {
408            cmd.push(ARG_KERNEL.to_string());
409            cmd.push(kernel.display().to_string());
410        }
411        if let Some(shim) = &self.shim {
412            cmd.push(ARG_SHIM.to_string());
413            cmd.push(shim.display().to_string());
414        }
415        if let Some(append) = &self.append {
416            cmd.push(ARG_APPEND.to_string());
417            cmd.push(append.as_ref().to_string());
418        }
419        if let Some(initrd) = &self.initrd {
420            cmd.push(ARG_INITRD.to_string());
421            cmd.push(initrd.display().to_string());
422        }
423        if let Some(dtb) = &self.dtb {
424            cmd.push(ARG_DTB.to_string());
425            cmd.push(dtb.display().to_string());
426        }
427        if let Some(compact) = &self.compact {
428            cmd.append(&mut compact.to_command());
429        }
430        if let Some(fw_cfg) = &self.fw_cfg {
431            cmd.append(&mut fw_cfg.to_command());
432        }
433        if let Some(serial) = &self.serial {
434            cmd.push(ARG_SERIAL.to_string());
435            cmd.append(&mut serial.to_args());
436        }
437        if let Some(parallels) = &self.parallel {
438            for parallel in parallels {
439                cmd.push(ARG_PARALLEL.to_string());
440                cmd.append(&mut parallel.to_args());
441            }
442        }
443        if let Some(monitor) = &self.monitor {
444            cmd.push(ARG_MONITOR.to_string());
445            cmd.append(&mut monitor.to_command());
446        }
447        if let Some(qmp) = &self.qmp {
448            cmd.push(ARG_QMP.to_string());
449            cmd.append(&mut qmp.to_command());
450        }
451        if let Some(qmp_pretty) = &self.qmp_pretty {
452            cmd.push(ARG_QMP_PRETTY.to_string());
453            cmd.append(&mut qmp_pretty.to_command());
454        }
455        if let Some(mons) = &self.mon {
456            for mon in mons {
457                cmd.append(&mut mon.to_command());
458            }
459        }
460        if let Some(debugcon) = &self.debugcon {
461            cmd.push(ARG_DEBUGCON.to_string());
462            cmd.append(&mut debugcon.to_command());
463        }
464        if let Some(pidfile) = &self.pidfile {
465            cmd.push(ARG_PIDFILE.to_string());
466            cmd.push(pidfile.display().to_string());
467        }
468        if let Some(preconfig) = &self.preconfig
469            && *preconfig
470        {
471            cmd.push(ARG_PRECONFIG.to_string());
472        }
473        if let Some(s) = &self.big_s
474            && *s
475        {
476            cmd.push(ARG_BIG_S.to_string());
477        }
478        if let Some(overcommit) = &self.overcommit {
479            cmd.append(&mut overcommit.to_command());
480        }
481        if let Some(gdb) = &self.gdb {
482            cmd.push(ARG_GDB.to_string());
483            cmd.append(&mut gdb.to_command());
484        }
485        if let Some(s) = &self.s
486            && *s
487        {
488            cmd.push(ARG_LITTLE_S.to_string());
489        }
490        if let Some(d) = &self.d {
491            cmd.push(ARG_LITTLE_D.to_string());
492            cmd.push(d.join(DELIM_COMMA));
493        }
494        if let Some(big_d) = &self.big_d {
495            cmd.push(ARG_BIG_D.to_string());
496            cmd.push(big_d.display().to_string());
497        }
498        if let Some(dfilter) = &self.dfilter {
499            cmd.push(ARG_DFILTER.to_string());
500            cmd.push(dfilter.join(DELIM_COMMA));
501        }
502        if let Some(seed) = &self.seed {
503            cmd.push(ARG_SEED.to_string());
504            cmd.push(seed.to_string());
505        }
506        if let Some(l) = &self.big_l {
507            cmd.push(ARG_L.to_string());
508            cmd.push(l.display().to_string());
509        }
510        if let Some(enable_kvm) = &self.enable_kvm
511            && *enable_kvm
512        {
513            cmd.push(ARG_ENABLE_KVM.to_string());
514        }
515        if let Some(xen_id) = &self.xen_id {
516            cmd.push(ARG_XEN_ID.to_string());
517            cmd.push(xen_id.to_string());
518        }
519        if let Some(xen_attach) = &self.xen_attach
520            && *xen_attach
521        {
522            cmd.push(ARG_XEN_ATTACH.to_string());
523        }
524        if let Some(xen_domid_restrict) = &self.xen_domid_restrict
525            && *xen_domid_restrict
526        {
527            cmd.push(ARG_XEN_DOMID_RESTRICT.to_string());
528        }
529        if let Some(no_reboot) = &self.no_reboot
530            && *no_reboot
531        {
532            cmd.push(ARG_NO_REBOOT.to_string());
533        }
534        if let Some(no_shutdown) = &self.no_shutdown
535            && *no_shutdown
536        {
537            cmd.push(ARG_NO_SHUTDOWN.to_string());
538        }
539        if let Some(action) = &self.action {
540            cmd.append(&mut action.to_command());
541        }
542        if let Some(loadvm) = &self.loadvm {
543            cmd.push(ARG_LOADVM.to_string());
544            cmd.push(loadvm.to_string());
545        }
546        if let Some(daemonize) = &self.daemonize
547            && *daemonize
548        {
549            cmd.push(ARG_DAEMONIZE.to_string());
550        }
551        if let Some(option_rom) = &self.option_rom {
552            cmd.push(ARG_OPTION_ROM.to_string());
553            cmd.push(option_rom.display().to_string());
554        }
555        if let Some(rtc) = &self.rtc {
556            cmd.append(&mut rtc.to_command());
557        }
558        if let Some(icount) = &self.icount {
559            cmd.append(&mut icount.to_command());
560        }
561        if let Some(watchdog_action) = &self.watchdog_action {
562            cmd.push("-watchdog-action".to_string());
563            cmd.push(watchdog_action.to_arg().to_string());
564        }
565        if let Some(echr) = &self.echr {
566            cmd.push(ARG_ECHR.to_string());
567            cmd.push(echr.to_string());
568        }
569        if let Some(incomings) = &self.incoming {
570            for incoming in incomings {
571                cmd.append(&mut incoming.to_command());
572            }
573        }
574        if let Some(only_migratable) = &self.only_migratable
575            && *only_migratable
576        {
577            cmd.push(ARG_ONLY_MIGRATABLE.to_string());
578        }
579        if let Some(nodefaults) = &self.nodefaults
580            && *nodefaults
581        {
582            cmd.push(ARG_NODEFAULTS.to_string());
583        }
584        if let Some(sandbox) = &self.sandbox {
585            cmd.append(&mut sandbox.to_command());
586        }
587        if let Some(readconfig) = &self.readconfig {
588            cmd.push(ARG_READCONFIG.to_string());
589            cmd.push(readconfig.display().to_string());
590        }
591        if let Some(no_user_config) = &self.no_user_config
592            && *no_user_config
593        {
594            cmd.push(ARG_NO_USER_CONFIG.to_string());
595        }
596        if let Some(trace) = &self.trace {
597            cmd.append(&mut trace.to_command());
598        }
599        if let Some(plugin) = &self.plugin {
600            cmd.append(&mut plugin.to_command());
601        }
602        if let Some(run_with) = &self.run_with {
603            cmd.append(&mut run_with.to_command());
604        }
605        if let Some(runas) = &self.runas {
606            cmd.push(runas.to_string());
607        }
608        if let Some(chroot) = &self.chroot {
609            cmd.push(chroot.display().to_string());
610        }
611        if let Some(msg) = &self.msg {
612            cmd.append(&mut msg.to_command());
613        }
614        if let Some(dump_vmstate) = &self.dump_vmstate {
615            cmd.push(ARG_DUMP_VMSTATE.to_string());
616            cmd.push(dump_vmstate.display().to_string());
617        }
618        if let Some(enable_sync_profile) = &self.enable_sync_profile
619            && *enable_sync_profile
620        {
621            cmd.push(ARG_ENABLE_SYNC_PROFILE.to_string());
622        }
623        if let Some(perfmap) = &self.perfmap {
624            cmd.push(ARG_PERFMAP.to_string());
625            cmd.push(perfmap.display().to_string());
626        }
627        if let Some(jitdump) = &self.jitdump {
628            cmd.push(ARG_JITDUMP.to_string());
629            cmd.push(jitdump.display().to_string());
630        }
631        if let Some(objects) = &self.object {
632            for object in objects {
633                cmd.append(&mut object.to_command());
634            }
635        }
636        cmd
637    }
638}
639
640pub type QemuInstanceForX86_64 = QemuInstanceBase<MachineX86_64, CpuX86>;
641pub type QemuInstanceForAarch64 = QemuInstanceBase<MachineAarch64, CpuAarch64>;
642
643pub struct QUuid {}
644
645impl TypedUuidKind for QUuid {
646    fn tag() -> TypedUuidTag {
647        // Tags are required to be ASCII identifiers, with underscores
648        // and dashes also supported. The validity of a tag can be checked
649        // at compile time by assigning it to a const, like so:
650        const TAG: TypedUuidTag = TypedUuidTag::new("my_kind");
651        TAG
652    }
653}
654
655#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]
656pub struct QDateTime(DateTime<Utc>);
657
658impl Arbitrary for QDateTime {
659    type Parameters = ();
660    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
661        let dt = Utc.with_ymd_and_hms(1984, 10, 22, 0, 1, 5).unwrap();
662        Just(QDateTime(dt))
663    }
664
665    type Strategy = proptest::strategy::Just<Self>;
666}
667
668#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
669pub struct QIpv4Net {
670    ip: ipnet::Ipv4Net,
671}
672
673impl Arbitrary for QIpv4Net {
674    type Parameters = ();
675    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
676        todo!()
677    }
678
679    type Strategy = proptest::strategy::Just<Self>;
680}
681
682#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Builder)]
683pub struct QIpv6Net {
684    ip: ipnet::Ipv6Net,
685}
686
687impl Arbitrary for QIpv6Net {
688    type Parameters = ();
689    fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
690        todo!()
691    }
692
693    type Strategy = proptest::strategy::Just<Self>;
694}