]>
Commit | Line | Data |
---|---|---|
04454e1e FG |
1 | /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case? |
2 | #[cfg(feature = "yaml")] | |
923072b8 FG |
3 | #[cfg_attr( |
4 | feature = "deprecated", | |
5 | deprecated( | |
6 | since = "3.0.0", | |
7 | note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?" | |
8 | ) | |
04454e1e FG |
9 | )] |
10 | #[doc(hidden)] | |
11 | #[macro_export] | |
12 | macro_rules! load_yaml { | |
13 | ($yaml:expr) => { | |
14 | &$crate::YamlLoader::load_from_str(include_str!($yaml)).expect("failed to load YAML file") | |
15 | [0] | |
16 | }; | |
17 | } | |
18 | ||
19 | /// Deprecated, replaced with [`ArgMatches::value_of_t`][crate::ArgMatches::value_of_t] | |
20 | #[macro_export] | |
923072b8 FG |
21 | #[cfg_attr( |
22 | feature = "deprecated", | |
23 | deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::value_of_t`") | |
24 | )] | |
04454e1e FG |
25 | #[doc(hidden)] |
26 | macro_rules! value_t { | |
27 | ($m:ident, $v:expr, $t:ty) => { | |
28 | $crate::value_t!($m.value_of($v), $t) | |
29 | }; | |
30 | ($m:ident.value_of($v:expr), $t:ty) => { | |
31 | $m.value_of_t::<$t>($v) | |
32 | }; | |
33 | } | |
34 | ||
35 | /// Deprecated, replaced with [`ArgMatches::value_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit] | |
36 | #[macro_export] | |
923072b8 FG |
37 | #[cfg_attr( |
38 | feature = "deprecated", | |
39 | deprecated( | |
40 | since = "3.0.0", | |
41 | note = "Replaced with `ArgMatches::value_of_t_or_exit`" | |
42 | ) | |
04454e1e FG |
43 | )] |
44 | #[doc(hidden)] | |
45 | macro_rules! value_t_or_exit { | |
46 | ($m:ident, $v:expr, $t:ty) => { | |
47 | value_t_or_exit!($m.value_of($v), $t) | |
48 | }; | |
49 | ($m:ident.value_of($v:expr), $t:ty) => { | |
50 | $m.value_of_t_or_exit::<$t>($v) | |
51 | }; | |
52 | } | |
53 | ||
54 | /// Deprecated, replaced with [`ArgMatches::values_of_t`][crate::ArgMatches::value_of_t] | |
55 | #[macro_export] | |
923072b8 FG |
56 | #[cfg_attr( |
57 | feature = "deprecated", | |
58 | deprecated(since = "3.0.0", note = "Replaced with `ArgMatches::values_of_t`") | |
59 | )] | |
04454e1e FG |
60 | #[doc(hidden)] |
61 | macro_rules! values_t { | |
62 | ($m:ident, $v:expr, $t:ty) => { | |
63 | values_t!($m.values_of($v), $t) | |
64 | }; | |
65 | ($m:ident.values_of($v:expr), $t:ty) => { | |
66 | $m.values_of_t::<$t>($v) | |
67 | }; | |
68 | } | |
69 | ||
70 | /// Deprecated, replaced with [`ArgMatches::values_of_t_or_exit`][crate::ArgMatches::value_of_t_or_exit] | |
71 | #[macro_export] | |
923072b8 FG |
72 | #[cfg_attr( |
73 | feature = "deprecated", | |
74 | deprecated( | |
75 | since = "3.0.0", | |
76 | note = "Replaced with `ArgMatches::values_of_t_or_exit`" | |
77 | ) | |
04454e1e FG |
78 | )] |
79 | #[doc(hidden)] | |
80 | macro_rules! values_t_or_exit { | |
81 | ($m:ident, $v:expr, $t:ty) => { | |
82 | values_t_or_exit!($m.values_of($v), $t) | |
83 | }; | |
84 | ($m:ident.values_of($v:expr), $t:ty) => { | |
85 | $m.values_of_t_or_exit::<$t>($v) | |
86 | }; | |
87 | } | |
88 | ||
923072b8 FG |
89 | #[cfg_attr( |
90 | feature = "deprecated", | |
91 | deprecated(since = "3.0.0", note = "Replaced with `ArgEnum`") | |
92 | )] | |
93 | #[doc(hidden)] | |
94 | #[macro_export] | |
95 | macro_rules! _clap_count_exprs { | |
96 | () => { 0 }; | |
97 | ($e:expr) => { 1 }; | |
98 | ($e:expr, $($es:expr),+) => { 1 + $crate::_clap_count_exprs!($($es),*) }; | |
99 | } | |
100 | ||
04454e1e | 101 | /// Deprecated, replaced with [`ArgEnum`][crate::ArgEnum] |
923072b8 FG |
102 | #[cfg_attr( |
103 | feature = "deprecated", | |
104 | deprecated(since = "3.0.0", note = "Replaced with `ArgEnum`") | |
105 | )] | |
04454e1e FG |
106 | #[doc(hidden)] |
107 | #[macro_export] | |
108 | macro_rules! arg_enum { | |
109 | (@as_item $($i:item)*) => ($($i)*); | |
110 | (@impls ( $($tts:tt)* ) -> ($e:ident, $($v:ident),+)) => { | |
111 | $crate::arg_enum!(@as_item | |
112 | $($tts)* | |
113 | ||
114 | impl ::std::str::FromStr for $e { | |
115 | type Err = String; | |
116 | ||
117 | fn from_str(s: &str) -> ::std::result::Result<Self,Self::Err> { | |
118 | #[allow(deprecated, unused_imports)] | |
119 | use ::std::ascii::AsciiExt; | |
120 | match s { | |
121 | $(stringify!($v) | | |
122 | _ if s.eq_ignore_ascii_case(stringify!($v)) => Ok($e::$v)),+, | |
123 | _ => Err({ | |
124 | let v = vec![ | |
125 | $(stringify!($v),)+ | |
126 | ]; | |
127 | format!("valid values: {}", | |
128 | v.join(", ")) | |
129 | }), | |
130 | } | |
131 | } | |
132 | } | |
133 | impl ::std::fmt::Display for $e { | |
134 | fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { | |
135 | match *self { | |
136 | $($e::$v => write!(f, stringify!($v)),)+ | |
137 | } | |
138 | } | |
139 | } | |
140 | impl $e { | |
141 | #[allow(dead_code)] | |
142 | pub fn variants() -> [&'static str; $crate::_clap_count_exprs!($(stringify!($v)),+)] { | |
143 | [ | |
144 | $(stringify!($v),)+ | |
145 | ] | |
146 | } | |
147 | }); | |
148 | }; | |
149 | ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { | |
150 | $crate::arg_enum!(@impls | |
151 | ($(#[$($m),+])+ | |
152 | pub enum $e { | |
153 | $($v$(=$val)*),+ | |
154 | }) -> ($e, $($v),+) | |
155 | ); | |
156 | }; | |
157 | ($(#[$($m:meta),+])+ pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { | |
158 | $crate::arg_enum!(@impls | |
159 | ($(#[$($m),+])+ | |
160 | pub enum $e { | |
161 | $($v$(=$val)*),+ | |
162 | }) -> ($e, $($v),+) | |
163 | ); | |
164 | }; | |
165 | ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { | |
166 | $crate::arg_enum!(@impls | |
167 | ($(#[$($m),+])+ | |
168 | enum $e { | |
169 | $($v$(=$val)*),+ | |
170 | }) -> ($e, $($v),+) | |
171 | ); | |
172 | }; | |
173 | ($(#[$($m:meta),+])+ enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { | |
174 | $crate::arg_enum!(@impls | |
175 | ($(#[$($m),+])+ | |
176 | enum $e { | |
177 | $($v$(=$val)*),+ | |
178 | }) -> ($e, $($v),+) | |
179 | ); | |
180 | }; | |
181 | (pub enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { | |
182 | $crate::arg_enum!(@impls | |
183 | (pub enum $e { | |
184 | $($v$(=$val)*),+ | |
185 | }) -> ($e, $($v),+) | |
186 | ); | |
187 | }; | |
188 | (pub enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { | |
189 | $crate::arg_enum!(@impls | |
190 | (pub enum $e { | |
191 | $($v$(=$val)*),+ | |
192 | }) -> ($e, $($v),+) | |
193 | ); | |
194 | }; | |
195 | (enum $e:ident { $($v:ident $(=$val:expr)*,)+ } ) => { | |
196 | $crate::arg_enum!(@impls | |
197 | (enum $e { | |
198 | $($v$(=$val)*),+ | |
199 | }) -> ($e, $($v),+) | |
200 | ); | |
201 | }; | |
202 | (enum $e:ident { $($v:ident $(=$val:expr)*),+ } ) => { | |
203 | $crate::arg_enum!(@impls | |
204 | (enum $e { | |
205 | $($v$(=$val)*),+ | |
206 | }) -> ($e, $($v),+) | |
207 | ); | |
208 | }; | |
209 | } | |
210 | ||
211 | /// Allows you to pull the version from your Cargo.toml at compile time as | |
212 | /// `MAJOR.MINOR.PATCH_PKGVERSION_PRE` | |
213 | /// | |
214 | /// # Examples | |
215 | /// | |
216 | /// ```no_run | |
217 | /// # #[macro_use] | |
218 | /// # extern crate clap; | |
219 | /// # use clap::Command; | |
220 | /// # fn main() { | |
221 | /// let m = Command::new("cmd") | |
222 | /// .version(crate_version!()) | |
223 | /// .get_matches(); | |
224 | /// # } | |
225 | /// ``` | |
226 | #[cfg(feature = "cargo")] | |
227 | #[macro_export] | |
228 | macro_rules! crate_version { | |
229 | () => { | |
230 | env!("CARGO_PKG_VERSION") | |
231 | }; | |
232 | } | |
233 | ||
234 | /// Allows you to pull the authors for the command from your Cargo.toml at | |
235 | /// compile time in the form: | |
236 | /// `"author1 lastname <author1@example.com>:author2 lastname <author2@example.com>"` | |
237 | /// | |
238 | /// You can replace the colons with a custom separator by supplying a | |
239 | /// replacement string, so, for example, | |
240 | /// `crate_authors!(",\n")` would become | |
241 | /// `"author1 lastname <author1@example.com>,\nauthor2 lastname <author2@example.com>,\nauthor3 lastname <author3@example.com>"` | |
242 | /// | |
243 | /// # Examples | |
244 | /// | |
245 | /// ```no_run | |
246 | /// # #[macro_use] | |
247 | /// # extern crate clap; | |
248 | /// # use clap::Command; | |
249 | /// # fn main() { | |
250 | /// let m = Command::new("cmd") | |
251 | /// .author(crate_authors!("\n")) | |
252 | /// .get_matches(); | |
253 | /// # } | |
254 | /// ``` | |
255 | #[cfg(feature = "cargo")] | |
256 | #[macro_export] | |
257 | macro_rules! crate_authors { | |
258 | ($sep:expr) => {{ | |
923072b8 FG |
259 | static CACHED: clap::once_cell::sync::Lazy<String> = |
260 | clap::once_cell::sync::Lazy::new(|| env!("CARGO_PKG_AUTHORS").replace(':', $sep)); | |
04454e1e FG |
261 | |
262 | let s: &'static str = &*CACHED; | |
263 | s | |
264 | }}; | |
265 | () => { | |
266 | env!("CARGO_PKG_AUTHORS") | |
267 | }; | |
268 | } | |
269 | ||
270 | /// Allows you to pull the description from your Cargo.toml at compile time. | |
271 | /// | |
272 | /// # Examples | |
273 | /// | |
274 | /// ```no_run | |
275 | /// # #[macro_use] | |
276 | /// # extern crate clap; | |
277 | /// # use clap::Command; | |
278 | /// # fn main() { | |
279 | /// let m = Command::new("cmd") | |
280 | /// .about(crate_description!()) | |
281 | /// .get_matches(); | |
282 | /// # } | |
283 | /// ``` | |
284 | #[cfg(feature = "cargo")] | |
285 | #[macro_export] | |
286 | macro_rules! crate_description { | |
287 | () => { | |
288 | env!("CARGO_PKG_DESCRIPTION") | |
289 | }; | |
290 | } | |
291 | ||
292 | /// Allows you to pull the name from your Cargo.toml at compile time. | |
293 | /// | |
294 | /// # Examples | |
295 | /// | |
296 | /// ```no_run | |
297 | /// # #[macro_use] | |
298 | /// # extern crate clap; | |
299 | /// # use clap::Command; | |
300 | /// # fn main() { | |
301 | /// let m = Command::new(crate_name!()) | |
302 | /// .get_matches(); | |
303 | /// # } | |
304 | /// ``` | |
305 | #[cfg(feature = "cargo")] | |
306 | #[macro_export] | |
307 | macro_rules! crate_name { | |
308 | () => { | |
309 | env!("CARGO_PKG_NAME") | |
310 | }; | |
311 | } | |
312 | ||
313 | /// Allows you to build the `Command` instance from your Cargo.toml at compile time. | |
314 | /// | |
315 | /// **NOTE:** Changing the values in your `Cargo.toml` does not trigger a re-build automatically, | |
316 | /// and therefore won't change the generated output until you recompile. | |
317 | /// | |
318 | /// In some cases you can "trick" the compiler into triggering a rebuild when your | |
319 | /// `Cargo.toml` is changed by including this in your `src/main.rs` file | |
320 | /// `include_str!("../Cargo.toml");` | |
321 | /// | |
322 | /// # Examples | |
323 | /// | |
324 | /// ```no_run | |
325 | /// # #[macro_use] | |
326 | /// # extern crate clap; | |
327 | /// # fn main() { | |
328 | /// let m = command!().get_matches(); | |
329 | /// # } | |
330 | /// ``` | |
331 | #[cfg(feature = "cargo")] | |
332 | #[macro_export] | |
333 | macro_rules! command { | |
334 | () => {{ | |
335 | $crate::command!($crate::crate_name!()) | |
336 | }}; | |
337 | ($name:expr) => {{ | |
338 | let mut cmd = $crate::Command::new($name).version($crate::crate_version!()); | |
339 | ||
340 | let author = $crate::crate_authors!(); | |
341 | if !author.is_empty() { | |
342 | cmd = cmd.author(author) | |
343 | } | |
344 | ||
345 | let about = $crate::crate_description!(); | |
346 | if !about.is_empty() { | |
347 | cmd = cmd.about(about) | |
348 | } | |
349 | ||
350 | cmd | |
351 | }}; | |
352 | } | |
353 | ||
923072b8 FG |
354 | /// Requires `cargo` feature flag to be enabled. |
355 | #[cfg(not(feature = "cargo"))] | |
356 | #[macro_export] | |
357 | macro_rules! command { | |
358 | () => {{ | |
359 | compile_error!("`cargo` feature flag is required"); | |
360 | }}; | |
361 | ($name:expr) => {{ | |
362 | compile_error!("`cargo` feature flag is required"); | |
363 | }}; | |
364 | } | |
365 | ||
04454e1e FG |
366 | /// Deprecated, replaced with [`clap::command!`][crate::command] |
367 | #[cfg(feature = "cargo")] | |
923072b8 FG |
368 | #[cfg_attr( |
369 | feature = "deprecated", | |
370 | deprecated(since = "3.1.0", note = "Replaced with `clap::command!") | |
371 | )] | |
04454e1e FG |
372 | #[macro_export] |
373 | macro_rules! app_from_crate { | |
374 | () => {{ | |
375 | let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!()); | |
376 | ||
377 | let author = $crate::crate_authors!(", "); | |
378 | if !author.is_empty() { | |
379 | cmd = cmd.author(author) | |
380 | } | |
381 | ||
382 | let about = $crate::crate_description!(); | |
383 | if !about.is_empty() { | |
384 | cmd = cmd.about(about) | |
385 | } | |
386 | ||
387 | cmd | |
388 | }}; | |
389 | ($sep:expr) => {{ | |
390 | let mut cmd = $crate::Command::new($crate::crate_name!()).version($crate::crate_version!()); | |
391 | ||
392 | let author = $crate::crate_authors!($sep); | |
393 | if !author.is_empty() { | |
394 | cmd = cmd.author(author) | |
395 | } | |
396 | ||
397 | let about = $crate::crate_description!(); | |
398 | if !about.is_empty() { | |
399 | cmd = cmd.about(about) | |
400 | } | |
401 | ||
402 | cmd | |
403 | }}; | |
404 | } | |
405 | ||
406 | #[doc(hidden)] | |
407 | #[macro_export] | |
408 | macro_rules! arg_impl { | |
409 | ( @string $val:ident ) => { | |
410 | stringify!($val) | |
411 | }; | |
412 | ( @string $val:literal ) => {{ | |
413 | let ident_or_string_literal: &str = $val; | |
414 | ident_or_string_literal | |
415 | }}; | |
416 | ( @string $val:tt ) => { | |
417 | ::std::compile_error!("Only identifiers or string literals supported"); | |
418 | }; | |
419 | ( @string ) => { | |
420 | None | |
421 | }; | |
422 | ||
423 | ( @char $val:ident ) => {{ | |
424 | let ident_or_char_literal = stringify!($val); | |
425 | debug_assert_eq!( | |
426 | ident_or_char_literal.len(), | |
427 | 1, | |
428 | "Single-letter identifier expected, got {}", | |
429 | ident_or_char_literal | |
430 | ); | |
431 | ident_or_char_literal.chars().next().unwrap() | |
432 | }}; | |
433 | ( @char $val:literal ) => {{ | |
434 | let ident_or_char_literal: char = $val; | |
435 | ident_or_char_literal | |
436 | }}; | |
437 | ( @char ) => {{ | |
438 | None | |
439 | }}; | |
440 | ||
441 | ( | |
442 | @arg | |
443 | ($arg:expr) | |
444 | --$long:ident | |
445 | $($tail:tt)* | |
446 | ) => { | |
447 | $crate::arg_impl! { | |
448 | @arg | |
449 | ({ | |
450 | debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); | |
923072b8 FG |
451 | #[allow(deprecated)] |
452 | { | |
453 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); | |
454 | } | |
04454e1e FG |
455 | |
456 | let mut arg = $arg; | |
457 | let long = $crate::arg_impl! { @string $long }; | |
458 | if arg.get_id().is_empty() { | |
459 | arg = arg.id(long); | |
460 | } | |
461 | arg.long(long) | |
462 | }) | |
463 | $($tail)* | |
464 | } | |
465 | }; | |
466 | ( | |
467 | @arg | |
468 | ($arg:expr) | |
469 | --$long:literal | |
470 | $($tail:tt)* | |
471 | ) => { | |
472 | $crate::arg_impl! { | |
473 | @arg | |
474 | ({ | |
475 | debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); | |
923072b8 FG |
476 | #[allow(deprecated)] |
477 | { | |
478 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); | |
479 | } | |
04454e1e FG |
480 | |
481 | let mut arg = $arg; | |
482 | let long = $crate::arg_impl! { @string $long }; | |
483 | if arg.get_id().is_empty() { | |
484 | arg = arg.id(long); | |
485 | } | |
486 | arg.long(long) | |
487 | }) | |
488 | $($tail)* | |
489 | } | |
490 | }; | |
491 | ( | |
492 | @arg | |
493 | ($arg:expr) | |
494 | -$short:ident | |
495 | $($tail:tt)* | |
496 | ) => { | |
497 | $crate::arg_impl! { | |
498 | @arg | |
499 | ({ | |
500 | debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); | |
501 | debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); | |
923072b8 FG |
502 | #[allow(deprecated)] |
503 | { | |
504 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); | |
505 | } | |
04454e1e FG |
506 | |
507 | $arg.short($crate::arg_impl! { @char $short }) | |
508 | }) | |
509 | $($tail)* | |
510 | } | |
511 | }; | |
512 | ( | |
513 | @arg | |
514 | ($arg:expr) | |
515 | -$short:literal | |
516 | $($tail:tt)* | |
517 | ) => { | |
518 | $crate::arg_impl! { | |
519 | @arg | |
520 | ({ | |
521 | debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); | |
522 | debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); | |
923072b8 FG |
523 | #[allow(deprecated)] |
524 | { | |
525 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Flags should precede `...`"); | |
526 | } | |
04454e1e FG |
527 | |
528 | $arg.short($crate::arg_impl! { @char $short }) | |
529 | }) | |
530 | $($tail)* | |
531 | } | |
532 | }; | |
533 | ( | |
534 | @arg | |
535 | ($arg:expr) | |
536 | <$value_name:ident> | |
537 | $($tail:tt)* | |
538 | ) => { | |
539 | $crate::arg_impl! { | |
540 | @arg | |
541 | ({ | |
923072b8 FG |
542 | #[allow(deprecated)] |
543 | { | |
544 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); | |
545 | } | |
546 | debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); | |
547 | ||
548 | let mut arg = $arg; | |
549 | ||
550 | arg = arg.required(true); | |
551 | arg = arg.takes_value(true); | |
552 | ||
553 | let value_name = $crate::arg_impl! { @string $value_name }; | |
554 | if arg.get_id().is_empty() { | |
555 | arg = arg.id(value_name); | |
556 | } | |
557 | arg.value_name(value_name) | |
558 | }) | |
559 | $($tail)* | |
560 | } | |
561 | }; | |
562 | ( | |
563 | @arg | |
564 | ($arg:expr) | |
565 | <$value_name:literal> | |
566 | $($tail:tt)* | |
567 | ) => { | |
568 | $crate::arg_impl! { | |
569 | @arg | |
570 | ({ | |
571 | #[allow(deprecated)] | |
572 | { | |
573 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); | |
574 | } | |
04454e1e FG |
575 | debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); |
576 | ||
577 | let mut arg = $arg; | |
578 | ||
579 | arg = arg.required(true); | |
580 | arg = arg.takes_value(true); | |
581 | ||
582 | let value_name = $crate::arg_impl! { @string $value_name }; | |
583 | if arg.get_id().is_empty() { | |
584 | arg = arg.id(value_name); | |
585 | } | |
586 | arg.value_name(value_name) | |
587 | }) | |
588 | $($tail)* | |
589 | } | |
590 | }; | |
591 | ( | |
592 | @arg | |
593 | ($arg:expr) | |
594 | [$value_name:ident] | |
595 | $($tail:tt)* | |
596 | ) => { | |
597 | $crate::arg_impl! { | |
598 | @arg | |
599 | ({ | |
923072b8 FG |
600 | #[allow(deprecated)] |
601 | { | |
602 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); | |
603 | } | |
04454e1e FG |
604 | debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); |
605 | ||
606 | let mut arg = $arg; | |
607 | ||
608 | if arg.get_long().is_none() && arg.get_short().is_none() { | |
609 | arg = arg.required(false); | |
610 | } else { | |
611 | arg = arg.min_values(0).max_values(1); | |
612 | } | |
613 | arg = arg.takes_value(true); | |
614 | ||
615 | let value_name = $crate::arg_impl! { @string $value_name }; | |
616 | if arg.get_id().is_empty() { | |
617 | arg = arg.id(value_name); | |
618 | } | |
619 | arg.value_name(value_name) | |
620 | }) | |
621 | $($tail)* | |
622 | } | |
623 | }; | |
624 | ( | |
625 | @arg | |
626 | ($arg:expr) | |
923072b8 | 627 | [$value_name:literal] |
04454e1e FG |
628 | $($tail:tt)* |
629 | ) => { | |
630 | $crate::arg_impl! { | |
631 | @arg | |
632 | ({ | |
923072b8 FG |
633 | #[allow(deprecated)] |
634 | { | |
635 | debug_assert!(!$arg.is_multiple_occurrences_set(), "Values should precede `...`"); | |
636 | } | |
637 | debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); | |
638 | ||
639 | let mut arg = $arg; | |
640 | ||
641 | if arg.get_long().is_none() && arg.get_short().is_none() { | |
642 | arg = arg.required(false); | |
643 | } else { | |
644 | arg = arg.min_values(0).max_values(1); | |
645 | } | |
646 | arg = arg.takes_value(true); | |
647 | ||
648 | let value_name = $crate::arg_impl! { @string $value_name }; | |
649 | if arg.get_id().is_empty() { | |
650 | arg = arg.id(value_name); | |
651 | } | |
652 | arg.value_name(value_name) | |
04454e1e FG |
653 | }) |
654 | $($tail)* | |
655 | } | |
656 | }; | |
923072b8 FG |
657 | ( |
658 | @arg | |
659 | ($arg:expr) | |
660 | ... | |
661 | $($tail:tt)* | |
662 | ) => { | |
663 | $crate::arg_impl! { | |
664 | @arg | |
665 | ({#[allow(deprecated)]{ | |
666 | $arg.multiple_occurrences(true) | |
667 | }}) | |
668 | $($tail)* | |
669 | } | |
670 | }; | |
04454e1e FG |
671 | ( |
672 | @arg | |
673 | ($arg:expr) | |
674 | $help:literal | |
675 | ) => { | |
676 | $arg.help($help) | |
677 | }; | |
678 | ( | |
679 | @arg | |
680 | ($arg:expr) | |
681 | ) => { | |
682 | $arg | |
683 | }; | |
684 | } | |
685 | ||
686 | /// Create an [`Arg`] from a usage string. | |
687 | /// | |
688 | /// Allows creation of basic settings for the [`Arg`]. | |
689 | /// | |
690 | /// **NOTE**: Not all settings may be set using the usage string method. Some properties are | |
691 | /// only available via the builder pattern. | |
692 | /// | |
693 | /// # Syntax | |
694 | /// | |
695 | /// Usage strings typically following the form: | |
696 | /// | |
697 | /// ```notrust | |
698 | /// [explicit name] [short] [long] [value names] [...] [help string] | |
699 | /// ``` | |
700 | /// | |
701 | /// ### Explicit Name | |
702 | /// | |
703 | /// The name may be either a bare-word or a string, followed by a `:`, like `name:` or | |
704 | /// `"name":`. | |
705 | /// | |
706 | /// *Note:* This is an optional field, if it's omitted the argument will use one of the additional | |
707 | /// fields as the name using the following priority order: | |
708 | /// | |
709 | /// 1. Explicit Name | |
710 | /// 2. Long | |
711 | /// 3. Value Name | |
712 | /// | |
713 | /// See [`Arg::name`][crate::Arg::name]. | |
714 | /// | |
715 | /// ### Short | |
716 | /// | |
717 | /// A short flag is a `-` followed by either a bare-character or quoted character, like `-f` or | |
718 | /// `-'f'`. | |
719 | /// | |
720 | /// See [`Arg::short`][crate::Arg::short]. | |
721 | /// | |
722 | /// ### Long | |
723 | /// | |
724 | /// A long flag is a `--` followed by either a bare-word or a string, like `--foo` or | |
725 | /// `--"foo"`. | |
726 | /// | |
727 | /// See [`Arg::long`][crate::Arg::long]. | |
728 | /// | |
729 | /// ### Values (Value Notation) | |
730 | /// | |
731 | /// This is set by placing bare-word between: | |
732 | /// - `[]` like `[FOO]` | |
733 | /// - Positional argument: optional | |
734 | /// - Named argument: optional value | |
735 | /// - `<>` like `<FOO>`: required | |
736 | /// | |
737 | /// See [`Arg::value_name`][crate::Arg::value_name]. | |
738 | /// | |
739 | /// ### `...` | |
740 | /// | |
741 | /// `...` (three consecutive dots/periods) specifies that this argument may occur multiple | |
742 | /// times (not to be confused with multiple values per occurrence). | |
743 | /// | |
744 | /// See [`Arg::multiple_occurrences`][crate::Arg::multiple_occurrences]. | |
745 | /// | |
746 | /// ### Help String | |
747 | /// | |
923072b8 | 748 | /// The help string is denoted between a pair of double quotes `""` and may contain any |
04454e1e FG |
749 | /// characters. |
750 | /// | |
751 | /// # Examples | |
752 | /// | |
753 | /// ```rust | |
754 | /// # use clap::{Command, Arg, arg}; | |
755 | /// Command::new("prog") | |
756 | /// .args(&[ | |
757 | /// arg!(--config <FILE> "a required file for the configuration and no short"), | |
758 | /// arg!(-d --debug ... "turns on debugging information and allows multiples"), | |
759 | /// arg!([input] "an optional input file to use") | |
760 | /// ]) | |
761 | /// # ; | |
762 | /// ``` | |
763 | /// [`Arg`]: ./struct.Arg.html | |
764 | #[macro_export] | |
765 | macro_rules! arg { | |
766 | ( $name:ident: $($tail:tt)+ ) => { | |
767 | $crate::arg_impl! { | |
768 | @arg ($crate::Arg::new($crate::arg_impl! { @string $name })) $($tail)+ | |
769 | } | |
770 | }; | |
771 | ( $($tail:tt)+ ) => {{ | |
772 | let arg = $crate::arg_impl! { | |
773 | @arg ($crate::Arg::default()) $($tail)+ | |
774 | }; | |
775 | debug_assert!(!arg.get_id().is_empty(), "Without a value or long flag, the `name:` prefix is required"); | |
776 | arg | |
777 | }}; | |
778 | } | |
779 | ||
780 | /// Deprecated, replaced with [`clap::Parser`][crate::Parser] and [`clap::arg!`][crate::arg] (Issue clap-rs/clap#2835) | |
923072b8 FG |
781 | #[cfg_attr( |
782 | feature = "deprecated", | |
783 | deprecated( | |
784 | since = "3.0.0", | |
785 | note = "Replaced with `clap::Parser` for a declarative API (Issue clap-rs/clap#2835)" | |
786 | ) | |
04454e1e FG |
787 | )] |
788 | #[doc(hidden)] | |
789 | #[macro_export] | |
790 | macro_rules! clap_app { | |
791 | (@app ($builder:expr)) => { $builder }; | |
792 | (@app ($builder:expr) (@arg ($name:expr): $($tail:tt)*) $($tt:tt)*) => { | |
793 | $crate::clap_app!{ @app | |
794 | ($builder.arg( | |
795 | $crate::clap_app!{ @arg ($crate::Arg::new($name)) (-) $($tail)* })) | |
796 | $($tt)* | |
797 | } | |
798 | }; | |
799 | (@app ($builder:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => { | |
800 | $crate::clap_app!{ @app | |
801 | ($builder.arg( | |
802 | $crate::clap_app!{ @arg ($crate::Arg::new(stringify!($name))) (-) $($tail)* })) | |
803 | $($tt)* | |
804 | } | |
805 | }; | |
806 | (@app ($builder:expr) (@setting $setting:ident) $($tt:tt)*) => { | |
807 | $crate::clap_app!{ @app | |
808 | ($builder.setting($crate::AppSettings::$setting)) | |
809 | $($tt)* | |
810 | } | |
811 | }; | |
812 | // Treat the application builder as an argument to set its attributes | |
813 | (@app ($builder:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => { | |
814 | $crate::clap_app!{ @app ($crate::clap_app!{ @arg ($builder) $($attr)* }) $($tt)* } | |
815 | }; | |
816 | (@app ($builder:expr) (@group $name:ident => $($tail:tt)*) $($tt:tt)*) => { | |
817 | $crate::clap_app!{ @app | |
818 | ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name))) $($tail)* }) | |
819 | $($tt)* | |
820 | } | |
821 | }; | |
822 | (@app ($builder:expr) (@group $name:ident !$ident:ident => $($tail:tt)*) $($tt:tt)*) => { | |
823 | $crate::clap_app!{ @app | |
824 | ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(false)) $($tail)* }) | |
825 | $($tt)* | |
826 | } | |
827 | }; | |
828 | (@app ($builder:expr) (@group $name:ident +$ident:ident => $($tail:tt)*) $($tt:tt)*) => { | |
829 | $crate::clap_app!{ @app | |
830 | ($crate::clap_app!{ @group ($builder, $crate::ArgGroup::new(stringify!($name)).$ident(true)) $($tail)* }) | |
831 | $($tt)* | |
832 | } | |
833 | }; | |
834 | // Handle subcommand creation | |
835 | (@app ($builder:expr) (@subcommand $name:ident => $($tail:tt)*) $($tt:tt)*) => { | |
836 | $crate::clap_app!{ @app | |
837 | ($builder.subcommand( | |
838 | $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* } | |
839 | )) | |
840 | $($tt)* | |
841 | } | |
842 | }; | |
843 | // Yaml like function calls - used for setting various meta directly against the app | |
844 | (@app ($builder:expr) ($ident:ident: $($v:expr),*) $($tt:tt)*) => { | |
845 | // $crate::clap_app!{ @app ($builder.$ident($($v),*)) $($tt)* } | |
846 | $crate::clap_app!{ @app | |
847 | ($builder.$ident($($v),*)) | |
848 | $($tt)* | |
849 | } | |
850 | }; | |
851 | ||
852 | // Add members to group and continue argument handling with the parent builder | |
853 | (@group ($builder:expr, $group:expr)) => { $builder.group($group) }; | |
854 | // Treat the group builder as an argument to set its attributes | |
855 | (@group ($builder:expr, $group:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => { | |
856 | $crate::clap_app!{ @group ($builder, $crate::clap_app!{ @arg ($group) (-) $($attr)* }) $($tt)* } | |
857 | }; | |
858 | (@group ($builder:expr, $group:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => { | |
859 | $crate::clap_app!{ @group | |
860 | ($crate::clap_app!{ @app ($builder) (@arg $name: $($tail)*) }, | |
861 | $group.arg(stringify!($name))) | |
862 | $($tt)* | |
863 | } | |
864 | }; | |
865 | ||
866 | // No more tokens to munch | |
867 | (@arg ($arg:expr) $modes:tt) => { $arg }; | |
868 | // Shorthand tokens influenced by the usage_string | |
869 | (@arg ($arg:expr) $modes:tt --($long:expr) $($tail:tt)*) => { | |
870 | $crate::clap_app!{ @arg ($arg.long($long)) $modes $($tail)* } | |
871 | }; | |
872 | (@arg ($arg:expr) $modes:tt --$long:ident $($tail:tt)*) => { | |
873 | $crate::clap_app!{ @arg ($arg.long(stringify!($long))) $modes $($tail)* } | |
874 | }; | |
875 | (@arg ($arg:expr) $modes:tt -$short:ident $($tail:tt)*) => { | |
876 | $crate::clap_app!{ @arg ($arg.short(stringify!($short).chars().next().unwrap())) $modes $($tail)* } | |
877 | }; | |
878 | (@arg ($arg:expr) (-) <$var:ident> $($tail:tt)*) => { | |
879 | $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value +required $($tail)* } | |
880 | }; | |
881 | (@arg ($arg:expr) (+) <$var:ident> $($tail:tt)*) => { | |
882 | $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* } | |
883 | }; | |
884 | (@arg ($arg:expr) (-) [$var:ident] $($tail:tt)*) => { | |
885 | $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) +takes_value $($tail)* } | |
886 | }; | |
887 | (@arg ($arg:expr) (+) [$var:ident] $($tail:tt)*) => { | |
888 | $crate::clap_app!{ @arg ($arg.value_name(stringify!($var))) (+) $($tail)* } | |
889 | }; | |
890 | (@arg ($arg:expr) $modes:tt ... $($tail:tt)*) => { | |
891 | $crate::clap_app!{ @arg ($arg) $modes +multiple +takes_value $($tail)* } | |
892 | }; | |
893 | // Shorthand magic | |
894 | (@arg ($arg:expr) $modes:tt #{$n:expr, $m:expr} $($tail:tt)*) => { | |
895 | $crate::clap_app!{ @arg ($arg) $modes min_values($n) max_values($m) $($tail)* } | |
896 | }; | |
897 | (@arg ($arg:expr) $modes:tt * $($tail:tt)*) => { | |
898 | $crate::clap_app!{ @arg ($arg) $modes +required $($tail)* } | |
899 | }; | |
900 | // !foo -> .foo(false) | |
901 | (@arg ($arg:expr) $modes:tt !$ident:ident $($tail:tt)*) => { | |
902 | $crate::clap_app!{ @arg ($arg.$ident(false)) $modes $($tail)* } | |
903 | }; | |
904 | // +foo -> .foo(true) | |
905 | (@arg ($arg:expr) $modes:tt +$ident:ident $($tail:tt)*) => { | |
906 | $crate::clap_app!{ @arg ($arg.$ident(true)) $modes $($tail)* } | |
907 | }; | |
908 | // Validator | |
909 | (@arg ($arg:expr) $modes:tt {$fn_:expr} $($tail:tt)*) => { | |
910 | $crate::clap_app!{ @arg ($arg.validator($fn_)) $modes $($tail)* } | |
911 | }; | |
912 | (@as_expr $expr:expr) => { $expr }; | |
913 | // Help | |
914 | (@arg ($arg:expr) $modes:tt $desc:tt) => { $arg.help($crate::clap_app!{ @as_expr $desc }) }; | |
915 | // Handle functions that need to be called multiple times for each argument | |
916 | (@arg ($arg:expr) $modes:tt $ident:ident[$($target:ident)*] $($tail:tt)*) => { | |
917 | $crate::clap_app!{ @arg ($arg $( .$ident(stringify!($target)) )*) $modes $($tail)* } | |
918 | }; | |
919 | // Inherit builder's functions, e.g. `index(2)`, `requires_if("val", "arg")` | |
920 | (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr),*) $($tail:tt)*) => { | |
921 | $crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } | |
922 | }; | |
923 | // Inherit builder's functions with trailing comma, e.g. `index(2,)`, `requires_if("val", "arg",)` | |
924 | (@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr,)*) $($tail:tt)*) => { | |
925 | $crate::clap_app!{ @arg ($arg.$ident($($expr),*)) $modes $($tail)* } | |
926 | }; | |
927 | ||
928 | // Build a subcommand outside of an app. | |
929 | (@subcommand $name:ident => $($tail:tt)*) => { | |
930 | $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)* } | |
931 | }; | |
932 | // Start the magic | |
933 | (($name:expr) => $($tail:tt)*) => {{ | |
934 | $crate::clap_app!{ @app ($crate::Command::new($name)) $($tail)*} | |
935 | }}; | |
936 | ||
937 | ($name:ident => $($tail:tt)*) => {{ | |
938 | $crate::clap_app!{ @app ($crate::Command::new(stringify!($name))) $($tail)*} | |
939 | }}; | |
940 | } | |
941 | ||
942 | macro_rules! impl_settings { | |
943 | ($settings:ident, $flags:ident, | |
944 | $( | |
945 | $(#[$inner:ident $($args:tt)*])* | |
946 | $setting:ident => $flag:path | |
947 | ),+ | |
948 | ) => { | |
949 | impl $flags { | |
950 | #[allow(dead_code)] | |
951 | pub(crate) fn empty() -> Self { | |
952 | $flags(Flags::empty()) | |
953 | } | |
954 | ||
955 | #[allow(dead_code)] | |
956 | pub(crate) fn insert(&mut self, rhs: Self) { | |
957 | self.0.insert(rhs.0); | |
958 | } | |
959 | ||
960 | #[allow(dead_code)] | |
961 | pub(crate) fn remove(&mut self, rhs: Self) { | |
962 | self.0.remove(rhs.0); | |
963 | } | |
964 | ||
965 | #[allow(dead_code)] | |
966 | pub(crate) fn set(&mut self, s: $settings) { | |
967 | #[allow(deprecated)] // some Settings might be deprecated | |
968 | match s { | |
969 | $( | |
970 | $(#[$inner $($args)*])* | |
971 | $settings::$setting => self.0.insert($flag), | |
972 | )* | |
973 | } | |
974 | } | |
975 | ||
976 | #[allow(dead_code)] | |
977 | pub(crate) fn unset(&mut self, s: $settings) { | |
978 | #[allow(deprecated)] // some Settings might be deprecated | |
979 | match s { | |
980 | $( | |
981 | $(#[$inner $($args)*])* | |
982 | $settings::$setting => self.0.remove($flag), | |
983 | )* | |
984 | } | |
985 | } | |
986 | ||
987 | #[allow(dead_code)] | |
988 | pub(crate) fn is_set(&self, s: $settings) -> bool { | |
989 | #[allow(deprecated)] // some Settings might be deprecated | |
990 | match s { | |
991 | $( | |
992 | $(#[$inner $($args)*])* | |
993 | $settings::$setting => self.0.contains($flag), | |
994 | )* | |
995 | } | |
996 | } | |
997 | } | |
998 | ||
999 | impl BitOr for $flags { | |
1000 | type Output = Self; | |
1001 | ||
1002 | fn bitor(mut self, rhs: Self) -> Self::Output { | |
1003 | self.0.insert(rhs.0); | |
1004 | self | |
1005 | } | |
1006 | } | |
1007 | ||
1008 | impl From<$settings> for $flags { | |
1009 | fn from(setting: $settings) -> Self { | |
1010 | let mut flags = $flags::empty(); | |
1011 | flags.set(setting); | |
1012 | flags | |
1013 | } | |
1014 | } | |
1015 | ||
1016 | impl BitOr<$settings> for $flags { | |
1017 | type Output = Self; | |
1018 | ||
1019 | fn bitor(mut self, rhs: $settings) -> Self::Output { | |
1020 | self.set(rhs); | |
1021 | self | |
1022 | } | |
1023 | } | |
1024 | ||
1025 | impl BitOr for $settings { | |
1026 | type Output = $flags; | |
1027 | ||
1028 | fn bitor(self, rhs: Self) -> Self::Output { | |
1029 | let mut flags = $flags::empty(); | |
1030 | flags.set(self); | |
1031 | flags.set(rhs); | |
1032 | flags | |
1033 | } | |
1034 | } | |
1035 | } | |
1036 | } | |
1037 | ||
1038 | // Convenience for writing to stderr thanks to https://github.com/BurntSushi | |
1039 | macro_rules! wlnerr { | |
1040 | ($($arg:tt)*) => ({ | |
1041 | use std::io::{Write, stderr}; | |
1042 | writeln!(&mut stderr(), $($arg)*).ok(); | |
1043 | }) | |
1044 | } | |
1045 | ||
1046 | #[cfg(feature = "debug")] | |
1047 | macro_rules! debug { | |
1048 | ($($arg:tt)*) => ({ | |
1049 | let prefix = format!("[{:>w$}] \t", module_path!(), w = 28); | |
1050 | let body = format!($($arg)*); | |
923072b8 | 1051 | let mut color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto); |
04454e1e FG |
1052 | color.hint(prefix); |
1053 | color.hint(body); | |
1054 | color.none("\n"); | |
1055 | let _ = color.print(); | |
1056 | }) | |
1057 | } | |
1058 | ||
1059 | #[cfg(not(feature = "debug"))] | |
1060 | macro_rules! debug { | |
1061 | ($($arg:tt)*) => {}; | |
1062 | } |