qemu_command_builder/
to_command.rs1use std::fmt::Debug;
2use std::hash::Hash;
3use std::str::FromStr;
4
5fn shell_escape_arg(arg: &str) -> String {
6 if !arg.is_empty() && arg.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | '.' | '/' | ':' | ',' | '=' | '+')) {
7 return arg.to_string();
8 }
9
10 let escaped = arg.replace('\'', r#"'\''"#);
11 format!("'{}'", escaped)
12}
13
14pub trait ToCommand: Debug + Clone + Hash + Ord + PartialOrd + Eq + PartialEq + FromStr {
15 fn has_args(&self) -> bool {
16 true
17 }
18
19 fn command(&self) -> String {
21 String::new()
22 }
23
24 fn to_args(&self) -> Vec<String>;
26
27 fn to_command(&self) -> Vec<String> {
29 if self.has_args() {
30 let mut cmd = vec![self.command()];
31 cmd.append(&mut self.to_args());
32 cmd
33 } else {
34 vec![]
35 }
36 }
37
38 fn to_single_command(&self) -> String {
40 self.to_command().iter().map(|arg| shell_escape_arg(arg)).collect::<Vec<_>>().join(" ")
41 }
42
43 fn to_single_arg(&self) -> String {
45 self.to_args().iter().map(|arg| shell_escape_arg(arg)).collect::<Vec<_>>().join(" ")
46 }
47}
48
49pub trait ToArg {
50 fn to_arg(&self) -> &str;
51}
52
53#[macro_export]
55macro_rules! qao {
56 ($a:expr,$b:expr,$c:expr) => {{
57 if let Some(val) = $a {
58 $b.push(format!("{}{}", $c, val));
59 }
60 }};
61}
62
63#[macro_export]
65macro_rules! qaoo {
66 ($a:expr,$b:expr,$c:expr) => {
67 if let Some(val) = $a {
68 match val.clone().into_string() {
69 Ok(str) => $b.push(format!("{}{}", $c, str)),
70 Err(x) => panic!("can't convert {:?} to a string", x),
71 }
72 }
73 };
74}
75
76#[macro_export]
78macro_rules! qaop {
79 ($a:expr,$b:expr,$c:expr) => {{
80 if let Some(val) = $a {
81 $b.push(format!("{}{}", $c, val.display()));
82 }
83 }};
84}
85
86#[macro_export]
88macro_rules! pco {
89 ($a:ident,$b:expr,$c:ty,$d:expr) => {
90 fn $a(s: &mut &str) -> ModalResult<$c> {
91 let _ = literal(DELIM_COMMA).parse_next(s)?;
92 let _ = literal($d).parse_next(s)?;
93 let parsed = $b.parse_to::<$c>().parse_next(s)?;
94 Ok(parsed)
95 }
96 };
97}
98#[macro_export]
100macro_rules! pco0 {
101 ($a:ident,$b:expr,$c:ty,$d:expr) => {
102 fn $a(s: &mut &str) -> ModalResult<$c> {
103 let _ = opt(literal(DELIM_COMMA)).parse_next(s)?;
104 let _ = literal($d).parse_next(s)?;
105 let parsed = $b.parse_to::<$c>().parse_next(s)?;
106 Ok(parsed)
107 }
108 };
109}
110#[macro_export]
112macro_rules! ppo {
113 ($a:ident,$b:expr,$c:ty,$d:expr) => {
114 fn $a(s: &mut &str) -> ModalResult<$c> {
115 let _ = literal(DELIM_COMMA).parse_next(s)?;
116 let _ = literal($d).parse_next(s)?;
117 let parsed = $b.parse_next(s)?;
118 Ok(parsed)
119 }
120 };
121}
122
123#[macro_export]
125macro_rules! ppo0 {
126 ($a:ident,$b:expr,$c:ty,$d:expr) => {
127 fn $a(s: &mut &str) -> ModalResult<$c> {
128 let _ = opt(literal(DELIM_COMMA)).parse_next(s)?;
129 let _ = literal($d).parse_next(s)?;
130 let parsed = $b.parse_next(s)?;
131 Ok(parsed)
132 }
133 };
134}
135
136#[macro_export]
138macro_rules! pso {
139 ($a:ident,$b:expr) => {
140 fn $a(s: &mut &str) -> ModalResult<ShellString> {
141 let _ = literal(DELIM_COMMA).parse_next(s)?;
142 let _ = literal($b).parse_next(s)?;
143 let parsed = ascii_plus_more.parse_next(s)?;
144 Ok(ShellString { s: parsed.to_string() })
145 }
146 };
147}
148
149#[macro_export]
151macro_rules! pso0 {
152 ($a:ident,$b:expr) => {
153 fn $a(s: &mut &str) -> ModalResult<ShellString> {
154 let _ = opt(literal(DELIM_COMMA)).parse_next(s)?;
155 let _ = literal($b).parse_next(s)?;
156 let parsed = ascii_plus_more.parse_next(s)?;
157 Ok(ShellString { s: parsed.to_string() })
158 }
159 };
160}