1 mod help; 2 mod meta; 3 pub mod parser; 4 mod settings; 5 mod usage; 6 mod validator; 7 8 // Std 9 use std::env; 10 use std::ffi::{OsStr, OsString}; 11 use std::fmt; 12 use std::io::{self, BufRead, BufWriter, Write}; 13 use std::path::Path; 14 use std::process; 15 use std::rc::Rc; 16 use std::result::Result as StdResult; 17 18 // Third Party 19 #[cfg(feature = "yaml")] 20 use yaml_rust::Yaml; 21 22 // Internal 23 pub use self::settings::AppSettings; 24 use app::help::Help; 25 use app::parser::Parser; 26 use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings}; 27 use completions::Shell; 28 use errors::Result as ClapResult; 29 use map::{self, VecMap}; 30 31 /// Used to create a representation of a command line program and all possible command line 32 /// arguments. Application settings are set using the "builder pattern" with the 33 /// [`App::get_matches`] family of methods being the terminal methods that starts the 34 /// runtime-parsing process. These methods then return information about the user supplied 35 /// arguments (or lack there of). 36 /// 37 /// **NOTE:** There aren't any mandatory "options" that one must set. The "options" may 38 /// also appear in any order (so long as one of the [`App::get_matches`] methods is the last method 39 /// called). 40 /// 41 /// # Examples 42 /// 43 /// ```no_run 44 /// # use clap::{App, Arg}; 45 /// let m = App::new("My Program") 46 /// .author("Me, me@mail.com") 47 /// .version("1.0.2") 48 /// .about("Explains in brief what the program does") 49 /// .arg( 50 /// Arg::with_name("in_file").index(1) 51 /// ) 52 /// .after_help("Longer explanation to appear after the options when \ 53 /// displaying the help information from --help or -h") 54 /// .get_matches(); 55 /// 56 /// // Your program logic starts here... 57 /// ``` 58 /// [`App::get_matches`]: ./struct.App.html#method.get_matches 59 #[allow(missing_debug_implementations)] 60 pub struct App<'a, 'b> 61 where 62 'a: 'b, 63 { 64 #[doc(hidden)] 65 pub p: Parser<'a, 'b>, 66 } 67 68 impl<'a, 'b> App<'a, 'b> { 69 /// Creates a new instance of an application requiring a name. The name may be, but doesn't 70 /// have to be same as the binary. The name will be displayed to the user when they request to 71 /// print version or help and usage information. 72 /// 73 /// # Examples 74 /// 75 /// ```no_run 76 /// # use clap::{App, Arg}; 77 /// let prog = App::new("My Program") 78 /// # ; 79 /// ``` new<S: Into<String>>(n: S) -> Self80 pub fn new<S: Into<String>>(n: S) -> Self { 81 App { 82 p: Parser::with_name(n.into()), 83 } 84 } 85 86 /// Get the name of the app get_name(&self) -> &str87 pub fn get_name(&self) -> &str { 88 &self.p.meta.name 89 } 90 91 /// Get the name of the binary get_bin_name(&self) -> Option<&str>92 pub fn get_bin_name(&self) -> Option<&str> { 93 self.p.meta.bin_name.as_ref().map(|s| s.as_str()) 94 } 95 96 /// Creates a new instance of an application requiring a name, but uses the [`crate_authors!`] 97 /// and [`crate_version!`] macros to fill in the [`App::author`] and [`App::version`] fields. 98 /// 99 /// # Examples 100 /// 101 /// ```no_run 102 /// # use clap::{App, Arg}; 103 /// let prog = App::with_defaults("My Program") 104 /// # ; 105 /// ``` 106 /// [`crate_authors!`]: ./macro.crate_authors!.html 107 /// [`crate_version!`]: ./macro.crate_version!.html 108 /// [`App::author`]: ./struct.App.html#method.author 109 /// [`App::version`]: ./struct.App.html#method.author 110 #[deprecated( 111 since = "2.14.1", 112 note = "Can never work; use explicit App::author() and App::version() calls instead" 113 )] with_defaults<S: Into<String>>(n: S) -> Self114 pub fn with_defaults<S: Into<String>>(n: S) -> Self { 115 let mut a = App { 116 p: Parser::with_name(n.into()), 117 }; 118 a.p.meta.author = Some("Kevin K. <kbknapp@gmail.com>"); 119 a.p.meta.version = Some("2.19.2"); 120 a 121 } 122 123 /// Creates a new instance of [`App`] from a .yml (YAML) file. A full example of supported YAML 124 /// objects can be found in [`examples/17_yaml.rs`] and [`examples/17_yaml.yml`]. One great use 125 /// for using YAML is when supporting multiple languages and dialects, as each language could 126 /// be a distinct YAML file and determined at compiletime via `cargo` "features" in your 127 /// `Cargo.toml` 128 /// 129 /// In order to use this function you must compile `clap` with the `features = ["yaml"]` in 130 /// your settings for the `[dependencies.clap]` table of your `Cargo.toml` 131 /// 132 /// **NOTE:** Due to how the YAML objects are built there is a convenience macro for loading 133 /// the YAML file at compile time (relative to the current file, like modules work). That YAML 134 /// object can then be passed to this function. 135 /// 136 /// # Panics 137 /// 138 /// The YAML file must be properly formatted or this function will [`panic!`]. A good way to 139 /// ensure this doesn't happen is to run your program with the `--help` switch. If this passes 140 /// without error, you needn't worry because the YAML is properly formatted. 141 /// 142 /// # Examples 143 /// 144 /// The following example shows how to load a properly formatted YAML file to build an instance 145 /// of an [`App`] struct. 146 /// 147 /// ```ignore 148 /// # #[macro_use] 149 /// # extern crate clap; 150 /// # use clap::App; 151 /// # fn main() { 152 /// let yml = load_yaml!("app.yml"); 153 /// let app = App::from_yaml(yml); 154 /// 155 /// // continued logic goes here, such as `app.get_matches()` etc. 156 /// # } 157 /// ``` 158 /// [`App`]: ./struct.App.html 159 /// [`examples/17_yaml.rs`]: https://github.com/clap-rs/clap/blob/v2.33.1/examples/17_yaml.rs 160 /// [`examples/17_yaml.yml`]: https://github.com/clap-rs/clap/blob/v2.33.1/examples/17_yaml.yml 161 /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html 162 #[cfg(feature = "yaml")] from_yaml(yaml: &'a Yaml) -> App<'a, 'a>163 pub fn from_yaml(yaml: &'a Yaml) -> App<'a, 'a> { 164 App::from(yaml) 165 } 166 167 /// Sets a string of author(s) that will be displayed to the user when they 168 /// request the help information with `--help` or `-h`. 169 /// 170 /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to automatically set your 171 /// application's author(s) to the same thing as your crate at compile time. See the [`examples/`] 172 /// directory for more information 173 /// 174 /// See the [`examples/`] 175 /// directory for more information 176 /// 177 /// # Examples 178 /// 179 /// ```no_run 180 /// # use clap::{App, Arg}; 181 /// App::new("myprog") 182 /// .author("Me, me@mymain.com") 183 /// # ; 184 /// ``` 185 /// [`crate_authors!`]: ./macro.crate_authors!.html 186 /// [`examples/`]: https://github.com/clap-rs/clap/tree/v2.33.1/examples author<S: Into<&'b str>>(mut self, author: S) -> Self187 pub fn author<S: Into<&'b str>>(mut self, author: S) -> Self { 188 self.p.meta.author = Some(author.into()); 189 self 190 } 191 192 /// Overrides the system-determined binary name. This should only be used when absolutely 193 /// necessary, such as when the binary name for your application is misleading, or perhaps 194 /// *not* how the user should invoke your program. 195 /// 196 /// **Pro-tip:** When building things such as third party `cargo` subcommands, this setting 197 /// **should** be used! 198 /// 199 /// **NOTE:** This command **should not** be used for [`SubCommand`]s. 200 /// 201 /// # Examples 202 /// 203 /// ```no_run 204 /// # use clap::{App, Arg}; 205 /// App::new("My Program") 206 /// .bin_name("my_binary") 207 /// # ; 208 /// ``` 209 /// [`SubCommand`]: ./struct.SubCommand.html bin_name<S: Into<String>>(mut self, name: S) -> Self210 pub fn bin_name<S: Into<String>>(mut self, name: S) -> Self { 211 self.p.meta.bin_name = Some(name.into()); 212 self 213 } 214 215 /// Sets a string describing what the program does. This will be displayed when displaying help 216 /// information with `-h`. 217 /// 218 /// **NOTE:** If only `about` is provided, and not [`App::long_about`] but the user requests 219 /// `--help` clap will still display the contents of `about` appropriately 220 /// 221 /// **NOTE:** Only [`App::about`] is used in completion script generation in order to be 222 /// concise 223 /// 224 /// # Examples 225 /// 226 /// ```no_run 227 /// # use clap::{App, Arg}; 228 /// App::new("myprog") 229 /// .about("Does really amazing things to great people") 230 /// # ; 231 /// ``` 232 /// [`App::long_about`]: ./struct.App.html#method.long_about about<S: Into<&'b str>>(mut self, about: S) -> Self233 pub fn about<S: Into<&'b str>>(mut self, about: S) -> Self { 234 self.p.meta.about = Some(about.into()); 235 self 236 } 237 238 /// Sets a string describing what the program does. This will be displayed when displaying help 239 /// information. 240 /// 241 /// **NOTE:** If only `long_about` is provided, and not [`App::about`] but the user requests 242 /// `-h` clap will still display the contents of `long_about` appropriately 243 /// 244 /// **NOTE:** Only [`App::about`] is used in completion script generation in order to be 245 /// concise 246 /// 247 /// # Examples 248 /// 249 /// ```no_run 250 /// # use clap::{App, Arg}; 251 /// App::new("myprog") 252 /// .long_about( 253 /// "Does really amazing things to great people. Now let's talk a little 254 /// more in depth about how this subcommand really works. It may take about 255 /// a few lines of text, but that's ok!") 256 /// # ; 257 /// ``` 258 /// [`App::about`]: ./struct.App.html#method.about long_about<S: Into<&'b str>>(mut self, about: S) -> Self259 pub fn long_about<S: Into<&'b str>>(mut self, about: S) -> Self { 260 self.p.meta.long_about = Some(about.into()); 261 self 262 } 263 264 /// Sets the program's name. This will be displayed when displaying help information. 265 /// 266 /// **Pro-top:** This function is particularly useful when configuring a program via 267 /// [`App::from_yaml`] in conjunction with the [`crate_name!`] macro to derive the program's 268 /// name from its `Cargo.toml`. 269 /// 270 /// # Examples 271 /// ```ignore 272 /// # #[macro_use] 273 /// # extern crate clap; 274 /// # use clap::App; 275 /// # fn main() { 276 /// let yml = load_yaml!("app.yml"); 277 /// let app = App::from_yaml(yml) 278 /// .name(crate_name!()); 279 /// 280 /// // continued logic goes here, such as `app.get_matches()` etc. 281 /// # } 282 /// ``` 283 /// 284 /// [`App::from_yaml`]: ./struct.App.html#method.from_yaml 285 /// [`crate_name!`]: ./macro.crate_name.html name<S: Into<String>>(mut self, name: S) -> Self286 pub fn name<S: Into<String>>(mut self, name: S) -> Self { 287 self.p.meta.name = name.into(); 288 self 289 } 290 291 /// Adds additional help information to be displayed in addition to auto-generated help. This 292 /// information is displayed **after** the auto-generated help information. This is often used 293 /// to describe how to use the arguments, or caveats to be noted. 294 /// 295 /// # Examples 296 /// 297 /// ```no_run 298 /// # use clap::App; 299 /// App::new("myprog") 300 /// .after_help("Does really amazing things to great people...but be careful with -R") 301 /// # ; 302 /// ``` after_help<S: Into<&'b str>>(mut self, help: S) -> Self303 pub fn after_help<S: Into<&'b str>>(mut self, help: S) -> Self { 304 self.p.meta.more_help = Some(help.into()); 305 self 306 } 307 308 /// Adds additional help information to be displayed in addition to auto-generated help. This 309 /// information is displayed **before** the auto-generated help information. This is often used 310 /// for header information. 311 /// 312 /// # Examples 313 /// 314 /// ```no_run 315 /// # use clap::App; 316 /// App::new("myprog") 317 /// .before_help("Some info I'd like to appear before the help info") 318 /// # ; 319 /// ``` before_help<S: Into<&'b str>>(mut self, help: S) -> Self320 pub fn before_help<S: Into<&'b str>>(mut self, help: S) -> Self { 321 self.p.meta.pre_help = Some(help.into()); 322 self 323 } 324 325 /// Sets a string of the version number to be displayed when displaying version or help 326 /// information with `-V`. 327 /// 328 /// **NOTE:** If only `version` is provided, and not [`App::long_version`] but the user 329 /// requests `--version` clap will still display the contents of `version` appropriately 330 /// 331 /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to automatically set your 332 /// application's version to the same thing as your crate at compile time. See the [`examples/`] 333 /// directory for more information 334 /// 335 /// # Examples 336 /// 337 /// ```no_run 338 /// # use clap::{App, Arg}; 339 /// App::new("myprog") 340 /// .version("v0.1.24") 341 /// # ; 342 /// ``` 343 /// [`crate_version!`]: ./macro.crate_version!.html 344 /// [`examples/`]: https://github.com/clap-rs/clap/tree/v2.33.1/examples 345 /// [`App::long_version`]: ./struct.App.html#method.long_version version<S: Into<&'b str>>(mut self, ver: S) -> Self346 pub fn version<S: Into<&'b str>>(mut self, ver: S) -> Self { 347 self.p.meta.version = Some(ver.into()); 348 self 349 } 350 351 /// Sets a string of the version number to be displayed when displaying version or help 352 /// information with `--version`. 353 /// 354 /// **NOTE:** If only `long_version` is provided, and not [`App::version`] but the user 355 /// requests `-V` clap will still display the contents of `long_version` appropriately 356 /// 357 /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to automatically set your 358 /// application's version to the same thing as your crate at compile time. See the [`examples/`] 359 /// directory for more information 360 /// 361 /// # Examples 362 /// 363 /// ```no_run 364 /// # use clap::{App, Arg}; 365 /// App::new("myprog") 366 /// .long_version( 367 /// "v0.1.24 368 /// commit: abcdef89726d 369 /// revision: 123 370 /// release: 2 371 /// binary: myprog") 372 /// # ; 373 /// ``` 374 /// [`crate_version!`]: ./macro.crate_version!.html 375 /// [`examples/`]: https://github.com/clap-rs/clap/tree/v2.33.1/examples 376 /// [`App::version`]: ./struct.App.html#method.version long_version<S: Into<&'b str>>(mut self, ver: S) -> Self377 pub fn long_version<S: Into<&'b str>>(mut self, ver: S) -> Self { 378 self.p.meta.long_version = Some(ver.into()); 379 self 380 } 381 382 /// Sets a custom usage string to override the auto-generated usage string. 383 /// 384 /// This will be displayed to the user when errors are found in argument parsing, or when you 385 /// call [`ArgMatches::usage`] 386 /// 387 /// **CAUTION:** Using this setting disables `clap`s "context-aware" usage strings. After this 388 /// setting is set, this will be the only usage string displayed to the user! 389 /// 390 /// **NOTE:** You do not need to specify the "USAGE: \n\t" portion, as that will 391 /// still be applied by `clap`, you only need to specify the portion starting 392 /// with the binary name. 393 /// 394 /// **NOTE:** This will not replace the entire help message, *only* the portion 395 /// showing the usage. 396 /// 397 /// # Examples 398 /// 399 /// ```no_run 400 /// # use clap::{App, Arg}; 401 /// App::new("myprog") 402 /// .usage("myapp [-clDas] <some_file>") 403 /// # ; 404 /// ``` 405 /// [`ArgMatches::usage`]: ./struct.ArgMatches.html#method.usage usage<S: Into<&'b str>>(mut self, usage: S) -> Self406 pub fn usage<S: Into<&'b str>>(mut self, usage: S) -> Self { 407 self.p.meta.usage_str = Some(usage.into()); 408 self 409 } 410 411 /// Sets a custom help message and overrides the auto-generated one. This should only be used 412 /// when the auto-generated message does not suffice. 413 /// 414 /// This will be displayed to the user when they use `--help` or `-h` 415 /// 416 /// **NOTE:** This replaces the **entire** help message, so nothing will be auto-generated. 417 /// 418 /// **NOTE:** This **only** replaces the help message for the current command, meaning if you 419 /// are using subcommands, those help messages will still be auto-generated unless you 420 /// specify a [`Arg::help`] for them as well. 421 /// 422 /// # Examples 423 /// 424 /// ```no_run 425 /// # use clap::{App, Arg}; 426 /// App::new("myapp") 427 /// .help("myapp v1.0\n\ 428 /// Does awesome things\n\ 429 /// (C) me@mail.com\n\n\ 430 /// 431 /// USAGE: myapp <opts> <command>\n\n\ 432 /// 433 /// Options:\n\ 434 /// -h, --help Display this message\n\ 435 /// -V, --version Display version info\n\ 436 /// -s <stuff> Do something with stuff\n\ 437 /// -v Be verbose\n\n\ 438 /// 439 /// Commmands:\n\ 440 /// help Prints this message\n\ 441 /// work Do some work") 442 /// # ; 443 /// ``` 444 /// [`Arg::help`]: ./struct.Arg.html#method.help help<S: Into<&'b str>>(mut self, help: S) -> Self445 pub fn help<S: Into<&'b str>>(mut self, help: S) -> Self { 446 self.p.meta.help_str = Some(help.into()); 447 self 448 } 449 450 /// Sets the [`short`] for the auto-generated `help` argument. 451 /// 452 /// By default `clap` automatically assigns `h`, but this can be overridden if you have a 453 /// different argument which you'd prefer to use the `-h` short with. This can be done by 454 /// defining your own argument with a lowercase `h` as the [`short`]. 455 /// 456 /// `clap` lazily generates these `help` arguments **after** you've defined any arguments of 457 /// your own. 458 /// 459 /// **NOTE:** Any leading `-` characters will be stripped, and only the first 460 /// non `-` character will be used as the [`short`] version 461 /// 462 /// # Examples 463 /// 464 /// ```no_run 465 /// # use clap::{App, Arg}; 466 /// App::new("myprog") 467 /// .help_short("H") // Using an uppercase `H` instead of the default lowercase `h` 468 /// # ; 469 /// ``` 470 /// [`short`]: ./struct.Arg.html#method.short help_short<S: AsRef<str> + 'b>(mut self, s: S) -> Self471 pub fn help_short<S: AsRef<str> + 'b>(mut self, s: S) -> Self { 472 self.p.help_short(s.as_ref()); 473 self 474 } 475 476 /// Sets the [`short`] for the auto-generated `version` argument. 477 /// 478 /// By default `clap` automatically assigns `V`, but this can be overridden if you have a 479 /// different argument which you'd prefer to use the `-V` short with. This can be done by 480 /// defining your own argument with an uppercase `V` as the [`short`]. 481 /// 482 /// `clap` lazily generates these `version` arguments **after** you've defined any arguments of 483 /// your own. 484 /// 485 /// **NOTE:** Any leading `-` characters will be stripped, and only the first 486 /// non `-` character will be used as the `short` version 487 /// 488 /// # Examples 489 /// 490 /// ```no_run 491 /// # use clap::{App, Arg}; 492 /// App::new("myprog") 493 /// .version_short("v") // Using a lowercase `v` instead of the default capital `V` 494 /// # ; 495 /// ``` 496 /// [`short`]: ./struct.Arg.html#method.short version_short<S: AsRef<str>>(mut self, s: S) -> Self497 pub fn version_short<S: AsRef<str>>(mut self, s: S) -> Self { 498 self.p.version_short(s.as_ref()); 499 self 500 } 501 502 /// Sets the help text for the auto-generated `help` argument. 503 /// 504 /// By default `clap` sets this to `"Prints help information"`, but if you're using a 505 /// different convention for your help messages and would prefer a different phrasing you can 506 /// override it. 507 /// 508 /// # Examples 509 /// 510 /// ```no_run 511 /// # use clap::{App, Arg}; 512 /// App::new("myprog") 513 /// .help_message("Print help information") // Perhaps you want imperative help messages 514 /// 515 /// # ; 516 /// ``` help_message<S: Into<&'a str>>(mut self, s: S) -> Self517 pub fn help_message<S: Into<&'a str>>(mut self, s: S) -> Self { 518 self.p.help_message = Some(s.into()); 519 self 520 } 521 522 /// Sets the help text for the auto-generated `version` argument. 523 /// 524 /// By default `clap` sets this to `"Prints version information"`, but if you're using a 525 /// different convention for your help messages and would prefer a different phrasing then you 526 /// can change it. 527 /// 528 /// # Examples 529 /// ```no_run 530 /// # use clap::{App, Arg}; 531 /// App::new("myprog") 532 /// .version_message("Print version information") // Perhaps you want imperative help messages 533 /// # ; 534 /// ``` version_message<S: Into<&'a str>>(mut self, s: S) -> Self535 pub fn version_message<S: Into<&'a str>>(mut self, s: S) -> Self { 536 self.p.version_message = Some(s.into()); 537 self 538 } 539 540 /// Sets the help template to be used, overriding the default format. 541 /// 542 /// Tags arg given inside curly brackets. 543 /// 544 /// Valid tags are: 545 /// 546 /// * `{bin}` - Binary name. 547 /// * `{version}` - Version number. 548 /// * `{author}` - Author information. 549 /// * `{about}` - General description (from [`App::about`]) 550 /// * `{usage}` - Automatically generated or given usage string. 551 /// * `{all-args}` - Help for all arguments (options, flags, positionals arguments, 552 /// and subcommands) including titles. 553 /// * `{unified}` - Unified help for options and flags. Note, you must *also* set 554 /// [`AppSettings::UnifiedHelpMessage`] to fully merge both options and 555 /// flags, otherwise the ordering is "best effort" 556 /// * `{flags}` - Help for flags. 557 /// * `{options}` - Help for options. 558 /// * `{positionals}` - Help for positionals arguments. 559 /// * `{subcommands}` - Help for subcommands. 560 /// * `{after-help}` - Help from [`App::after_help`] 561 /// * `{before-help}` - Help from [`App::before_help`] 562 /// 563 /// # Examples 564 /// 565 /// ```no_run 566 /// # use clap::{App, Arg}; 567 /// App::new("myprog") 568 /// .version("1.0") 569 /// .template("{bin} ({version}) - {usage}") 570 /// # ; 571 /// ``` 572 /// **NOTE:** The template system is, on purpose, very simple. Therefore the tags have to be 573 /// written in lowercase and without spacing. 574 /// 575 /// [`App::about`]: ./struct.App.html#method.about 576 /// [`App::after_help`]: ./struct.App.html#method.after_help 577 /// [`App::before_help`]: ./struct.App.html#method.before_help 578 /// [`AppSettings::UnifiedHelpMessage`]: ./enum.AppSettings.html#variant.UnifiedHelpMessage template<S: Into<&'b str>>(mut self, s: S) -> Self579 pub fn template<S: Into<&'b str>>(mut self, s: S) -> Self { 580 self.p.meta.template = Some(s.into()); 581 self 582 } 583 584 /// Enables a single command, or [`SubCommand`], level settings. 585 /// 586 /// See [`AppSettings`] for a full list of possibilities and examples. 587 /// 588 /// # Examples 589 /// 590 /// ```no_run 591 /// # use clap::{App, Arg, AppSettings}; 592 /// App::new("myprog") 593 /// .setting(AppSettings::SubcommandRequired) 594 /// .setting(AppSettings::WaitOnError) 595 /// # ; 596 /// ``` 597 /// [`SubCommand`]: ./struct.SubCommand.html 598 /// [`AppSettings`]: ./enum.AppSettings.html setting(mut self, setting: AppSettings) -> Self599 pub fn setting(mut self, setting: AppSettings) -> Self { 600 self.p.set(setting); 601 self 602 } 603 604 /// Enables multiple command, or [`SubCommand`], level settings 605 /// 606 /// See [`AppSettings`] for a full list of possibilities and examples. 607 /// 608 /// # Examples 609 /// 610 /// ```no_run 611 /// # use clap::{App, Arg, AppSettings}; 612 /// App::new("myprog") 613 /// .settings(&[AppSettings::SubcommandRequired, 614 /// AppSettings::WaitOnError]) 615 /// # ; 616 /// ``` 617 /// [`SubCommand`]: ./struct.SubCommand.html 618 /// [`AppSettings`]: ./enum.AppSettings.html settings(mut self, settings: &[AppSettings]) -> Self619 pub fn settings(mut self, settings: &[AppSettings]) -> Self { 620 for s in settings { 621 self.p.set(*s); 622 } 623 self 624 } 625 626 /// Enables a single setting that is propagated down through all child [`SubCommand`]s. 627 /// 628 /// See [`AppSettings`] for a full list of possibilities and examples. 629 /// 630 /// **NOTE**: The setting is *only* propagated *down* and not up through parent commands. 631 /// 632 /// # Examples 633 /// 634 /// ```no_run 635 /// # use clap::{App, Arg, AppSettings}; 636 /// App::new("myprog") 637 /// .global_setting(AppSettings::SubcommandRequired) 638 /// # ; 639 /// ``` 640 /// [`SubCommand`]: ./struct.SubCommand.html 641 /// [`AppSettings`]: ./enum.AppSettings.html global_setting(mut self, setting: AppSettings) -> Self642 pub fn global_setting(mut self, setting: AppSettings) -> Self { 643 self.p.set(setting); 644 self.p.g_settings.set(setting); 645 self 646 } 647 648 /// Enables multiple settings which are propagated *down* through all child [`SubCommand`]s. 649 /// 650 /// See [`AppSettings`] for a full list of possibilities and examples. 651 /// 652 /// **NOTE**: The setting is *only* propagated *down* and not up through parent commands. 653 /// 654 /// # Examples 655 /// 656 /// ```no_run 657 /// # use clap::{App, Arg, AppSettings}; 658 /// App::new("myprog") 659 /// .global_settings(&[AppSettings::SubcommandRequired, 660 /// AppSettings::ColoredHelp]) 661 /// # ; 662 /// ``` 663 /// [`SubCommand`]: ./struct.SubCommand.html 664 /// [`AppSettings`]: ./enum.AppSettings.html global_settings(mut self, settings: &[AppSettings]) -> Self665 pub fn global_settings(mut self, settings: &[AppSettings]) -> Self { 666 for s in settings { 667 self.p.set(*s); 668 self.p.g_settings.set(*s) 669 } 670 self 671 } 672 673 /// Disables a single command, or [`SubCommand`], level setting. 674 /// 675 /// See [`AppSettings`] for a full list of possibilities and examples. 676 /// 677 /// # Examples 678 /// 679 /// ```no_run 680 /// # use clap::{App, AppSettings}; 681 /// App::new("myprog") 682 /// .unset_setting(AppSettings::ColorAuto) 683 /// # ; 684 /// ``` 685 /// [`SubCommand`]: ./struct.SubCommand.html 686 /// [`AppSettings`]: ./enum.AppSettings.html unset_setting(mut self, setting: AppSettings) -> Self687 pub fn unset_setting(mut self, setting: AppSettings) -> Self { 688 self.p.unset(setting); 689 self 690 } 691 692 /// Disables multiple command, or [`SubCommand`], level settings. 693 /// 694 /// See [`AppSettings`] for a full list of possibilities and examples. 695 /// 696 /// # Examples 697 /// 698 /// ```no_run 699 /// # use clap::{App, AppSettings}; 700 /// App::new("myprog") 701 /// .unset_settings(&[AppSettings::ColorAuto, 702 /// AppSettings::AllowInvalidUtf8]) 703 /// # ; 704 /// ``` 705 /// [`SubCommand`]: ./struct.SubCommand.html 706 /// [`AppSettings`]: ./enum.AppSettings.html unset_settings(mut self, settings: &[AppSettings]) -> Self707 pub fn unset_settings(mut self, settings: &[AppSettings]) -> Self { 708 for s in settings { 709 self.p.unset(*s); 710 } 711 self 712 } 713 714 /// Sets the terminal width at which to wrap help messages. Defaults to `120`. Using `0` will 715 /// ignore terminal widths and use source formatting. 716 /// 717 /// `clap` automatically tries to determine the terminal width on Unix, Linux, macOS and Windows 718 /// if the `wrap_help` cargo "feature" has been used while compiling. If the terminal width 719 /// cannot be determined, `clap` defaults to `120`. 720 /// 721 /// **NOTE:** This setting applies globally and *not* on a per-command basis. 722 /// 723 /// **NOTE:** This setting must be set **before** any subcommands are added! 724 /// 725 /// # Platform Specific 726 /// 727 /// Only Unix, Linux, macOS and Windows support automatic determination of terminal width. 728 /// Even on those platforms, this setting is useful if for any reason the terminal width 729 /// cannot be determined. 730 /// 731 /// # Examples 732 /// 733 /// ```no_run 734 /// # use clap::App; 735 /// App::new("myprog") 736 /// .set_term_width(80) 737 /// # ; 738 /// ``` set_term_width(mut self, width: usize) -> Self739 pub fn set_term_width(mut self, width: usize) -> Self { 740 self.p.meta.term_w = Some(width); 741 self 742 } 743 744 /// Sets the max terminal width at which to wrap help messages. Using `0` will ignore terminal 745 /// widths and use source formatting. 746 /// 747 /// `clap` automatically tries to determine the terminal width on Unix, Linux, macOS and Windows 748 /// if the `wrap_help` cargo "feature" has been used while compiling, but one might want to 749 /// limit the size (e.g. when the terminal is running fullscreen). 750 /// 751 /// **NOTE:** This setting applies globally and *not* on a per-command basis. 752 /// 753 /// **NOTE:** This setting must be set **before** any subcommands are added! 754 /// 755 /// # Platform Specific 756 /// 757 /// Only Unix, Linux, macOS and Windows support automatic determination of terminal width. 758 /// 759 /// # Examples 760 /// 761 /// ```no_run 762 /// # use clap::App; 763 /// App::new("myprog") 764 /// .max_term_width(100) 765 /// # ; 766 /// ``` max_term_width(mut self, w: usize) -> Self767 pub fn max_term_width(mut self, w: usize) -> Self { 768 self.p.meta.max_w = Some(w); 769 self 770 } 771 772 /// Adds an [argument] to the list of valid possibilities. 773 /// 774 /// # Examples 775 /// 776 /// ```no_run 777 /// # use clap::{App, Arg}; 778 /// App::new("myprog") 779 /// // Adding a single "flag" argument with a short and help text, using Arg::with_name() 780 /// .arg( 781 /// Arg::with_name("debug") 782 /// .short("d") 783 /// .help("turns on debugging mode") 784 /// ) 785 /// // Adding a single "option" argument with a short, a long, and help text using the less 786 /// // verbose Arg::from_usage() 787 /// .arg( 788 /// Arg::from_usage("-c --config=[CONFIG] 'Optionally sets a config file to use'") 789 /// ) 790 /// # ; 791 /// ``` 792 /// [argument]: ./struct.Arg.html arg<A: Into<Arg<'a, 'b>>>(mut self, a: A) -> Self793 pub fn arg<A: Into<Arg<'a, 'b>>>(mut self, a: A) -> Self { 794 self.p.add_arg(a.into()); 795 self 796 } 797 798 /// Adds multiple [arguments] to the list of valid possibilities 799 /// 800 /// # Examples 801 /// 802 /// ```no_run 803 /// # use clap::{App, Arg}; 804 /// App::new("myprog") 805 /// .args( 806 /// &[Arg::from_usage("[debug] -d 'turns on debugging info'"), 807 /// Arg::with_name("input").index(1).help("the input file to use")] 808 /// ) 809 /// # ; 810 /// ``` 811 /// [arguments]: ./struct.Arg.html args(mut self, args: &[Arg<'a, 'b>]) -> Self812 pub fn args(mut self, args: &[Arg<'a, 'b>]) -> Self { 813 for arg in args { 814 self.p.add_arg_ref(arg); 815 } 816 self 817 } 818 819 /// A convenience method for adding a single [argument] from a usage type string. The string 820 /// used follows the same rules and syntax as [`Arg::from_usage`] 821 /// 822 /// **NOTE:** The downside to using this method is that you can not set any additional 823 /// properties of the [`Arg`] other than what [`Arg::from_usage`] supports. 824 /// 825 /// # Examples 826 /// 827 /// ```no_run 828 /// # use clap::{App, Arg}; 829 /// App::new("myprog") 830 /// .arg_from_usage("-c --config=<FILE> 'Sets a configuration file to use'") 831 /// # ; 832 /// ``` 833 /// [argument]: ./struct.Arg.html 834 /// [`Arg`]: ./struct.Arg.html 835 /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage arg_from_usage(mut self, usage: &'a str) -> Self836 pub fn arg_from_usage(mut self, usage: &'a str) -> Self { 837 self.p.add_arg(Arg::from_usage(usage)); 838 self 839 } 840 841 /// Adds multiple [arguments] at once from a usage string, one per line. See 842 /// [`Arg::from_usage`] for details on the syntax and rules supported. 843 /// 844 /// **NOTE:** Like [`App::arg_from_usage`] the downside is you only set properties for the 845 /// [`Arg`]s which [`Arg::from_usage`] supports. 846 /// 847 /// # Examples 848 /// 849 /// ```no_run 850 /// # use clap::{App, Arg}; 851 /// App::new("myprog") 852 /// .args_from_usage( 853 /// "-c --config=[FILE] 'Sets a configuration file to use' 854 /// [debug]... -d 'Sets the debugging level' 855 /// <FILE> 'The input file to use'" 856 /// ) 857 /// # ; 858 /// ``` 859 /// [arguments]: ./struct.Arg.html 860 /// [`Arg::from_usage`]: ./struct.Arg.html#method.from_usage 861 /// [`App::arg_from_usage`]: ./struct.App.html#method.arg_from_usage 862 /// [`Arg`]: ./struct.Arg.html args_from_usage(mut self, usage: &'a str) -> Self863 pub fn args_from_usage(mut self, usage: &'a str) -> Self { 864 for line in usage.lines() { 865 let l = line.trim(); 866 if l.is_empty() { 867 continue; 868 } 869 self.p.add_arg(Arg::from_usage(l)); 870 } 871 self 872 } 873 874 /// Allows adding a [`SubCommand`] alias, which function as "hidden" subcommands that 875 /// automatically dispatch as if this subcommand was used. This is more efficient, and easier 876 /// than creating multiple hidden subcommands as one only needs to check for the existence of 877 /// this command, and not all variants. 878 /// 879 /// # Examples 880 /// 881 /// ```no_run 882 /// # use clap::{App, Arg, SubCommand}; 883 /// let m = App::new("myprog") 884 /// .subcommand(SubCommand::with_name("test") 885 /// .alias("do-stuff")) 886 /// .get_matches_from(vec!["myprog", "do-stuff"]); 887 /// assert_eq!(m.subcommand_name(), Some("test")); 888 /// ``` 889 /// [`SubCommand`]: ./struct.SubCommand.html alias<S: Into<&'b str>>(mut self, name: S) -> Self890 pub fn alias<S: Into<&'b str>>(mut self, name: S) -> Self { 891 if let Some(ref mut als) = self.p.meta.aliases { 892 als.push((name.into(), false)); 893 } else { 894 self.p.meta.aliases = Some(vec![(name.into(), false)]); 895 } 896 self 897 } 898 899 /// Allows adding [`SubCommand`] aliases, which function as "hidden" subcommands that 900 /// automatically dispatch as if this subcommand was used. This is more efficient, and easier 901 /// than creating multiple hidden subcommands as one only needs to check for the existence of 902 /// this command, and not all variants. 903 /// 904 /// # Examples 905 /// 906 /// ```rust 907 /// # use clap::{App, Arg, SubCommand}; 908 /// let m = App::new("myprog") 909 /// .subcommand(SubCommand::with_name("test") 910 /// .aliases(&["do-stuff", "do-tests", "tests"])) 911 /// .arg(Arg::with_name("input") 912 /// .help("the file to add") 913 /// .index(1) 914 /// .required(false)) 915 /// .get_matches_from(vec!["myprog", "do-tests"]); 916 /// assert_eq!(m.subcommand_name(), Some("test")); 917 /// ``` 918 /// [`SubCommand`]: ./struct.SubCommand.html aliases(mut self, names: &[&'b str]) -> Self919 pub fn aliases(mut self, names: &[&'b str]) -> Self { 920 if let Some(ref mut als) = self.p.meta.aliases { 921 for n in names { 922 als.push((n, false)); 923 } 924 } else { 925 self.p.meta.aliases = Some(names.iter().map(|n| (*n, false)).collect::<Vec<_>>()); 926 } 927 self 928 } 929 930 /// Allows adding a [`SubCommand`] alias that functions exactly like those defined with 931 /// [`App::alias`], except that they are visible inside the help message. 932 /// 933 /// # Examples 934 /// 935 /// ```no_run 936 /// # use clap::{App, Arg, SubCommand}; 937 /// let m = App::new("myprog") 938 /// .subcommand(SubCommand::with_name("test") 939 /// .visible_alias("do-stuff")) 940 /// .get_matches_from(vec!["myprog", "do-stuff"]); 941 /// assert_eq!(m.subcommand_name(), Some("test")); 942 /// ``` 943 /// [`SubCommand`]: ./struct.SubCommand.html 944 /// [`App::alias`]: ./struct.App.html#method.alias visible_alias<S: Into<&'b str>>(mut self, name: S) -> Self945 pub fn visible_alias<S: Into<&'b str>>(mut self, name: S) -> Self { 946 if let Some(ref mut als) = self.p.meta.aliases { 947 als.push((name.into(), true)); 948 } else { 949 self.p.meta.aliases = Some(vec![(name.into(), true)]); 950 } 951 self 952 } 953 954 /// Allows adding multiple [`SubCommand`] aliases that functions exactly like those defined 955 /// with [`App::aliases`], except that they are visible inside the help message. 956 /// 957 /// # Examples 958 /// 959 /// ```no_run 960 /// # use clap::{App, Arg, SubCommand}; 961 /// let m = App::new("myprog") 962 /// .subcommand(SubCommand::with_name("test") 963 /// .visible_aliases(&["do-stuff", "tests"])) 964 /// .get_matches_from(vec!["myprog", "do-stuff"]); 965 /// assert_eq!(m.subcommand_name(), Some("test")); 966 /// ``` 967 /// [`SubCommand`]: ./struct.SubCommand.html 968 /// [`App::aliases`]: ./struct.App.html#method.aliases visible_aliases(mut self, names: &[&'b str]) -> Self969 pub fn visible_aliases(mut self, names: &[&'b str]) -> Self { 970 if let Some(ref mut als) = self.p.meta.aliases { 971 for n in names { 972 als.push((n, true)); 973 } 974 } else { 975 self.p.meta.aliases = Some(names.iter().map(|n| (*n, true)).collect::<Vec<_>>()); 976 } 977 self 978 } 979 980 /// Adds an [`ArgGroup`] to the application. [`ArgGroup`]s are a family of related arguments. 981 /// By placing them in a logical group, you can build easier requirement and exclusion rules. 982 /// For instance, you can make an entire [`ArgGroup`] required, meaning that one (and *only* 983 /// one) argument from that group must be present at runtime. 984 /// 985 /// You can also do things such as name an [`ArgGroup`] as a conflict to another argument. 986 /// Meaning any of the arguments that belong to that group will cause a failure if present with 987 /// the conflicting argument. 988 /// 989 /// Another added benefit of [`ArgGroup`]s is that you can extract a value from a group instead 990 /// of determining exactly which argument was used. 991 /// 992 /// Finally, using [`ArgGroup`]s to ensure exclusion between arguments is another very common 993 /// use 994 /// 995 /// # Examples 996 /// 997 /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one, 998 /// of the arguments from the specified group is present at runtime. 999 /// 1000 /// ```no_run 1001 /// # use clap::{App, ArgGroup}; 1002 /// App::new("app") 1003 /// .args_from_usage( 1004 /// "--set-ver [ver] 'set the version manually' 1005 /// --major 'auto increase major' 1006 /// --minor 'auto increase minor' 1007 /// --patch 'auto increase patch'") 1008 /// .group(ArgGroup::with_name("vers") 1009 /// .args(&["set-ver", "major", "minor","patch"]) 1010 /// .required(true)) 1011 /// # ; 1012 /// ``` 1013 /// [`ArgGroup`]: ./struct.ArgGroup.html group(mut self, group: ArgGroup<'a>) -> Self1014 pub fn group(mut self, group: ArgGroup<'a>) -> Self { 1015 self.p.add_group(group); 1016 self 1017 } 1018 1019 /// Adds multiple [`ArgGroup`]s to the [`App`] at once. 1020 /// 1021 /// # Examples 1022 /// 1023 /// ```no_run 1024 /// # use clap::{App, ArgGroup}; 1025 /// App::new("app") 1026 /// .args_from_usage( 1027 /// "--set-ver [ver] 'set the version manually' 1028 /// --major 'auto increase major' 1029 /// --minor 'auto increase minor' 1030 /// --patch 'auto increase patch' 1031 /// -c [FILE] 'a config file' 1032 /// -i [IFACE] 'an interface'") 1033 /// .groups(&[ 1034 /// ArgGroup::with_name("vers") 1035 /// .args(&["set-ver", "major", "minor","patch"]) 1036 /// .required(true), 1037 /// ArgGroup::with_name("input") 1038 /// .args(&["c", "i"]) 1039 /// ]) 1040 /// # ; 1041 /// ``` 1042 /// [`ArgGroup`]: ./struct.ArgGroup.html 1043 /// [`App`]: ./struct.App.html groups(mut self, groups: &[ArgGroup<'a>]) -> Self1044 pub fn groups(mut self, groups: &[ArgGroup<'a>]) -> Self { 1045 for g in groups { 1046 self = self.group(g.into()); 1047 } 1048 self 1049 } 1050 1051 /// Adds a [`SubCommand`] to the list of valid possibilities. Subcommands are effectively 1052 /// sub-[`App`]s, because they can contain their own arguments, subcommands, version, usage, 1053 /// etc. They also function just like [`App`]s, in that they get their own auto generated help, 1054 /// version, and usage. 1055 /// 1056 /// # Examples 1057 /// 1058 /// ```no_run 1059 /// # use clap::{App, Arg, SubCommand}; 1060 /// App::new("myprog") 1061 /// .subcommand(SubCommand::with_name("config") 1062 /// .about("Controls configuration features") 1063 /// .arg_from_usage("<config> 'Required configuration file to use'")) 1064 /// # ; 1065 /// ``` 1066 /// [`SubCommand`]: ./struct.SubCommand.html 1067 /// [`App`]: ./struct.App.html subcommand(mut self, subcmd: App<'a, 'b>) -> Self1068 pub fn subcommand(mut self, subcmd: App<'a, 'b>) -> Self { 1069 self.p.add_subcommand(subcmd); 1070 self 1071 } 1072 1073 /// Adds multiple subcommands to the list of valid possibilities by iterating over an 1074 /// [`IntoIterator`] of [`SubCommand`]s 1075 /// 1076 /// # Examples 1077 /// 1078 /// ```rust 1079 /// # use clap::{App, Arg, SubCommand}; 1080 /// # App::new("myprog") 1081 /// .subcommands( vec![ 1082 /// SubCommand::with_name("config").about("Controls configuration functionality") 1083 /// .arg(Arg::with_name("config_file").index(1)), 1084 /// SubCommand::with_name("debug").about("Controls debug functionality")]) 1085 /// # ; 1086 /// ``` 1087 /// [`SubCommand`]: ./struct.SubCommand.html 1088 /// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html subcommands<I>(mut self, subcmds: I) -> Self where I: IntoIterator<Item = App<'a, 'b>>,1089 pub fn subcommands<I>(mut self, subcmds: I) -> Self 1090 where 1091 I: IntoIterator<Item = App<'a, 'b>>, 1092 { 1093 for subcmd in subcmds { 1094 self.p.add_subcommand(subcmd); 1095 } 1096 self 1097 } 1098 1099 /// Allows custom ordering of [`SubCommand`]s within the help message. Subcommands with a lower 1100 /// value will be displayed first in the help message. This is helpful when one would like to 1101 /// emphasise frequently used subcommands, or prioritize those towards the top of the list. 1102 /// Duplicate values **are** allowed. Subcommands with duplicate display orders will be 1103 /// displayed in alphabetical order. 1104 /// 1105 /// **NOTE:** The default is 999 for all subcommands. 1106 /// 1107 /// # Examples 1108 /// 1109 /// ```rust 1110 /// # use clap::{App, SubCommand}; 1111 /// let m = App::new("cust-ord") 1112 /// .subcommand(SubCommand::with_name("alpha") // typically subcommands are grouped 1113 /// // alphabetically by name. Subcommands 1114 /// // without a display_order have a value of 1115 /// // 999 and are displayed alphabetically with 1116 /// // all other 999 subcommands 1117 /// .about("Some help and text")) 1118 /// .subcommand(SubCommand::with_name("beta") 1119 /// .display_order(1) // In order to force this subcommand to appear *first* 1120 /// // all we have to do is give it a value lower than 999. 1121 /// // Any other subcommands with a value of 1 will be displayed 1122 /// // alphabetically with this one...then 2 values, then 3, etc. 1123 /// .about("I should be first!")) 1124 /// .get_matches_from(vec![ 1125 /// "cust-ord", "--help" 1126 /// ]); 1127 /// ``` 1128 /// 1129 /// The above example displays the following help message 1130 /// 1131 /// ```text 1132 /// cust-ord 1133 /// 1134 /// USAGE: 1135 /// cust-ord [FLAGS] [OPTIONS] 1136 /// 1137 /// FLAGS: 1138 /// -h, --help Prints help information 1139 /// -V, --version Prints version information 1140 /// 1141 /// SUBCOMMANDS: 1142 /// beta I should be first! 1143 /// alpha Some help and text 1144 /// ``` 1145 /// [`SubCommand`]: ./struct.SubCommand.html display_order(mut self, ord: usize) -> Self1146 pub fn display_order(mut self, ord: usize) -> Self { 1147 self.p.meta.disp_ord = ord; 1148 self 1149 } 1150 1151 /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same 1152 /// method as if someone ran `-h` to request the help message 1153 /// 1154 /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages 1155 /// depending on if the user ran [`-h` (short)] or [`--help` (long)] 1156 /// 1157 /// # Examples 1158 /// 1159 /// ```rust 1160 /// # use clap::App; 1161 /// let mut app = App::new("myprog"); 1162 /// app.print_help(); 1163 /// ``` 1164 /// [`io::stdout()`]: https://doc.rust-lang.org/std/io/fn.stdout.html 1165 /// [`BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html 1166 /// [`-h` (short)]: ./struct.Arg.html#method.help 1167 /// [`--help` (long)]: ./struct.Arg.html#method.long_help print_help(&mut self) -> ClapResult<()>1168 pub fn print_help(&mut self) -> ClapResult<()> { 1169 // If there are global arguments, or settings we need to propagate them down to subcommands 1170 // before parsing incase we run into a subcommand 1171 self.p.propagate_globals(); 1172 self.p.propagate_settings(); 1173 self.p.derive_display_order(); 1174 1175 self.p.create_help_and_version(); 1176 let out = io::stdout(); 1177 let mut buf_w = BufWriter::new(out.lock()); 1178 self.write_help(&mut buf_w) 1179 } 1180 1181 /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same 1182 /// method as if someone ran `--help` to request the help message 1183 /// 1184 /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages 1185 /// depending on if the user ran [`-h` (short)] or [`--help` (long)] 1186 /// 1187 /// # Examples 1188 /// 1189 /// ```rust 1190 /// # use clap::App; 1191 /// let mut app = App::new("myprog"); 1192 /// app.print_long_help(); 1193 /// ``` 1194 /// [`io::stdout()`]: https://doc.rust-lang.org/std/io/fn.stdout.html 1195 /// [`BufWriter`]: https://doc.rust-lang.org/std/io/struct.BufWriter.html 1196 /// [`-h` (short)]: ./struct.Arg.html#method.help 1197 /// [`--help` (long)]: ./struct.Arg.html#method.long_help print_long_help(&mut self) -> ClapResult<()>1198 pub fn print_long_help(&mut self) -> ClapResult<()> { 1199 let out = io::stdout(); 1200 let mut buf_w = BufWriter::new(out.lock()); 1201 self.write_long_help(&mut buf_w) 1202 } 1203 1204 /// Writes the full help message to the user to a [`io::Write`] object in the same method as if 1205 /// the user ran `-h` 1206 /// 1207 /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages 1208 /// depending on if the user ran [`-h` (short)] or [`--help` (long)] 1209 /// 1210 /// **NOTE:** There is a known bug where this method does not write propagated global arguments 1211 /// or autogenerated arguments (i.e. the default help/version args). Prefer 1212 /// [`App::write_long_help`] instead if possible! 1213 /// 1214 /// # Examples 1215 /// 1216 /// ```rust 1217 /// # use clap::App; 1218 /// use std::io; 1219 /// let mut app = App::new("myprog"); 1220 /// let mut out = io::stdout(); 1221 /// app.write_help(&mut out).expect("failed to write to stdout"); 1222 /// ``` 1223 /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 1224 /// [`-h` (short)]: ./struct.Arg.html#method.help 1225 /// [`--help` (long)]: ./struct.Arg.html#method.long_help write_help<W: Write>(&self, w: &mut W) -> ClapResult<()>1226 pub fn write_help<W: Write>(&self, w: &mut W) -> ClapResult<()> { 1227 // PENDING ISSUE: 808 1228 // https://github.com/clap-rs/clap/issues/808 1229 // If there are global arguments, or settings we need to propagate them down to subcommands 1230 // before parsing incase we run into a subcommand 1231 // self.p.propagate_globals(); 1232 // self.p.propagate_settings(); 1233 // self.p.derive_display_order(); 1234 // self.p.create_help_and_version(); 1235 1236 Help::write_app_help(w, self, false) 1237 } 1238 1239 /// Writes the full help message to the user to a [`io::Write`] object in the same method as if 1240 /// the user ran `--help` 1241 /// 1242 /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages 1243 /// depending on if the user ran [`-h` (short)] or [`--help` (long)] 1244 /// 1245 /// # Examples 1246 /// 1247 /// ```rust 1248 /// # use clap::App; 1249 /// use std::io; 1250 /// let mut app = App::new("myprog"); 1251 /// let mut out = io::stdout(); 1252 /// app.write_long_help(&mut out).expect("failed to write to stdout"); 1253 /// ``` 1254 /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 1255 /// [`-h` (short)]: ./struct.Arg.html#method.help 1256 /// [`--help` (long)]: ./struct.Arg.html#method.long_help write_long_help<W: Write>(&mut self, w: &mut W) -> ClapResult<()>1257 pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> ClapResult<()> { 1258 // If there are global arguments, or settings we need to propagate them down to subcommands 1259 // before parsing incase we run into a subcommand 1260 self.p.propagate_globals(); 1261 self.p.propagate_settings(); 1262 self.p.derive_display_order(); 1263 self.p.create_help_and_version(); 1264 1265 Help::write_app_help(w, self, true) 1266 } 1267 1268 /// Writes the version message to the user to a [`io::Write`] object as if the user ran `-V`. 1269 /// 1270 /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages 1271 /// depending on if the user ran [`-V` (short)] or [`--version` (long)] 1272 /// 1273 /// # Examples 1274 /// 1275 /// ```rust 1276 /// # use clap::App; 1277 /// use std::io; 1278 /// let mut app = App::new("myprog"); 1279 /// let mut out = io::stdout(); 1280 /// app.write_version(&mut out).expect("failed to write to stdout"); 1281 /// ``` 1282 /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 1283 /// [`-V` (short)]: ./struct.App.html#method.version 1284 /// [`--version` (long)]: ./struct.App.html#method.long_version write_version<W: Write>(&self, w: &mut W) -> ClapResult<()>1285 pub fn write_version<W: Write>(&self, w: &mut W) -> ClapResult<()> { 1286 self.p.write_version(w, false).map_err(From::from) 1287 } 1288 1289 /// Writes the version message to the user to a [`io::Write`] object 1290 /// 1291 /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages 1292 /// depending on if the user ran [`-V` (short)] or [`--version` (long)] 1293 /// 1294 /// # Examples 1295 /// 1296 /// ```rust 1297 /// # use clap::App; 1298 /// use std::io; 1299 /// let mut app = App::new("myprog"); 1300 /// let mut out = io::stdout(); 1301 /// app.write_long_version(&mut out).expect("failed to write to stdout"); 1302 /// ``` 1303 /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html 1304 /// [`-V` (short)]: ./struct.App.html#method.version 1305 /// [`--version` (long)]: ./struct.App.html#method.long_version write_long_version<W: Write>(&self, w: &mut W) -> ClapResult<()>1306 pub fn write_long_version<W: Write>(&self, w: &mut W) -> ClapResult<()> { 1307 self.p.write_version(w, true).map_err(From::from) 1308 } 1309 1310 /// Generate a completions file for a specified shell at compile time. 1311 /// 1312 /// **NOTE:** to generate the file at compile time you must use a `build.rs` "Build Script" 1313 /// 1314 /// # Examples 1315 /// 1316 /// The following example generates a bash completion script via a `build.rs` script. In this 1317 /// simple example, we'll demo a very small application with only a single subcommand and two 1318 /// args. Real applications could be many multiple levels deep in subcommands, and have tens or 1319 /// potentially hundreds of arguments. 1320 /// 1321 /// First, it helps if we separate out our `App` definition into a separate file. Whether you 1322 /// do this as a function, or bare App definition is a matter of personal preference. 1323 /// 1324 /// ``` 1325 /// // src/cli.rs 1326 /// 1327 /// use clap::{App, Arg, SubCommand}; 1328 /// 1329 /// pub fn build_cli() -> App<'static, 'static> { 1330 /// App::new("compl") 1331 /// .about("Tests completions") 1332 /// .arg(Arg::with_name("file") 1333 /// .help("some input file")) 1334 /// .subcommand(SubCommand::with_name("test") 1335 /// .about("tests things") 1336 /// .arg(Arg::with_name("case") 1337 /// .long("case") 1338 /// .takes_value(true) 1339 /// .help("the case to test"))) 1340 /// } 1341 /// ``` 1342 /// 1343 /// In our regular code, we can simply call this `build_cli()` function, then call 1344 /// `get_matches()`, or any of the other normal methods directly after. For example: 1345 /// 1346 /// ```ignore 1347 /// // src/main.rs 1348 /// 1349 /// mod cli; 1350 /// 1351 /// fn main() { 1352 /// let m = cli::build_cli().get_matches(); 1353 /// 1354 /// // normal logic continues... 1355 /// } 1356 /// ``` 1357 /// 1358 /// Next, we set up our `Cargo.toml` to use a `build.rs` build script. 1359 /// 1360 /// ```toml 1361 /// # Cargo.toml 1362 /// build = "build.rs" 1363 /// 1364 /// [build-dependencies] 1365 /// clap = "2.23" 1366 /// ``` 1367 /// 1368 /// Next, we place a `build.rs` in our project root. 1369 /// 1370 /// ```ignore 1371 /// extern crate clap; 1372 /// 1373 /// use clap::Shell; 1374 /// 1375 /// include!("src/cli.rs"); 1376 /// 1377 /// fn main() { 1378 /// let outdir = match env::var_os("OUT_DIR") { 1379 /// None => return, 1380 /// Some(outdir) => outdir, 1381 /// }; 1382 /// let mut app = build_cli(); 1383 /// app.gen_completions("myapp", // We need to specify the bin name manually 1384 /// Shell::Bash, // Then say which shell to build completions for 1385 /// outdir); // Then say where write the completions to 1386 /// } 1387 /// ``` 1388 /// Now, once we compile there will be a `{bin_name}.bash` file in the directory. 1389 /// Assuming we compiled with debug mode, it would be somewhere similar to 1390 /// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash`. 1391 /// 1392 /// Fish shell completions will use the file format `{bin_name}.fish` gen_completions<T: Into<OsString>, S: Into<String>>( &mut self, bin_name: S, for_shell: Shell, out_dir: T, )1393 pub fn gen_completions<T: Into<OsString>, S: Into<String>>( 1394 &mut self, 1395 bin_name: S, 1396 for_shell: Shell, 1397 out_dir: T, 1398 ) { 1399 self.p.meta.bin_name = Some(bin_name.into()); 1400 self.p.gen_completions(for_shell, out_dir.into()); 1401 } 1402 1403 /// Generate a completions file for a specified shell at runtime. Until `cargo install` can 1404 /// install extra files like a completion script, this may be used e.g. in a command that 1405 /// outputs the contents of the completion script, to be redirected into a file by the user. 1406 /// 1407 /// # Examples 1408 /// 1409 /// Assuming a separate `cli.rs` like the [example above](./struct.App.html#method.gen_completions), 1410 /// we can let users generate a completion script using a command: 1411 /// 1412 /// ```ignore 1413 /// // src/main.rs 1414 /// 1415 /// mod cli; 1416 /// use std::io; 1417 /// 1418 /// fn main() { 1419 /// let matches = cli::build_cli().get_matches(); 1420 /// 1421 /// if matches.is_present("generate-bash-completions") { 1422 /// cli::build_cli().gen_completions_to("myapp", Shell::Bash, &mut io::stdout()); 1423 /// } 1424 /// 1425 /// // normal logic continues... 1426 /// } 1427 /// 1428 /// ``` 1429 /// 1430 /// Usage: 1431 /// 1432 /// ```shell 1433 /// $ myapp generate-bash-completions > /usr/share/bash-completion/completions/myapp.bash 1434 /// ``` gen_completions_to<W: Write, S: Into<String>>( &mut self, bin_name: S, for_shell: Shell, buf: &mut W, )1435 pub fn gen_completions_to<W: Write, S: Into<String>>( 1436 &mut self, 1437 bin_name: S, 1438 for_shell: Shell, 1439 buf: &mut W, 1440 ) { 1441 self.p.meta.bin_name = Some(bin_name.into()); 1442 self.p.gen_completions_to(for_shell, buf); 1443 } 1444 1445 /// Starts the parsing process, upon a failed parse an error will be displayed to the user and 1446 /// the process will exit with the appropriate error code. By default this method gets all user 1447 /// provided arguments from [`env::args_os`] in order to allow for invalid UTF-8 code points, 1448 /// which are legal on many platforms. 1449 /// 1450 /// # Examples 1451 /// 1452 /// ```no_run 1453 /// # use clap::{App, Arg}; 1454 /// let matches = App::new("myprog") 1455 /// // Args and options go here... 1456 /// .get_matches(); 1457 /// ``` 1458 /// [`env::args_os`]: https://doc.rust-lang.org/std/env/fn.args_os.html get_matches(self) -> ArgMatches<'a>1459 pub fn get_matches(self) -> ArgMatches<'a> { 1460 self.get_matches_from(&mut env::args_os()) 1461 } 1462 1463 /// Starts the parsing process. This method will return a [`clap::Result`] type instead of exiting 1464 /// the process on failed parse. By default this method gets matches from [`env::args_os`] 1465 /// 1466 /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are 1467 /// used. It will return a [`clap::Error`], where the [`kind`] is a 1468 /// [`ErrorKind::HelpDisplayed`] or [`ErrorKind::VersionDisplayed`] respectively. You must call 1469 /// [`Error::exit`] or perform a [`std::process::exit`]. 1470 /// 1471 /// # Examples 1472 /// 1473 /// ```no_run 1474 /// # use clap::{App, Arg}; 1475 /// let matches = App::new("myprog") 1476 /// // Args and options go here... 1477 /// .get_matches_safe() 1478 /// .unwrap_or_else( |e| e.exit() ); 1479 /// ``` 1480 /// [`env::args_os`]: https://doc.rust-lang.org/std/env/fn.args_os.html 1481 /// [`ErrorKind::HelpDisplayed`]: ./enum.ErrorKind.html#variant.HelpDisplayed 1482 /// [`ErrorKind::VersionDisplayed`]: ./enum.ErrorKind.html#variant.VersionDisplayed 1483 /// [`Error::exit`]: ./struct.Error.html#method.exit 1484 /// [`std::process::exit`]: https://doc.rust-lang.org/std/process/fn.exit.html 1485 /// [`clap::Result`]: ./type.Result.html 1486 /// [`clap::Error`]: ./struct.Error.html 1487 /// [`kind`]: ./struct.Error.html get_matches_safe(self) -> ClapResult<ArgMatches<'a>>1488 pub fn get_matches_safe(self) -> ClapResult<ArgMatches<'a>> { 1489 // Start the parsing 1490 self.get_matches_from_safe(&mut env::args_os()) 1491 } 1492 1493 /// Starts the parsing process. Like [`App::get_matches`] this method does not return a [`clap::Result`] 1494 /// and will automatically exit with an error message. This method, however, lets you specify 1495 /// what iterator to use when performing matches, such as a [`Vec`] of your making. 1496 /// 1497 /// **NOTE:** The first argument will be parsed as the binary name unless 1498 /// [`AppSettings::NoBinaryName`] is used 1499 /// 1500 /// # Examples 1501 /// 1502 /// ```no_run 1503 /// # use clap::{App, Arg}; 1504 /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; 1505 /// 1506 /// let matches = App::new("myprog") 1507 /// // Args and options go here... 1508 /// .get_matches_from(arg_vec); 1509 /// ``` 1510 /// [`App::get_matches`]: ./struct.App.html#method.get_matches 1511 /// [`clap::Result`]: ./type.Result.html 1512 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html 1513 /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName get_matches_from<I, T>(mut self, itr: I) -> ArgMatches<'a> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,1514 pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches<'a> 1515 where 1516 I: IntoIterator<Item = T>, 1517 T: Into<OsString> + Clone, 1518 { 1519 self.get_matches_from_safe_borrow(itr).unwrap_or_else(|e| { 1520 // Otherwise, write to stderr and exit 1521 if e.use_stderr() { 1522 wlnerr!("{}", e.message); 1523 if self.p.is_set(AppSettings::WaitOnError) { 1524 wlnerr!("\nPress [ENTER] / [RETURN] to continue..."); 1525 let mut s = String::new(); 1526 let i = io::stdin(); 1527 i.lock().read_line(&mut s).unwrap(); 1528 } 1529 drop(self); 1530 drop(e); 1531 process::exit(1); 1532 } 1533 1534 drop(self); 1535 e.exit() 1536 }) 1537 } 1538 1539 /// Starts the parsing process. A combination of [`App::get_matches_from`], and 1540 /// [`App::get_matches_safe`] 1541 /// 1542 /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are 1543 /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::HelpDisplayed`] 1544 /// or [`ErrorKind::VersionDisplayed`] respectively. You must call [`Error::exit`] or 1545 /// perform a [`std::process::exit`] yourself. 1546 /// 1547 /// **NOTE:** The first argument will be parsed as the binary name unless 1548 /// [`AppSettings::NoBinaryName`] is used 1549 /// 1550 /// # Examples 1551 /// 1552 /// ```no_run 1553 /// # use clap::{App, Arg}; 1554 /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; 1555 /// 1556 /// let matches = App::new("myprog") 1557 /// // Args and options go here... 1558 /// .get_matches_from_safe(arg_vec) 1559 /// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) }); 1560 /// ``` 1561 /// [`App::get_matches_from`]: ./struct.App.html#method.get_matches_from 1562 /// [`App::get_matches_safe`]: ./struct.App.html#method.get_matches_safe 1563 /// [`ErrorKind::HelpDisplayed`]: ./enum.ErrorKind.html#variant.HelpDisplayed 1564 /// [`ErrorKind::VersionDisplayed`]: ./enum.ErrorKind.html#variant.VersionDisplayed 1565 /// [`Error::exit`]: ./struct.Error.html#method.exit 1566 /// [`std::process::exit`]: https://doc.rust-lang.org/std/process/fn.exit.html 1567 /// [`clap::Error`]: ./struct.Error.html 1568 /// [`Error::exit`]: ./struct.Error.html#method.exit 1569 /// [`kind`]: ./struct.Error.html 1570 /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName get_matches_from_safe<I, T>(mut self, itr: I) -> ClapResult<ArgMatches<'a>> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,1571 pub fn get_matches_from_safe<I, T>(mut self, itr: I) -> ClapResult<ArgMatches<'a>> 1572 where 1573 I: IntoIterator<Item = T>, 1574 T: Into<OsString> + Clone, 1575 { 1576 self.get_matches_from_safe_borrow(itr) 1577 } 1578 1579 /// Starts the parsing process without consuming the [`App`] struct `self`. This is normally not 1580 /// the desired functionality, instead prefer [`App::get_matches_from_safe`] which *does* 1581 /// consume `self`. 1582 /// 1583 /// **NOTE:** The first argument will be parsed as the binary name unless 1584 /// [`AppSettings::NoBinaryName`] is used 1585 /// 1586 /// # Examples 1587 /// 1588 /// ```no_run 1589 /// # use clap::{App, Arg}; 1590 /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"]; 1591 /// 1592 /// let mut app = App::new("myprog"); 1593 /// // Args and options go here... 1594 /// let matches = app.get_matches_from_safe_borrow(arg_vec) 1595 /// .unwrap_or_else( |e| { panic!("An error occurs: {}", e) }); 1596 /// ``` 1597 /// [`App`]: ./struct.App.html 1598 /// [`App::get_matches_from_safe`]: ./struct.App.html#method.get_matches_from_safe 1599 /// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName get_matches_from_safe_borrow<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches<'a>> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,1600 pub fn get_matches_from_safe_borrow<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches<'a>> 1601 where 1602 I: IntoIterator<Item = T>, 1603 T: Into<OsString> + Clone, 1604 { 1605 // If there are global arguments, or settings we need to propagate them down to subcommands 1606 // before parsing incase we run into a subcommand 1607 if !self.p.is_set(AppSettings::Propagated) { 1608 self.p.propagate_globals(); 1609 self.p.propagate_settings(); 1610 self.p.derive_display_order(); 1611 self.p.set(AppSettings::Propagated); 1612 } 1613 1614 let mut matcher = ArgMatcher::new(); 1615 1616 let mut it = itr.into_iter(); 1617 // Get the name of the program (argument 1 of env::args()) and determine the 1618 // actual file 1619 // that was used to execute the program. This is because a program called 1620 // ./target/release/my_prog -a 1621 // will have two arguments, './target/release/my_prog', '-a' but we don't want 1622 // to display 1623 // the full path when displaying help messages and such 1624 if !self.p.is_set(AppSettings::NoBinaryName) { 1625 if let Some(name) = it.next() { 1626 let bn_os = name.into(); 1627 let p = Path::new(&*bn_os); 1628 if let Some(f) = p.file_name() { 1629 if let Some(s) = f.to_os_string().to_str() { 1630 if self.p.meta.bin_name.is_none() { 1631 self.p.meta.bin_name = Some(s.to_owned()); 1632 } 1633 } 1634 } 1635 } 1636 } 1637 1638 // do the real parsing 1639 if let Err(e) = self.p.get_matches_with(&mut matcher, &mut it.peekable()) { 1640 return Err(e); 1641 } 1642 1643 let global_arg_vec: Vec<&str> = (&self).p.global_args.iter().map(|ga| ga.b.name).collect(); 1644 matcher.propagate_globals(&global_arg_vec); 1645 1646 Ok(matcher.into()) 1647 } 1648 } 1649 1650 #[cfg(feature = "yaml")] 1651 impl<'a> From<&'a Yaml> for App<'a, 'a> { from(mut yaml: &'a Yaml) -> Self1652 fn from(mut yaml: &'a Yaml) -> Self { 1653 use args::SubCommand; 1654 // We WANT this to panic on error...so expect() is good. 1655 let mut is_sc = None; 1656 let mut a = if let Some(name) = yaml["name"].as_str() { 1657 App::new(name) 1658 } else { 1659 let yaml_hash = yaml.as_hash().unwrap(); 1660 let sc_key = yaml_hash.keys().nth(0).unwrap(); 1661 is_sc = Some(yaml_hash.get(sc_key).unwrap()); 1662 App::new(sc_key.as_str().unwrap()) 1663 }; 1664 yaml = if let Some(sc) = is_sc { sc } else { yaml }; 1665 1666 macro_rules! yaml_str { 1667 ($a:ident, $y:ident, $i:ident) => { 1668 if let Some(v) = $y[stringify!($i)].as_str() { 1669 $a = $a.$i(v); 1670 } else if $y[stringify!($i)] != Yaml::BadValue { 1671 panic!( 1672 "Failed to convert YAML value {:?} to a string", 1673 $y[stringify!($i)] 1674 ); 1675 } 1676 }; 1677 } 1678 1679 yaml_str!(a, yaml, version); 1680 yaml_str!(a, yaml, long_version); 1681 yaml_str!(a, yaml, author); 1682 yaml_str!(a, yaml, bin_name); 1683 yaml_str!(a, yaml, about); 1684 yaml_str!(a, yaml, long_about); 1685 yaml_str!(a, yaml, before_help); 1686 yaml_str!(a, yaml, after_help); 1687 yaml_str!(a, yaml, template); 1688 yaml_str!(a, yaml, usage); 1689 yaml_str!(a, yaml, help); 1690 yaml_str!(a, yaml, help_short); 1691 yaml_str!(a, yaml, version_short); 1692 yaml_str!(a, yaml, help_message); 1693 yaml_str!(a, yaml, version_message); 1694 yaml_str!(a, yaml, alias); 1695 yaml_str!(a, yaml, visible_alias); 1696 1697 if let Some(v) = yaml["display_order"].as_i64() { 1698 a = a.display_order(v as usize); 1699 } else if yaml["display_order"] != Yaml::BadValue { 1700 panic!( 1701 "Failed to convert YAML value {:?} to a u64", 1702 yaml["display_order"] 1703 ); 1704 } 1705 if let Some(v) = yaml["setting"].as_str() { 1706 a = a.setting(v.parse().expect("unknown AppSetting found in YAML file")); 1707 } else if yaml["setting"] != Yaml::BadValue { 1708 panic!( 1709 "Failed to convert YAML value {:?} to an AppSetting", 1710 yaml["setting"] 1711 ); 1712 } 1713 if let Some(v) = yaml["settings"].as_vec() { 1714 for ys in v { 1715 if let Some(s) = ys.as_str() { 1716 a = a.setting(s.parse().expect("unknown AppSetting found in YAML file")); 1717 } 1718 } 1719 } else if let Some(v) = yaml["settings"].as_str() { 1720 a = a.setting(v.parse().expect("unknown AppSetting found in YAML file")); 1721 } else if yaml["settings"] != Yaml::BadValue { 1722 panic!( 1723 "Failed to convert YAML value {:?} to a string", 1724 yaml["settings"] 1725 ); 1726 } 1727 if let Some(v) = yaml["global_setting"].as_str() { 1728 a = a.setting(v.parse().expect("unknown AppSetting found in YAML file")); 1729 } else if yaml["global_setting"] != Yaml::BadValue { 1730 panic!( 1731 "Failed to convert YAML value {:?} to an AppSetting", 1732 yaml["setting"] 1733 ); 1734 } 1735 if let Some(v) = yaml["global_settings"].as_vec() { 1736 for ys in v { 1737 if let Some(s) = ys.as_str() { 1738 a = a.global_setting(s.parse().expect("unknown AppSetting found in YAML file")); 1739 } 1740 } 1741 } else if let Some(v) = yaml["global_settings"].as_str() { 1742 a = a.global_setting(v.parse().expect("unknown AppSetting found in YAML file")); 1743 } else if yaml["global_settings"] != Yaml::BadValue { 1744 panic!( 1745 "Failed to convert YAML value {:?} to a string", 1746 yaml["global_settings"] 1747 ); 1748 } 1749 1750 macro_rules! vec_or_str { 1751 ($a:ident, $y:ident, $as_vec:ident, $as_single:ident) => {{ 1752 let maybe_vec = $y[stringify!($as_vec)].as_vec(); 1753 if let Some(vec) = maybe_vec { 1754 for ys in vec { 1755 if let Some(s) = ys.as_str() { 1756 $a = $a.$as_single(s); 1757 } else { 1758 panic!("Failed to convert YAML value {:?} to a string", ys); 1759 } 1760 } 1761 } else { 1762 if let Some(s) = $y[stringify!($as_vec)].as_str() { 1763 $a = $a.$as_single(s); 1764 } else if $y[stringify!($as_vec)] != Yaml::BadValue { 1765 panic!( 1766 "Failed to convert YAML value {:?} to either a vec or string", 1767 $y[stringify!($as_vec)] 1768 ); 1769 } 1770 } 1771 $a 1772 }}; 1773 } 1774 1775 a = vec_or_str!(a, yaml, aliases, alias); 1776 a = vec_or_str!(a, yaml, visible_aliases, visible_alias); 1777 1778 if let Some(v) = yaml["args"].as_vec() { 1779 for arg_yaml in v { 1780 a = a.arg(Arg::from_yaml(arg_yaml.as_hash().unwrap())); 1781 } 1782 } 1783 if let Some(v) = yaml["subcommands"].as_vec() { 1784 for sc_yaml in v { 1785 a = a.subcommand(SubCommand::from_yaml(sc_yaml)); 1786 } 1787 } 1788 if let Some(v) = yaml["groups"].as_vec() { 1789 for ag_yaml in v { 1790 a = a.group(ArgGroup::from(ag_yaml.as_hash().unwrap())); 1791 } 1792 } 1793 1794 a 1795 } 1796 } 1797 1798 impl<'a, 'b> Clone for App<'a, 'b> { clone(&self) -> Self1799 fn clone(&self) -> Self { 1800 App { p: self.p.clone() } 1801 } 1802 } 1803 1804 impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> { name(&self) -> &'n str1805 fn name(&self) -> &'n str { 1806 "" 1807 } overrides(&self) -> Option<&[&'e str]>1808 fn overrides(&self) -> Option<&[&'e str]> { 1809 None 1810 } requires(&self) -> Option<&[(Option<&'e str>, &'n str)]>1811 fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { 1812 None 1813 } blacklist(&self) -> Option<&[&'e str]>1814 fn blacklist(&self) -> Option<&[&'e str]> { 1815 None 1816 } required_unless(&self) -> Option<&[&'e str]>1817 fn required_unless(&self) -> Option<&[&'e str]> { 1818 None 1819 } val_names(&self) -> Option<&VecMap<&'e str>>1820 fn val_names(&self) -> Option<&VecMap<&'e str>> { 1821 None 1822 } is_set(&self, _: ArgSettings) -> bool1823 fn is_set(&self, _: ArgSettings) -> bool { 1824 false 1825 } val_terminator(&self) -> Option<&'e str>1826 fn val_terminator(&self) -> Option<&'e str> { 1827 None 1828 } set(&mut self, _: ArgSettings)1829 fn set(&mut self, _: ArgSettings) { 1830 unreachable!("App struct does not support AnyArg::set, this is a bug!") 1831 } has_switch(&self) -> bool1832 fn has_switch(&self) -> bool { 1833 false 1834 } max_vals(&self) -> Option<u64>1835 fn max_vals(&self) -> Option<u64> { 1836 None 1837 } num_vals(&self) -> Option<u64>1838 fn num_vals(&self) -> Option<u64> { 1839 None 1840 } possible_vals(&self) -> Option<&[&'e str]>1841 fn possible_vals(&self) -> Option<&[&'e str]> { 1842 None 1843 } validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>>1844 fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { 1845 None 1846 } validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>>1847 fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { 1848 None 1849 } min_vals(&self) -> Option<u64>1850 fn min_vals(&self) -> Option<u64> { 1851 None 1852 } short(&self) -> Option<char>1853 fn short(&self) -> Option<char> { 1854 None 1855 } long(&self) -> Option<&'e str>1856 fn long(&self) -> Option<&'e str> { 1857 None 1858 } val_delim(&self) -> Option<char>1859 fn val_delim(&self) -> Option<char> { 1860 None 1861 } takes_value(&self) -> bool1862 fn takes_value(&self) -> bool { 1863 true 1864 } help(&self) -> Option<&'e str>1865 fn help(&self) -> Option<&'e str> { 1866 self.p.meta.about 1867 } long_help(&self) -> Option<&'e str>1868 fn long_help(&self) -> Option<&'e str> { 1869 self.p.meta.long_about 1870 } default_val(&self) -> Option<&'e OsStr>1871 fn default_val(&self) -> Option<&'e OsStr> { 1872 None 1873 } default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>1874 fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { 1875 None 1876 } env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)>1877 fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { 1878 None 1879 } longest_filter(&self) -> bool1880 fn longest_filter(&self) -> bool { 1881 true 1882 } aliases(&self) -> Option<Vec<&'e str>>1883 fn aliases(&self) -> Option<Vec<&'e str>> { 1884 if let Some(ref aliases) = self.p.meta.aliases { 1885 let vis_aliases: Vec<_> = aliases 1886 .iter() 1887 .filter_map(|&(n, v)| if v { Some(n) } else { None }) 1888 .collect(); 1889 if vis_aliases.is_empty() { 1890 None 1891 } else { 1892 Some(vis_aliases) 1893 } 1894 } else { 1895 None 1896 } 1897 } 1898 } 1899 1900 impl<'n, 'e> fmt::Display for App<'n, 'e> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result1901 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 1902 write!(f, "{}", self.p.meta.name) 1903 } 1904 } 1905