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