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