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