1 /// Allows you to pull the version from your Cargo.toml at compile time as 2 /// `MAJOR.MINOR.PATCH_PKGVERSION_PRE` 3 /// 4 /// # Examples 5 /// 6 /// ```no_run 7 /// # #[macro_use] 8 /// # extern crate clap; 9 /// # use clap::Command; 10 /// # fn main() { 11 /// let m = Command::new("cmd") 12 /// .version(crate_version!()) 13 /// .get_matches(); 14 /// # } 15 /// ``` 16 #[cfg(feature = "cargo")] 17 #[macro_export] 18 macro_rules! crate_version { 19 () => { 20 "4.1.8" 21 }; 22 } 23 24 /// Allows you to pull the authors for the command from your Cargo.toml at 25 /// compile time in the form: 26 /// `"author1 lastname <author1@example.com>:author2 lastname <author2@example.com>"` 27 /// 28 /// You can replace the colons with a custom separator by supplying a 29 /// replacement string, so, for example, 30 /// `crate_authors!(",\n")` would become 31 /// `"author1 lastname <author1@example.com>,\nauthor2 lastname <author2@example.com>,\nauthor3 lastname <author3@example.com>"` 32 /// 33 /// # Examples 34 /// 35 /// ```no_run 36 /// # #[macro_use] 37 /// # extern crate clap; 38 /// # use clap::Command; 39 /// # fn main() { 40 /// let m = Command::new("cmd") 41 /// .author(crate_authors!("\n")) 42 /// .get_matches(); 43 /// # } 44 /// ``` 45 #[cfg(feature = "cargo")] 46 #[macro_export] 47 macro_rules! crate_authors { 48 ($sep:expr) => {{ 49 static authors: &str = .join(":"); 50 if authors.contains(':') { 51 static CACHED: clap::__macro_refs::once_cell::sync::Lazy<String> = 52 clap::__macro_refs::once_cell::sync::Lazy::new(|| authors.replace(':', $sep)); 53 let s: &'static str = &*CACHED; 54 s 55 } else { 56 authors 57 } 58 }}; 59 () => { 60 .join(":") 61 }; 62 } 63 64 /// Allows you to pull the description from your Cargo.toml at compile time. 65 /// 66 /// # Examples 67 /// 68 /// ```no_run 69 /// # #[macro_use] 70 /// # extern crate clap; 71 /// # use clap::Command; 72 /// # fn main() { 73 /// let m = Command::new("cmd") 74 /// .about(crate_description!()) 75 /// .get_matches(); 76 /// # } 77 /// ``` 78 #[cfg(feature = "cargo")] 79 #[macro_export] 80 macro_rules! crate_description { 81 () => { 82 "A simple to use, efficient, and full-featured Command Line Argument Parser" 83 }; 84 } 85 86 /// Allows you to pull the name from your Cargo.toml at compile time. 87 /// 88 /// **NOTE:** This macro extracts the name from an environment variable `CARGO_PKG_NAME`. 89 /// When the crate name is set to something different from the package name, 90 /// use environment variables `CARGO_CRATE_NAME` or `CARGO_BIN_NAME`. 91 /// See [the Cargo Book](https://doc.rust-lang.org/cargo/reference/environment-variables.html) 92 /// for more information. 93 /// 94 /// # Examples 95 /// 96 /// ```no_run 97 /// # #[macro_use] 98 /// # extern crate clap; 99 /// # use clap::Command; 100 /// # fn main() { 101 /// let m = Command::new(crate_name!()) 102 /// .get_matches(); 103 /// # } 104 /// ``` 105 #[cfg(feature = "cargo")] 106 #[macro_export] 107 macro_rules! crate_name { 108 () => { 109 "clap" 110 }; 111 } 112 113 /// Allows you to build the `Command` instance from your Cargo.toml at compile time. 114 /// 115 /// **NOTE:** Changing the values in your `Cargo.toml` does not trigger a re-build automatically, 116 /// and therefore won't change the generated output until you recompile. 117 /// 118 /// In some cases you can "trick" the compiler into triggering a rebuild when your 119 /// `Cargo.toml` is changed by including this in your `src/main.rs` file 120 /// `include_str!("../Cargo.toml");` 121 /// 122 /// # Examples 123 /// 124 /// ```no_run 125 /// # #[macro_use] 126 /// # extern crate clap; 127 /// # fn main() { 128 /// let m = command!().get_matches(); 129 /// # } 130 /// ``` 131 #[cfg(feature = "cargo")] 132 #[macro_export] 133 macro_rules! command { 134 () => {{ 135 $crate::command!($crate::crate_name!()) 136 }}; 137 ($name:expr) => {{ 138 let mut cmd = $crate::Command::new($name).version($crate::crate_version!()); 139 140 let author = $crate::crate_authors!(); 141 if !author.is_empty() { 142 cmd = cmd.author(author) 143 } 144 145 let about = $crate::crate_description!(); 146 if !about.is_empty() { 147 cmd = cmd.about(about) 148 } 149 150 cmd 151 }}; 152 } 153 154 /// Requires `cargo` feature flag to be enabled. 155 #[cfg(not(feature = "cargo"))] 156 #[macro_export] 157 macro_rules! command { 158 () => {{ 159 compile_error!("`cargo` feature flag is required"); 160 }}; 161 ($name:expr) => {{ 162 compile_error!("`cargo` feature flag is required"); 163 }}; 164 } 165 166 #[doc(hidden)] 167 #[macro_export] 168 macro_rules! arg_impl { 169 ( @string $val:ident ) => { 170 stringify!($val) 171 }; 172 ( @string $val:literal ) => {{ 173 let ident_or_string_literal: &str = $val; 174 ident_or_string_literal 175 }}; 176 ( @string $val:tt ) => { 177 ::std::compile_error!("Only identifiers or string literals supported"); 178 }; 179 ( @string ) => { 180 None 181 }; 182 183 ( @char $val:ident ) => {{ 184 let ident_or_char_literal = stringify!($val); 185 debug_assert_eq!( 186 ident_or_char_literal.len(), 187 1, 188 "Single-letter identifier expected, got {}", 189 ident_or_char_literal 190 ); 191 ident_or_char_literal.chars().next().unwrap() 192 }}; 193 ( @char $val:literal ) => {{ 194 let ident_or_char_literal: char = $val; 195 ident_or_char_literal 196 }}; 197 ( @char ) => {{ 198 None 199 }}; 200 201 ( 202 @arg 203 ($arg:expr) 204 --$long:ident 205 $($tail:tt)* 206 ) => {{ 207 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); 208 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 209 210 let mut arg = $arg; 211 let long = $crate::arg_impl! { @string $long }; 212 if arg.get_id() == "" { 213 arg = arg.id(long); 214 } 215 let action = $crate::ArgAction::SetTrue; 216 let arg = arg 217 .long(long) 218 .action(action); 219 let arg = $crate::arg_impl! { 220 @arg (arg) $($tail)* 221 }; 222 arg 223 }}; 224 ( 225 @arg 226 ($arg:expr) 227 --$long:literal 228 $($tail:tt)* 229 ) => {{ 230 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); 231 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 232 233 let mut arg = $arg; 234 let long = $crate::arg_impl! { @string $long }; 235 if arg.get_id() == "" { 236 arg = arg.id(long); 237 } 238 let action = $crate::ArgAction::SetTrue; 239 let arg = arg 240 .long(long) 241 .action(action); 242 let arg = $crate::arg_impl! { 243 @arg (arg) $($tail)* 244 }; 245 arg 246 }}; 247 ( 248 @arg 249 ($arg:expr) 250 -$short:ident 251 $($tail:tt)* 252 ) => {{ 253 debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); 254 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); 255 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 256 257 let action = $crate::ArgAction::SetTrue; 258 let arg = $arg 259 .short($crate::arg_impl! { @char $short }) 260 .action(action); 261 let arg = $crate::arg_impl! { 262 @arg (arg) $($tail)* 263 }; 264 arg 265 }}; 266 ( 267 @arg 268 ($arg:expr) 269 -$short:literal 270 $($tail:tt)* 271 ) => {{ 272 debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags"); 273 debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values"); 274 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 275 276 let action = $crate::ArgAction::SetTrue; 277 let arg = $arg 278 .short($crate::arg_impl! { @char $short }) 279 .action(action); 280 let arg = $crate::arg_impl! { 281 @arg (arg) $($tail)* 282 }; 283 arg 284 }}; 285 ( 286 @arg 287 ($arg:expr) 288 <$value_name:ident> 289 $($tail:tt)* 290 ) => {{ 291 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 292 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); 293 294 let mut arg = $arg; 295 296 if arg.get_long().is_none() && arg.get_short().is_none() { 297 arg = arg.required(true); 298 } 299 300 let value_name = $crate::arg_impl! { @string $value_name }; 301 if arg.get_id() == "" { 302 arg = arg.id(value_name); 303 } 304 let arg = arg 305 .value_name(value_name) 306 .action($crate::ArgAction::Set); 307 let arg = $crate::arg_impl! { 308 @arg (arg) $($tail)* 309 }; 310 arg 311 }}; 312 ( 313 @arg 314 ($arg:expr) 315 <$value_name:literal> 316 $($tail:tt)* 317 ) => {{ 318 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 319 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); 320 321 let mut arg = $arg; 322 323 if arg.get_long().is_none() && arg.get_short().is_none() { 324 arg = arg.required(true); 325 } 326 327 let value_name = $crate::arg_impl! { @string $value_name }; 328 if arg.get_id() == "" { 329 arg = arg.id(value_name); 330 } 331 let arg = arg 332 .value_name(value_name) 333 .action($crate::ArgAction::Set); 334 let arg = $crate::arg_impl! { 335 @arg (arg) $($tail)* 336 }; 337 arg 338 }}; 339 ( 340 @arg 341 ($arg:expr) 342 [$value_name:ident] 343 $($tail:tt)* 344 ) => {{ 345 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 346 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); 347 348 let mut arg = $arg; 349 350 if arg.get_long().is_none() && arg.get_short().is_none() { 351 arg = arg.required(false); 352 } else { 353 arg = arg.num_args(0..=1); 354 } 355 356 let value_name = $crate::arg_impl! { @string $value_name }; 357 if arg.get_id() == "" { 358 arg = arg.id(value_name); 359 } 360 let arg = arg 361 .value_name(value_name) 362 .action($crate::ArgAction::Set); 363 let arg = $crate::arg_impl! { 364 @arg (arg) $($tail)* 365 }; 366 arg 367 }}; 368 ( 369 @arg 370 ($arg:expr) 371 [$value_name:literal] 372 $($tail:tt)* 373 ) => {{ 374 debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`"); 375 debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported"); 376 377 let mut arg = $arg; 378 379 if arg.get_long().is_none() && arg.get_short().is_none() { 380 arg = arg.required(false); 381 } else { 382 arg = arg.num_args(0..=1); 383 } 384 385 let value_name = $crate::arg_impl! { @string $value_name }; 386 if arg.get_id() == "" { 387 arg = arg.id(value_name); 388 } 389 let arg = arg 390 .value_name(value_name) 391 .action($crate::ArgAction::Set); 392 let arg = $crate::arg_impl! { 393 @arg (arg) $($tail)* 394 }; 395 arg 396 }}; 397 ( 398 @arg 399 ($arg:expr) 400 ... 401 $($tail:tt)* 402 ) => {{ 403 let arg = match $arg.get_action() { 404 $crate::ArgAction::Set => { 405 if $arg.get_long().is_none() && $arg.get_short().is_none() { 406 $arg.num_args(1..) 407 // Allow collecting arguments interleaved with flags 408 .action($crate::ArgAction::Append) 409 } else { 410 $arg.action($crate::ArgAction::Append) 411 } 412 }, 413 $crate::ArgAction::SetTrue | $crate::ArgAction::Help | $crate::ArgAction::Version => { 414 $arg.action($crate::ArgAction::Count) 415 } 416 action => { 417 panic!("Unexpected action {:?}", action) 418 } 419 }; 420 let arg = $crate::arg_impl! { 421 @arg (arg) $($tail)* 422 }; 423 arg 424 }}; 425 ( 426 @arg 427 ($arg:expr) 428 $help:literal 429 ) => {{ 430 $arg.help($help) 431 }}; 432 ( 433 @arg 434 ($arg:expr) 435 ) => {{ 436 $arg 437 }}; 438 } 439 440 /// Create an [`Arg`] from a usage string. 441 /// 442 /// Allows creation of basic settings for the [`Arg`]. 443 /// 444 /// **NOTE**: Not all settings may be set using the usage string method. Some properties are 445 /// only available via the builder pattern. 446 /// 447 /// # Syntax 448 /// 449 /// Usage strings typically following the form: 450 /// 451 /// ```notrust 452 /// [explicit name] [short] [long] [value names] [...] [help string] 453 /// ``` 454 /// 455 /// ### Explicit Name 456 /// 457 /// The name may be either a bare-word or a string, followed by a `:`, like `name:` or 458 /// `"name":`. 459 /// 460 /// *Note:* This is an optional field, if it's omitted the argument will use one of the additional 461 /// fields as the name using the following priority order: 462 /// 463 /// 1. Explicit Name 464 /// 2. Long 465 /// 3. Value Name 466 /// 467 /// See [`Arg::id`][crate::Arg::id]. 468 /// 469 /// ### Short 470 /// 471 /// A short flag is a `-` followed by either a bare-character or quoted character, like `-f` or 472 /// `-'f'`. 473 /// 474 /// See [`Arg::short`][crate::Arg::short]. 475 /// 476 /// ### Long 477 /// 478 /// A long flag is a `--` followed by either a bare-word or a string, like `--foo` or 479 /// `--"foo"`. 480 /// 481 /// **NOTE:** Dashes in the long name (e.g. `--foo-bar`) is not supported and quoting is required 482 /// (e.g. `--"foo-bar"`). 483 /// 484 /// See [`Arg::long`][crate::Arg::long]. 485 /// 486 /// ### Values (Value Notation) 487 /// 488 /// This is set by placing bare-word between: 489 /// - `[]` like `[FOO]` 490 /// - Positional argument: optional 491 /// - Named argument: optional value 492 /// - `<>` like `<FOO>`: required 493 /// 494 /// See [`Arg::value_name`][crate::Arg::value_name]. 495 /// 496 /// ### `...` 497 /// 498 /// `...` (three consecutive dots/periods) specifies that this argument may occur multiple 499 /// times (not to be confused with multiple values per occurrence). 500 /// 501 /// See [`ArgAction::Count`][crate::ArgAction::Count] and [`ArgAction::Append`][crate::ArgAction::Append]. 502 /// 503 /// ### Help String 504 /// 505 /// The help string is denoted between a pair of double quotes `""` and may contain any 506 /// characters. 507 /// 508 /// # Examples 509 /// 510 /// ```rust 511 /// # use clap::{Command, Arg, arg}; 512 /// let cmd = Command::new("prog") 513 /// .args(&[ 514 /// arg!(--config <FILE> "a required file for the configuration and no short"), 515 /// arg!(-d --debug ... "turns on debugging information and allows multiples"), 516 /// arg!([input] "an optional input file to use") 517 /// ]); 518 /// 519 /// let m = cmd.try_get_matches_from(["prog", "--config", "file.toml"]).unwrap(); 520 /// assert_eq!(m.get_one::<String>("config").unwrap(), "file.toml"); 521 /// assert_eq!(*m.get_one::<u8>("debug").unwrap(), 0); 522 /// assert_eq!(m.get_one::<String>("input"), None); 523 /// ``` 524 /// [`Arg`]: crate::Arg 525 #[macro_export] 526 macro_rules! arg { 527 ( $name:ident: $($tail:tt)+ ) => {{ 528 let arg = $crate::Arg::new($crate::arg_impl! { @string $name }); 529 let arg = $crate::arg_impl! { 530 @arg (arg) $($tail)+ 531 }; 532 arg 533 }}; 534 ( $($tail:tt)+ ) => {{ 535 let arg = $crate::Arg::default(); 536 let arg = $crate::arg_impl! { 537 @arg (arg) $($tail)+ 538 }; 539 debug_assert_ne!(arg.get_id(), "", "Without a value or long flag, the `name:` prefix is required"); 540 arg 541 }}; 542 } 543 544 macro_rules! impl_settings { 545 ($settings:ident, $flags:ident, 546 $( 547 $(#[$inner:ident $($args:tt)*])* 548 $setting:ident => $flag:path 549 ),+ 550 ) => { 551 impl $flags { 552 #[allow(dead_code)] 553 pub(crate) fn empty() -> Self { 554 $flags(Flags::empty()) 555 } 556 557 #[allow(dead_code)] 558 pub(crate) fn insert(&mut self, rhs: Self) { 559 self.0.insert(rhs.0); 560 } 561 562 #[allow(dead_code)] 563 pub(crate) fn remove(&mut self, rhs: Self) { 564 self.0.remove(rhs.0); 565 } 566 567 #[allow(dead_code)] 568 pub(crate) fn set(&mut self, s: $settings) { 569 match s { 570 $( 571 $(#[$inner $($args)*])* 572 $settings::$setting => self.0.insert($flag), 573 )* 574 } 575 } 576 577 #[allow(dead_code)] 578 pub(crate) fn unset(&mut self, s: $settings) { 579 match s { 580 $( 581 $(#[$inner $($args)*])* 582 $settings::$setting => self.0.remove($flag), 583 )* 584 } 585 } 586 587 #[allow(dead_code)] 588 pub(crate) fn is_set(&self, s: $settings) -> bool { 589 match s { 590 $( 591 $(#[$inner $($args)*])* 592 $settings::$setting => self.0.contains($flag), 593 )* 594 } 595 } 596 } 597 598 impl BitOr for $flags { 599 type Output = Self; 600 601 fn bitor(mut self, rhs: Self) -> Self::Output { 602 self.0.insert(rhs.0); 603 self 604 } 605 } 606 607 impl From<$settings> for $flags { 608 fn from(setting: $settings) -> Self { 609 let mut flags = $flags::empty(); 610 flags.set(setting); 611 flags 612 } 613 } 614 615 impl BitOr<$settings> for $flags { 616 type Output = Self; 617 618 fn bitor(mut self, rhs: $settings) -> Self::Output { 619 self.set(rhs); 620 self 621 } 622 } 623 624 impl BitOr for $settings { 625 type Output = $flags; 626 627 fn bitor(self, rhs: Self) -> Self::Output { 628 let mut flags = $flags::empty(); 629 flags.set(self); 630 flags.set(rhs); 631 flags 632 } 633 } 634 } 635 } 636 637 #[cfg(feature = "debug")] 638 macro_rules! debug { 639 ($($arg:tt)*) => ({ 640 let prefix = format!("[{:>w$}] \t", module_path!(), w = 28); 641 let body = format!($($arg)*); 642 let mut styled = $crate::builder::StyledStr::new(); 643 styled.hint(prefix); 644 styled.hint(body); 645 styled.none("\n"); 646 let color = $crate::output::fmt::Colorizer::new($crate::output::fmt::Stream::Stderr, $crate::ColorChoice::Auto).with_content(styled); 647 let _ = color.print(); 648 }) 649 } 650 651 #[cfg(not(feature = "debug"))] 652 macro_rules! debug { 653 ($($arg:tt)*) => {}; 654 } 655 656 macro_rules! ok { 657 ($expr:expr) => { 658 match $expr { 659 Ok(val) => val, 660 Err(err) => { 661 return Err(err); 662 } 663 } 664 }; 665 } 666 667 macro_rules! some { 668 ($expr:expr) => { 669 match $expr { 670 Some(val) => val, 671 None => { 672 return None; 673 } 674 } 675 }; 676 } 677