qemu_command_builder/args/
trace.rs1use crate::parsers::{ARG_TRACE, DELIM_COMMA};
2use crate::to_command::ToCommand;
3use bon::Builder;
4use proptest_derive::Arbitrary;
5use std::path::PathBuf;
6use std::str::FromStr;
7
8#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Default, Builder, Arbitrary)]
10pub struct Trace {
11 enable: Option<String>,
13 events: Option<PathBuf>,
15 file: Option<PathBuf>,
17}
18
19impl ToCommand for Trace {
20 fn command(&self) -> String {
21 ARG_TRACE.to_string()
22 }
23 fn to_args(&self) -> Vec<String> {
24 let mut args = vec![];
25
26 if let Some(enable) = &self.enable {
27 args.push(format!("enable={}", enable));
28 }
29 if let Some(events) = &self.events {
30 args.push(format!("events={}", events.display()));
31 }
32 if let Some(file) = &self.file {
33 args.push(format!("file={}", file.display()));
34 }
35 vec![args.join(DELIM_COMMA)]
36 }
37}
38
39impl FromStr for Trace {
40 type Err = String;
41
42 fn from_str(s: &str) -> Result<Self, Self::Err> {
43 let mut enable = None;
44 let mut events = None;
45 let mut file = None;
46
47 let mut parts = s.split(DELIM_COMMA);
48 if let Some(first) = parts.next()
49 && !first.is_empty()
50 {
51 if let Some(value) = first.strip_prefix("enable=") {
52 enable = Some(value.to_string());
53 } else if first.contains('=') {
54 let (key, value) = first.split_once('=').ok_or_else(|| format!("invalid -trace option: {first}"))?;
55 match key {
56 "events" => events = Some(PathBuf::from(value)),
57 "file" => file = Some(PathBuf::from(value)),
58 other => return Err(format!("unsupported -trace option: {other}")),
59 }
60 } else {
61 enable = Some(first.to_string());
62 }
63 }
64
65 for part in parts {
66 if !part.contains('=') {
67 if enable.is_none() {
68 enable = Some(part.to_string());
69 continue;
70 }
71 return Err(format!("invalid -trace option: {part}"));
72 }
73
74 let (key, value) = part.split_once('=').ok_or_else(|| format!("invalid -trace option: {part}"))?;
75 match key {
76 "enable" => enable = Some(value.to_string()),
77 "events" => events = Some(PathBuf::from(value)),
78 "file" => file = Some(PathBuf::from(value)),
79 other => return Err(format!("unsupported -trace option: {other}")),
80 }
81 }
82
83 Ok(Self { enable, events, file })
84 }
85}