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