1pub trait MkArg<'a> {
6 fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String>;
7}
8
9impl<'a> MkArg<'a> for bool {
10 fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
11 if *self {
12 args.push(option);
13 }
14 None
15 }
16}
17
18impl<'a, T: std::string::ToString> MkArg<'a> for Option<T> {
19 fn mk(&self, _option: &'a str, _args: &mut Vec<&'a str>) -> Option<String> {
20 if let Some(x) = self {
21 Some(x.to_string())
22 } else {
23 None
24 }
25 }
26}
27
28impl<'a> MkArg<'a> for u32 {
29 fn mk(&self, _option: &'a str, _args: &mut Vec<&'a str>) -> Option<String> {
30 Some(self.to_string())
31 }
32}
33
34impl<'a> MkArg<'a> for &'a [&'a str] {
35 fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
36 for v in *self {
37 if !v.is_empty() {
38 args.push(option);
39 args.push(&v);
40 }
41 }
42 None
43 }
44}
45
46impl<'a> MkArg<'a> for &'a str {
47 fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
48 if !self.is_empty() {
49 args.push(option);
50 args.push(self);
51 }
52 None
53 }
54}
55
56macro_rules! fn_array {
57 ($N: expr) => {
58 impl<'a> MkArg<'a> for &'a [&'a str; $N] {
59 fn mk(&self, option: &'a str, args: &mut Vec<&'a str>) -> Option<String> {
60 for v in *self {
61 if !v.is_empty() {
62 args.push(option);
63 args.push(&v);
64 }
65 }
66 None
67 }
68 }
69 };
70}
71
72fn_array!(1);
74fn_array!(2);
75fn_array!(3);
76fn_array!(4);
77fn_array!(5);
78fn_array!(6);
79fn_array!(7);
80fn_array!(8);
81fn_array!(9);
82fn_array!(10);
83fn_array!(11);
84fn_array!(12);
85fn_array!(13);
86fn_array!(14);
87fn_array!(15);
88fn_array!(16);
89
90#[macro_export]
91macro_rules! debug_vec {
92 ($v: expr) => {{
93 let tmp: Vec<char> = $v.iter().map(|x| *x as char).collect();
94 println!("DEBUG {}: {:?}", stringify!($v), tmp);
95 }};
96}
97
98#[macro_export]
99macro_rules! hg {
100 ($client: expr, $com: ident $(, $a: ident = $v: expr)* ) => {{
101 #![allow(clippy::needless_update)]
102 $client.$com($com::Arg {
103 $(
104 $a: $v,
105 )*
106 ..Default::default()
107 })
108 }}
109}
110
111#[macro_export]
112macro_rules! HG {
113 ($client: ident $(, $a: ident = $v: expr)* ) => {{
114 #![allow(clippy::needless_update)]
115 $client::Arg {
116 $(
117 $a: $v,
118 )*
119 ..Default::default()
120 }.run(&mut Basic { })
121 }}
122}
123
124#[macro_export]
125macro_rules! runcommand {
126 ( $client: expr, $name: expr, $args: expr $(, $o: expr, $x: expr )* ) => {{
127 let mut tmp = Vec::new();
128 tmp.push($name);
129 $(
130 let v = if let Some(s) = $x.mk($o, &mut tmp) {
131 s
132 } else {
133 String::new()
134 };
135 if !v.is_empty() {
136 tmp.push($o);
137 tmp.push(&v);
138 }
139 )*
140 if !$args.is_empty() {
141 tmp.push("--");
142 for arg in $args {
143 if !arg.is_empty() {
144 tmp.push(arg);
145 }
146 }
147 }
148 $client.runcommand(&tmp, None)
149 }};
150}
151
152#[macro_export]
153macro_rules! runcommand_with_prompt {
154 ( $client: expr, $name: expr, $prompt: expr, $args: expr $(, $o: expr, $x: expr )* ) => {{
155 let mut tmp = Vec::new();
156 tmp.push($name);
157 $(
158 let v = if let Some(s) = $x.mk($o, &mut tmp) {
159 s
160 } else {
161 String::new()
162 };
163 if !v.is_empty() {
164 tmp.push($o);
165 tmp.push(&v);
166 }
167 )*
168 if !$args.is_empty() {
169 for arg in $args {
170 if !arg.is_empty() {
171 tmp.push(arg);
172 }
173 }
174 }
175 $client.runcommand(&tmp, Some(Box::new($prompt)))
176 }};
177}