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] 18macro_rules! crate_version { 19 () => { 20 env!("CARGO_PKG_VERSION") 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] 47macro_rules! crate_authors { 48 ($sep:expr) => {{ 49 static authors: &str = env!("CARGO_PKG_AUTHORS"); 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 env!("CARGO_PKG_AUTHORS") 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] 80macro_rules! crate_description { 81 () => { 82 env!("CARGO_PKG_DESCRIPTION") 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] 107macro_rules! crate_name { 108 () => { 109 env!("CARGO_PKG_NAME") 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] 133macro_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] 157macro_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] 168macro_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] 526macro_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 544macro_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")] 638macro_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"))] 652macro_rules! debug { 653 ($($arg:tt)*) => {}; 654} 655 656macro_rules! ok { 657 ($expr:expr) => { 658 match $expr { 659 Ok(val) => val, 660 Err(err) => { 661 return Err(err); 662 } 663 } 664 }; 665} 666 667macro_rules! some { 668 ($expr:expr) => { 669 match $expr { 670 Some(val) => val, 671 None => { 672 return None; 673 } 674 } 675 }; 676} 677