qemu_command_builder/args/
object.rs1use crate::parsers::{ARG_OBJECT, DELIM_COMMA};
2use crate::to_command::ToCommand;
3use bon::Builder;
4use proptest_derive::Arbitrary;
5use std::str::FromStr;
6
7#[derive(Debug, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Default, Builder, Arbitrary)]
9pub struct Object {
10 typename: String,
12 properties: Vec<(String, String)>,
14}
15
16impl Object {
17 pub fn new<S: AsRef<str>>(typename: S) -> Self {
18 Object {
19 typename: typename.as_ref().to_string(),
20 properties: Default::default(),
21 }
22 }
23 pub fn add_prop<S: AsRef<str>>(&mut self, key: S, value: S) -> &mut Self {
24 self.properties.push((key.as_ref().to_string(), value.as_ref().to_string()));
25 self
26 }
27}
28
29impl ToCommand for Object {
30 fn command(&self) -> String {
31 ARG_OBJECT.to_string()
32 }
33 fn to_args(&self) -> Vec<String> {
34 let mut args = vec![self.typename.clone()];
35
36 for (prop_key, prop_value) in &self.properties {
37 args.push(format!("{}={}", prop_key, prop_value));
38 }
39 vec![args.join(DELIM_COMMA)]
40 }
41}
42
43impl FromStr for Object {
44 type Err = String;
45
46 fn from_str(s: &str) -> Result<Self, Self::Err> {
47 let mut parts = s.split(DELIM_COMMA);
48 let typename = parts.next().ok_or_else(|| "empty -object argument".to_string())?.to_string();
49
50 let mut properties = Vec::new();
51 for part in parts {
52 let (key, value) = part.split_once('=').ok_or_else(|| format!("invalid -object property: {part}"))?;
53 properties.push((key.to_string(), value.to_string()));
54 }
55
56 Ok(Self { typename, properties })
57 }
58}