1 #[cfg(debug_assertions)]
2 mod debug_asserts;
3 mod settings;
4 #[cfg(test)]
5 mod tests;
6 
7 pub use self::settings::{AppFlags, AppSettings};
8 
9 // Std
10 use std::{
11     collections::HashMap,
12     env,
13     ffi::OsString,
14     fmt,
15     io::{self, BufRead, Write},
16     ops::Index,
17     path::Path,
18 };
19 
20 // Third Party
21 use os_str_bytes::RawOsStr;
22 #[cfg(feature = "yaml")]
23 use yaml_rust::Yaml;
24 
25 // Internal
26 use crate::{
27     build::{arg::ArgProvider, Arg, ArgGroup, ArgSettings},
28     mkeymap::MKeyMap,
29     output::{fmt::Colorizer, Help, HelpWriter, Usage},
30     parse::{ArgMatcher, ArgMatches, Input, Parser},
31     util::{color::ColorChoice, safe_exit, Id, Key, USAGE_CODE},
32     Error, ErrorKind, Result as ClapResult, INTERNAL_ERROR_MSG,
33 };
34 
35 /// Represents a command line interface which is made up of all possible
36 /// command line arguments and subcommands. Interface arguments and settings are
37 /// configured using the "builder pattern." Once all configuration is complete,
38 /// the [`App::get_matches`] family of methods starts the runtime-parsing
39 /// process. These methods then return information about the user supplied
40 /// arguments (or lack thereof).
41 ///
42 /// **NOTE:** There aren't any mandatory "options" that one must set. The "options" may
43 /// also appear in any order (so long as one of the [`App::get_matches`] methods is the last method
44 /// called).
45 ///
46 /// # Examples
47 ///
48 /// ```no_run
49 /// # use clap::{App, Arg};
50 /// let m = App::new("My Program")
51 ///     .author("Me, me@mail.com")
52 ///     .version("1.0.2")
53 ///     .about("Explains in brief what the program does")
54 ///     .arg(
55 ///         Arg::new("in_file").index(1)
56 ///     )
57 ///     .after_help("Longer explanation to appear after the options when \
58 ///                  displaying the help information from --help or -h")
59 ///     .get_matches();
60 ///
61 /// // Your program logic starts here...
62 /// ```
63 /// [`App::get_matches`]: App::get_matches()
64 #[derive(Default, Debug, Clone, PartialEq, Eq)]
65 pub struct App<'help> {
66     pub(crate) id: Id,
67     pub(crate) name: String,
68     pub(crate) long_flag: Option<&'help str>,
69     pub(crate) short_flag: Option<char>,
70     pub(crate) bin_name: Option<String>,
71     pub(crate) author: Option<&'help str>,
72     pub(crate) version: Option<&'help str>,
73     pub(crate) long_version: Option<&'help str>,
74     pub(crate) license: Option<&'help str>,
75     pub(crate) about: Option<&'help str>,
76     pub(crate) long_about: Option<&'help str>,
77     pub(crate) before_help: Option<&'help str>,
78     pub(crate) before_long_help: Option<&'help str>,
79     pub(crate) after_help: Option<&'help str>,
80     pub(crate) after_long_help: Option<&'help str>,
81     pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible)
82     pub(crate) short_flag_aliases: Vec<(char, bool)>, // (name, visible)
83     pub(crate) long_flag_aliases: Vec<(&'help str, bool)>, // (name, visible)
84     pub(crate) usage_str: Option<&'help str>,
85     pub(crate) usage: Option<String>,
86     pub(crate) help_str: Option<&'help str>,
87     pub(crate) disp_ord: usize,
88     pub(crate) term_w: Option<usize>,
89     pub(crate) max_w: Option<usize>,
90     pub(crate) template: Option<&'help str>,
91     pub(crate) settings: AppFlags,
92     pub(crate) g_settings: AppFlags,
93     pub(crate) color: ColorChoice,
94     pub(crate) args: MKeyMap<'help>,
95     pub(crate) subcommands: Vec<App<'help>>,
96     pub(crate) replacers: HashMap<&'help str, &'help [&'help str]>,
97     pub(crate) groups: Vec<ArgGroup<'help>>,
98     pub(crate) current_help_heading: Option<&'help str>,
99     pub(crate) subcommand_placeholder: Option<&'help str>,
100     pub(crate) subcommand_header: Option<&'help str>,
101 }
102 
103 impl<'help> App<'help> {
104     /// Get the name of the app.
105     #[inline]
get_name(&self) -> &str106     pub fn get_name(&self) -> &str {
107         &self.name
108     }
109 
110     /// Get the short flag of the subcommand.
111     #[inline]
get_short_flag(&self) -> Option<char>112     pub fn get_short_flag(&self) -> Option<char> {
113         self.short_flag
114     }
115 
116     /// Get the long flag of the subcommand.
117     #[inline]
get_long_flag(&self) -> Option<&str>118     pub fn get_long_flag(&self) -> Option<&str> {
119         self.long_flag
120     }
121 
122     /// Get the name of the binary.
123     #[inline]
get_bin_name(&self) -> Option<&str>124     pub fn get_bin_name(&self) -> Option<&str> {
125         self.bin_name.as_deref()
126     }
127 
128     /// Set binary name. Uses `&mut self` instead of `self`.
set_bin_name<S: Into<String>>(&mut self, name: S)129     pub fn set_bin_name<S: Into<String>>(&mut self, name: S) {
130         self.bin_name = Some(name.into());
131     }
132 
133     /// Get the help message specified via [`App::about`].
134     ///
135     /// [`App::about`]: App::about()
136     #[inline]
get_about(&self) -> Option<&str>137     pub fn get_about(&self) -> Option<&str> {
138         self.about
139     }
140 
141     /// Get the help message specified via [`App::long_about`].
142     ///
143     /// [`App::long_about`]: App::long_about()
144     #[inline]
get_long_about(&self) -> Option<&str>145     pub fn get_long_about(&self) -> Option<&str> {
146         self.long_about
147     }
148 
149     /// Get the custom section heading specified via [`App::help_heading`].
150     ///
151     /// [`App::help_heading`]: App::help_heading()
152     #[inline]
get_help_heading(&self) -> Option<&'help str>153     pub fn get_help_heading(&self) -> Option<&'help str> {
154         self.current_help_heading
155     }
156 
157     /// Iterate through the *visible* aliases for this subcommand.
158     #[inline]
get_visible_aliases(&self) -> impl Iterator<Item = &str>159     pub fn get_visible_aliases(&self) -> impl Iterator<Item = &str> {
160         self.aliases.iter().filter(|(_, vis)| *vis).map(|a| a.0)
161     }
162 
163     /// Iterate through the *visible* short aliases for this subcommand.
164     #[inline]
get_visible_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_165     pub fn get_visible_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_ {
166         self.short_flag_aliases
167             .iter()
168             .filter(|(_, vis)| *vis)
169             .map(|a| a.0)
170     }
171 
172     /// Iterate through the *visible* long aliases for this subcommand.
173     #[inline]
get_visible_long_flag_aliases(&self) -> impl Iterator<Item = &'help str> + '_174     pub fn get_visible_long_flag_aliases(&self) -> impl Iterator<Item = &'help str> + '_ {
175         self.long_flag_aliases
176             .iter()
177             .filter(|(_, vis)| *vis)
178             .map(|a| a.0)
179     }
180 
181     /// Iterate through the set of *all* the aliases for this subcommand, both visible and hidden.
182     #[inline]
get_all_aliases(&self) -> impl Iterator<Item = &str>183     pub fn get_all_aliases(&self) -> impl Iterator<Item = &str> {
184         self.aliases.iter().map(|a| a.0)
185     }
186 
187     /// Iterate through the set of *all* the short aliases for this subcommand, both visible and hidden.
188     #[inline]
get_all_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_189     pub fn get_all_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_ {
190         self.short_flag_aliases.iter().map(|a| a.0)
191     }
192 
193     /// Iterate through the set of *all* the long aliases for this subcommand, both visible and hidden.
194     #[inline]
get_all_long_flag_aliases(&self) -> impl Iterator<Item = &'help str> + '_195     pub fn get_all_long_flag_aliases(&self) -> impl Iterator<Item = &'help str> + '_ {
196         self.long_flag_aliases.iter().map(|a| a.0)
197     }
198 
199     /// Iterate through the set of subcommands, getting a reference to each.
200     #[inline]
get_subcommands(&self) -> impl Iterator<Item = &App<'help>>201     pub fn get_subcommands(&self) -> impl Iterator<Item = &App<'help>> {
202         self.subcommands.iter()
203     }
204 
205     /// Iterate through the set of subcommands, getting a mutable reference to each.
206     #[inline]
get_subcommands_mut(&mut self) -> impl Iterator<Item = &mut App<'help>>207     pub fn get_subcommands_mut(&mut self) -> impl Iterator<Item = &mut App<'help>> {
208         self.subcommands.iter_mut()
209     }
210 
211     /// Iterate through the set of arguments.
212     #[inline]
get_arguments(&self) -> impl Iterator<Item = &Arg<'help>>213     pub fn get_arguments(&self) -> impl Iterator<Item = &Arg<'help>> {
214         self.args.args()
215     }
216 
217     /// Iterate through the *positionals* arguments.
218     #[inline]
get_positionals(&self) -> impl Iterator<Item = &Arg<'help>>219     pub fn get_positionals(&self) -> impl Iterator<Item = &Arg<'help>> {
220         self.get_arguments().filter(|a| a.is_positional())
221     }
222 
223     /// Iterate through the *options*.
get_opts(&self) -> impl Iterator<Item = &Arg<'help>>224     pub fn get_opts(&self) -> impl Iterator<Item = &Arg<'help>> {
225         self.get_arguments()
226             .filter(|a| a.is_set(ArgSettings::TakesValue) && !a.is_positional())
227     }
228 
229     // Get a list of subcommands which contain the provided Argument
230     //
231     // This command will only include subcommands in its list for which the subcommands
232     // parent also contains the Argument.
233     //
234     // This search follows the propagation rules of global arguments.
235     // It is useful to finding subcommands, that have inherited a global argument.
236     //
237     // **NOTE:** In this case only Sucommand_1 will be included
238     //   Subcommand_1 (contains Arg)
239     //     Subcommand_1.1 (doesn't contain Arg)
240     //       Subcommand_1.1.1 (contains Arg)
241     //
get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>>242     fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>> {
243         let mut vec = std::vec::Vec::new();
244         for idx in 0..self.subcommands.len() {
245             if self.subcommands[idx].args.args().any(|ar| ar.id == arg.id) {
246                 vec.push(&self.subcommands[idx]);
247                 vec.append(&mut self.subcommands[idx].get_subcommands_containing(arg));
248             }
249         }
250         vec
251     }
252 
253     // Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with.
254     //
255     // This behavior follows the propagation rules of global arguments.
256     // It is useful for finding conflicts for arguments declared as global.
257     //
258     // ### Panics
259     //
260     // If the given arg contains a conflict with an argument that is unknown to
261     // this `App`.
get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>>262     fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator
263     {
264         arg.blacklist
265             .iter()
266             .map(|id| {
267                 self.args
268                     .args()
269                     .chain(
270                         self.get_subcommands_containing(arg)
271                             .iter()
272                             .flat_map(|x| x.args.args()),
273                     )
274                     .find(|arg| arg.id == *id)
275                     .expect(
276                         "App::get_arg_conflicts_with: \
277                     The passed arg conflicts with an arg unknown to the app",
278                     )
279             })
280             .collect()
281     }
282 
283     /// Get a list of all arguments the given argument conflicts with.
284     ///
285     /// If the provided argument is declared as global, the conflicts will be determined
286     /// based on the propagation rules of global arguments.
287     ///
288     /// ### Panics
289     ///
290     /// If the given arg contains a conflict with an argument that is unknown to
291     /// this `App`.
get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>>292     pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator
293     {
294         if arg.global {
295             self.get_global_arg_conflicts_with(arg)
296         } else {
297             arg.blacklist
298                 .iter()
299                 .map(|id| {
300                     self.args.args().find(|arg| arg.id == *id).expect(
301                         "App::get_arg_conflicts_with: \
302                     The passed arg conflicts with an arg unknown to the app",
303                     )
304                 })
305                 .collect()
306         }
307     }
308 
309     /// Returns `true` if the given [`AppSettings`] variant is currently set in
310     /// this `App` (checks both [local] and [global settings]).
311     ///
312     /// [local]: App::setting()
313     /// [global settings]: App::global_setting()
314     #[inline]
is_set(&self, s: AppSettings) -> bool315     pub fn is_set(&self, s: AppSettings) -> bool {
316         self.settings.is_set(s) || self.g_settings.is_set(s)
317     }
318 
319     /// Returns `true` if this `App` has subcommands.
320     #[inline]
has_subcommands(&self) -> bool321     pub fn has_subcommands(&self) -> bool {
322         !self.subcommands.is_empty()
323     }
324 
325     /// Find subcommand such that its name or one of aliases equals `name`.
326     ///
327     /// This does not recurse through subcommands of subcommands.
328     #[inline]
find_subcommand<T>(&self, name: &T) -> Option<&App<'help>> where T: PartialEq<str> + ?Sized,329     pub fn find_subcommand<T>(&self, name: &T) -> Option<&App<'help>>
330     where
331         T: PartialEq<str> + ?Sized,
332     {
333         self.get_subcommands().find(|s| s.aliases_to(name))
334     }
335 }
336 
337 impl<'help> App<'help> {
338     /// Creates a new instance of an `App` requiring a `name`.
339     ///
340     /// It is common, but not required, to use binary name as the `name`. This
341     /// name will only be displayed to the user when they request to print
342     /// version or help and usage information.
343     ///
344     /// An `App` represents a command line interface (CLI) which is made up of
345     /// all possible command line arguments and subcommands. "Subcommands" are
346     /// sub-CLIs with their own arguments, settings, and even subcommands
347     /// forming a sort of hierarchy.
348     ///
349     /// # Examples
350     ///
351     /// ```no_run
352     /// # use clap::App;
353     /// App::new("My Program")
354     /// # ;
355     /// ```
new<S: Into<String>>(name: S) -> Self356     pub fn new<S: Into<String>>(name: S) -> Self {
357         let name = name.into();
358 
359         App {
360             id: Id::from(&*name),
361             name,
362             disp_ord: 999,
363             ..Default::default()
364         }
365         .arg(
366             Arg::new("help")
367                 .long("help")
368                 .about("Print help information")
369                 .global(true)
370                 .generated(),
371         )
372         .arg(
373             Arg::new("version")
374                 .long("version")
375                 .about("Print version information")
376                 .global(true)
377                 .generated(),
378         )
379     }
380 
381     /// Deprecated, see [`App::from`]
382     #[cfg(feature = "yaml")]
383     #[deprecated(since = "3.0.0", note = "Replaced with `App::from`")]
from_yaml(yaml: &'help Yaml) -> Self384     pub fn from_yaml(yaml: &'help Yaml) -> Self {
385         Self::from(yaml)
386     }
387 
388     /// Sets a string of author(s) that will be displayed to the user when they
389     /// request the help message.
390     ///
391     /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to
392     /// automatically set your application's author(s) to the same thing as your
393     /// crate at compile time.
394     ///
395     /// See the [`examples/`] directory for more information.
396     ///
397     /// # Examples
398     ///
399     /// ```no_run
400     /// # use clap::App;
401     /// App::new("myprog")
402     ///      .author("Me, me@mymain.com")
403     /// # ;
404     /// ```
405     /// [`crate_authors!`]: ./macro.crate_authors!.html
406     /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples
author<S: Into<&'help str>>(mut self, author: S) -> Self407     pub fn author<S: Into<&'help str>>(mut self, author: S) -> Self {
408         self.author = Some(author.into());
409         self
410     }
411 
412     /// Overrides the runtime-determined name of the binary. This should only be
413     /// used when absolutely necessary, such as when the binary name for your
414     /// application is misleading, or perhaps *not* how the user should invoke
415     /// your program.
416     ///
417     /// Normally, the binary name is used in help and error messages. `clap`
418     /// automatically determines the binary name at runtime, however by manually
419     /// setting the binary name, one can effectively override what will be
420     /// displayed in the help or error messages.
421     ///
422     /// **Pro-tip:** When building things such as third party `cargo`
423     /// subcommands, this setting **should** be used!
424     ///
425     /// **NOTE:** This *does not* change or set the name of the binary file on
426     /// disk. It only changes what clap thinks the name is for the purposes of
427     /// error or help messages.
428     ///
429     /// # Examples
430     ///
431     /// ```no_run
432     /// # use clap::App;
433     /// App::new("My Program")
434     ///      .bin_name("my_binary")
435     /// # ;
436     /// ```
bin_name<S: Into<String>>(mut self, name: S) -> Self437     pub fn bin_name<S: Into<String>>(mut self, name: S) -> Self {
438         self.bin_name = Some(name.into());
439         self
440     }
441 
442     /// Sets a string describing what the program does. This will be displayed
443     /// when the user requests the short format help message (`-h`).
444     ///
445     /// `clap` can display two different help messages, a [long format] and a
446     /// [short format] depending on whether the user used `-h` (short) or
447     /// `--help` (long). This method sets the message during the short format
448     /// (`-h`) message. However, if no long format message is configured, this
449     /// message will be displayed for *both* the long format, or short format
450     /// help message.
451     ///
452     /// **NOTE:** Only [`App::about`] (short format) is used in completion
453     /// script generation in order to be concise.
454     ///
455     /// # Examples
456     ///
457     /// ```no_run
458     /// # use clap::App;
459     /// App::new("myprog")
460     ///     .about("Does really amazing things for great people")
461     /// # ;
462     /// ```
463     /// [long format]: App::long_about()
464     /// [short format]: App::about()
465     /// [`App::about`]: App::about()
about<S: Into<&'help str>>(mut self, about: S) -> Self466     pub fn about<S: Into<&'help str>>(mut self, about: S) -> Self {
467         self.about = Some(about.into());
468         self
469     }
470 
471     /// Sets a long format string describing what the program does. This will be
472     /// displayed when the user requests the long format help message (`--help`).
473     ///
474     /// ## Advanced
475     ///
476     /// `clap` can display two different help messages, a [long format] and a
477     /// [short format] depending on whether the user used `-h` (short) or
478     /// `--help` (long). This method sets the message during the long format
479     /// (`--help`) message. However, if no short format message is configured,
480     /// this message will be displayed for *both* the long format, or short
481     /// format help message.
482     ///
483     /// **NOTE:** Only [`App::about`] (short format) is used in completion
484     /// script generation in order to be concise.
485     ///
486     /// # Examples
487     ///
488     /// ```no_run
489     /// # use clap::App;
490     /// App::new("myprog")
491     ///     .long_about(
492     /// "Does really amazing things to great people. Now let's talk a little
493     ///  more in depth about how this subcommand really works. It may take about
494     ///  a few lines of text, but that's ok!")
495     /// # ;
496     /// ```
497     /// [long format]: App::long_about()
498     /// [short format]: App::about()
499     /// [`App::about`]: App::about()
long_about<S: Into<&'help str>>(mut self, about: S) -> Self500     pub fn long_about<S: Into<&'help str>>(mut self, about: S) -> Self {
501         self.long_about = Some(about.into());
502         self
503     }
504 
505     /// (Re)Sets the program's name. This will be displayed when displaying help
506     /// or version messages.
507     ///
508     /// **Pro-tip:** This function is particularly useful when configuring a
509     /// program via `App::from(yaml)` in conjunction with the [`crate_name!`]
510     /// macro to derive the program's name from its `Cargo.toml`.
511     ///
512     /// # Examples
513     ///
514     /// ```ignore
515     /// # use clap::{App, load_yaml};
516     /// let yaml = load_yaml!("app.yaml");
517     /// let app = App::from(yaml)
518     ///     .name(crate_name!());
519     ///
520     /// // continued logic goes here, such as `app.get_matches()` etc.
521     /// ```
522     ///
name<S: Into<String>>(mut self, name: S) -> Self523     pub fn name<S: Into<String>>(mut self, name: S) -> Self {
524         self.name = name.into();
525         self
526     }
527 
528     /// Adds additional help information to be displayed at the end of the
529     /// auto-generated help. This is often used to describe how to use the
530     /// arguments, caveats to be noted, or license and contact information.
531     ///
532     /// **NOTE:** If only `after_long_help` is provided, and not [`App::after_help`] but the user requests
533     /// `-h` clap will still display the contents of `after_help` appropriately.
534     ///
535     /// # Examples
536     ///
537     /// ```no_run
538     /// # use clap::App;
539     /// App::new("myprog")
540     ///     .after_help("Does really amazing things for great people... but be careful with -R!")
541     /// # ;
542     /// ```
543     ///
544     /// [`App::after_help`]: App::after_help()
after_help<S: Into<&'help str>>(mut self, help: S) -> Self545     pub fn after_help<S: Into<&'help str>>(mut self, help: S) -> Self {
546         self.after_help = Some(help.into());
547         self
548     }
549 
550     /// Adds additional help information to be displayed in addition to auto-generated help. This
551     /// information is displayed **after** the auto-generated help information and is meant to be
552     /// more verbose than `after_help`. This is often used to describe how to use the arguments, or
553     /// caveats to be noted in man pages.
554     ///
555     /// **NOTE:** If only `after_help` is provided, and not [`App::after_long_help`] but the user
556     /// requests `--help`, clap will still display the contents of `after_help` appropriately.
557     ///
558     /// # Examples
559     ///
560     /// ```no_run
561     /// # use clap::App;
562     /// App::new("myprog")
563     ///     .after_long_help("Does really amazing things to great people... but be careful with -R, \
564     ///                      like, for real, be careful with this!")
565     /// # ;
566     /// ```
567     /// [`App::after_long_help`]: App::after_long_help()
after_long_help<S: Into<&'help str>>(mut self, help: S) -> Self568     pub fn after_long_help<S: Into<&'help str>>(mut self, help: S) -> Self {
569         self.after_long_help = Some(help.into());
570         self
571     }
572 
573     /// Adds additional help information to be displayed prior to the
574     /// auto-generated help. This is often used for header, copyright, or
575     /// license information.
576     ///
577     /// **NOTE:** If only `before_long_help` is provided, and not [`App::before_help`] but the user
578     /// requests `-h` clap will still display the contents of `before_long_help` appropriately.
579     ///
580     /// # Examples
581     ///
582     /// ```no_run
583     /// # use clap::App;
584     /// App::new("myprog")
585     ///     .before_help("Some info I'd like to appear before the help info")
586     /// # ;
587     /// ```
588     /// [`App::before_help`]: App::before_help()
before_help<S: Into<&'help str>>(mut self, help: S) -> Self589     pub fn before_help<S: Into<&'help str>>(mut self, help: S) -> Self {
590         self.before_help = Some(help.into());
591         self
592     }
593 
594     /// Adds additional help information to be displayed prior to the
595     /// auto-generated help. This is often used for header, copyright, or
596     /// license information.
597     ///
598     /// **NOTE:** If only `before_help` is provided, and not [`App::before_long_help`] but the user
599     /// requests `--help`, clap will still display the contents of `before_help` appropriately.
600     ///
601     /// # Examples
602     ///
603     /// ```no_run
604     /// # use clap::App;
605     /// App::new("myprog")
606     ///     .before_long_help("Some verbose and long info I'd like to appear before the help info")
607     /// # ;
608     /// ```
609     /// [`App::before_long_help`]: App::before_long_help()
before_long_help<S: Into<&'help str>>(mut self, help: S) -> Self610     pub fn before_long_help<S: Into<&'help str>>(mut self, help: S) -> Self {
611         self.before_long_help = Some(help.into());
612         self
613     }
614 
615     /// Allows the subcommand to be used as if it were an [`Arg::short`].
616     ///
617     /// Sets the short version of the subcommand flag without the preceding `-`.
618     ///
619     /// # Examples
620     ///
621     /// ```
622     /// # use clap::{App, Arg};
623     /// let matches = App::new("pacman")
624     ///     .subcommand(
625     ///         App::new("sync").short_flag('S').arg(
626     ///             Arg::new("search")
627     ///                 .short('s')
628     ///                 .long("search")
629     ///                 .about("search remote repositories for matching strings"),
630     ///         ),
631     ///     )
632     ///     .get_matches_from(vec!["pacman", "-Ss"]);
633     ///
634     /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
635     /// let sync_matches = matches.subcommand_matches("sync").unwrap();
636     /// assert!(sync_matches.is_present("search"));
637     /// ```
638     /// [`Arg::short`]: Arg::short()
short_flag(mut self, short: char) -> Self639     pub fn short_flag(mut self, short: char) -> Self {
640         self.short_flag = Some(short);
641         self
642     }
643 
644     /// Allows the subcommand to be used as if it were an [`Arg::long`].
645     ///
646     /// Sets the long version of the subcommand flag without the preceding `--`.
647     ///
648     /// **NOTE:** Any leading `-` characters will be stripped.
649     ///
650     /// # Examples
651     ///
652     /// To set `long_flag` use a word containing valid UTF-8 codepoints. If you supply a double leading
653     /// `--` such as `--sync` they will be stripped. Hyphens in the middle of the word; however,
654     /// will *not* be stripped (i.e. `sync-file` is allowed).
655     ///
656     /// ```
657     /// # use clap::{App, Arg};
658     /// let matches = App::new("pacman")
659     ///     .subcommand(
660     ///         App::new("sync").long_flag("sync").arg(
661     ///             Arg::new("search")
662     ///                 .short('s')
663     ///                 .long("search")
664     ///                 .about("search remote repositories for matching strings"),
665     ///         ),
666     ///     )
667     ///     .get_matches_from(vec!["pacman", "--sync", "--search"]);
668     ///
669     /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
670     /// let sync_matches = matches.subcommand_matches("sync").unwrap();
671     /// assert!(sync_matches.is_present("search"));
672     /// ```
673     ///
674     /// [`Arg::long`]: Arg::long()
long_flag(mut self, long: &'help str) -> Self675     pub fn long_flag(mut self, long: &'help str) -> Self {
676         self.long_flag = Some(long.trim_start_matches(|c| c == '-'));
677         self
678     }
679 
680     /// Sets a string of the version number to be displayed when displaying the
681     /// short format version message (`-V`) or the help message.
682     ///
683     /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
684     /// automatically set your application's version to the same thing as your
685     /// crate at compile time. See the [`examples/`] directory for more
686     /// information.
687     ///
688     /// `clap` can display two different version messages, a [long format] and a
689     /// [short format] depending on whether the user used `-V` (short) or
690     /// `--version` (long). This method sets the message during the short format
691     /// (`-V`). However, if no long format message is configured, this
692     /// message will be displayed for *both* the long format, or short format
693     /// version message.
694     ///
695     /// # Examples
696     ///
697     /// ```no_run
698     /// # use clap::App;
699     /// App::new("myprog")
700     ///     .version("v0.1.24")
701     /// # ;
702     /// ```
703     /// [`crate_version!`]: ./macro.crate_version!.html
704     /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples
705     /// [`App::long_version`]: App::long_version()
version<S: Into<&'help str>>(mut self, ver: S) -> Self706     pub fn version<S: Into<&'help str>>(mut self, ver: S) -> Self {
707         self.version = Some(ver.into());
708         self
709     }
710 
711     /// Sets a string of the version number to be displayed when the user
712     /// requests the long format version message (`--version`) or the help
713     /// message.
714     ///
715     /// This is often used to display things such as commit ID, or compile time
716     /// configured options.
717     ///
718     /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
719     /// automatically set your application's version to the same thing as your
720     /// crate at compile time. See the [`examples/`] directory for more
721     /// information.
722     ///
723     /// `clap` can display two different version messages, a [long format] and a
724     /// [short format] depending on whether the user used `-V` (short) or
725     /// `--version` (long). This method sets the message during the long format
726     /// (`--version`). However, if no short format message is configured, this
727     /// message will be displayed for *both* the long format, or short format
728     /// version message.
729     ///
730     /// # Examples
731     ///
732     /// ```no_run
733     /// # use clap::App;
734     /// App::new("myprog")
735     ///     .long_version(
736     /// "v0.1.24
737     ///  commit: abcdef89726d
738     ///  revision: 123
739     ///  release: 2
740     ///  binary: myprog")
741     /// # ;
742     /// ```
743     /// [`crate_version!`]: ./macro.crate_version!.html
744     /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples
745     /// [`App::version`]: App::version()
long_version<S: Into<&'help str>>(mut self, ver: S) -> Self746     pub fn long_version<S: Into<&'help str>>(mut self, ver: S) -> Self {
747         self.long_version = Some(ver.into());
748         self
749     }
750 
751     /// Sets a string of the license to be displayed when displaying help information.
752     ///
753     /// **Pro-tip:** Use `clap`s convenience macro [`crate_license!`] to automatically set your
754     /// application's license to the same thing as your crate at compile time. See the
755     /// [`examples/`] directory for more information
756     ///
757     /// # Examples
758     ///
759     /// ```no_run
760     /// # use clap::{App, Arg};
761     /// App::new("myprog")
762     ///     .license("MIT OR Apache-2.0")
763     /// # ;
764     /// ```
765     /// [`crate_license!`]: ./macro.crate_license!.html
766     /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples
license<S: Into<&'help str>>(mut self, license: S) -> Self767     pub fn license<S: Into<&'help str>>(mut self, license: S) -> Self {
768         self.license = Some(license.into());
769         self
770     }
771 
772     /// Overrides the `clap` generated usage string.
773     ///
774     /// This will be displayed to the user when errors are found in argument parsing.
775     ///
776     /// **CAUTION:** Using this setting disables `clap`s "context-aware" usage
777     /// strings. After this setting is set, this will be *the only* usage string
778     /// displayed to the user!
779     ///
780     /// **NOTE:** This will not replace the entire help message, *only* the portion
781     /// showing the usage.
782     ///
783     /// # Examples
784     ///
785     /// ```no_run
786     /// # use clap::{App, Arg};
787     /// App::new("myprog")
788     ///     .override_usage("myapp [-clDas] <some_file>")
789     /// # ;
790     /// ```
791     /// [`ArgMatches::usage`]: ArgMatches::usage()
override_usage<S: Into<&'help str>>(mut self, usage: S) -> Self792     pub fn override_usage<S: Into<&'help str>>(mut self, usage: S) -> Self {
793         self.usage_str = Some(usage.into());
794         self
795     }
796 
797     /// Deprecated, see [`App::override_usage`]
798     #[deprecated(since = "3.0.0", note = "Replaced with `App::override_usage`")]
usage<S: Into<&'help str>>(self, usage: S) -> Self799     pub fn usage<S: Into<&'help str>>(self, usage: S) -> Self {
800         self.override_usage(usage)
801     }
802 
803     /// Overrides the `clap` generated help message. This should only be used
804     /// when the auto-generated message does not suffice.
805     ///
806     /// This will be displayed to the user when they use `--help` or `-h`.
807     ///
808     /// **NOTE:** This replaces the **entire** help message, so nothing will be
809     /// auto-generated.
810     ///
811     /// **NOTE:** This **only** replaces the help message for the current
812     /// command, meaning if you are using subcommands, those help messages will
813     /// still be auto-generated unless you specify a [`App::override_help`] for
814     /// them as well.
815     ///
816     /// # Examples
817     ///
818     /// ```no_run
819     /// # use clap::{App, Arg};
820     /// App::new("myapp")
821     ///     .override_help("myapp v1.0\n\
822     ///            Does awesome things\n\
823     ///            (C) me@mail.com\n\n\
824     ///
825     ///            USAGE: myapp <opts> <comamnd>\n\n\
826     ///
827     ///            Options:\n\
828     ///            -h, --help       Display this message\n\
829     ///            -V, --version    Display version info\n\
830     ///            -s <stuff>       Do something with stuff\n\
831     ///            -v               Be verbose\n\n\
832     ///
833     ///            Commmands:\n\
834     ///            help             Print this message\n\
835     ///            work             Do some work")
836     /// # ;
837     /// ```
override_help<S: Into<&'help str>>(mut self, help: S) -> Self838     pub fn override_help<S: Into<&'help str>>(mut self, help: S) -> Self {
839         self.help_str = Some(help.into());
840         self
841     }
842 
843     /// Deprecated, see [`App::override_help`]
844     #[deprecated(since = "3.0.0", note = "Replaced with `App::override_help`")]
help<S: Into<&'help str>>(self, help: S) -> Self845     pub fn help<S: Into<&'help str>>(self, help: S) -> Self {
846         self.override_help(help)
847     }
848 
849     /// Sets the help template to be used, overriding the default format.
850     ///
851     /// **NOTE:** The template system is by design very simple. Therefore, the
852     /// tags have to be written in the lowercase and without spacing.
853     ///
854     /// Tags are given inside curly brackets.
855     ///
856     /// Valid tags are:
857     ///
858     ///   * `{bin}`                 - Binary name.
859     ///   * `{version}`             - Version number.
860     ///   * `{author}`              - Author information.
861     ///   * `{author-with-newline}` - Author followed by `\n`.
862     ///   * `{author-section}`      - Author preceded and followed by `\n`.
863     ///   * `{about}`               - General description (from [`App::about`] or
864     ///                               [`App::long_about`]).
865     ///   * `{about-with-newline}`  - About followed by `\n`.
866     ///   * `{about-section}`       - About preceded and followed by '\n'.
867     ///   * `{usage-heading}`       - Automatically generated usage heading.
868     ///   * `{usage}`               - Automatically generated or given usage string.
869     ///   * `{all-args}`            - Help for all arguments (options, flags, positional
870     ///                               arguments, and subcommands) including titles.
871     ///   * `{options}`             - Help for options.
872     ///   * `{positionals}`         - Help for positional arguments.
873     ///   * `{subcommands}`         - Help for subcommands.
874     ///   * `{after-help}`          - Help from [`App::after_help`] or [`App::after_long_help`].
875     ///   * `{before-help}`         - Help from [`App::before_help`] or [`App::before_long_help`].
876     ///
877     /// # Examples
878     ///
879     /// ```no_run
880     /// # use clap::App;
881     /// App::new("myprog")
882     ///     .version("1.0")
883     ///     .help_template("{bin} ({version}) - {usage}")
884     /// # ;
885     /// ```
886     /// [`App::about`]: App::about()
887     /// [`App::long_about`]: App::long_about()
888     /// [`App::after_help`]: App::after_help()
889     /// [`App::after_long_help`]: App::after_long_help()
890     /// [`App::before_help`]: App::before_help()
891     /// [`App::before_long_help`]: App::before_long_help()
help_template<S: Into<&'help str>>(mut self, s: S) -> Self892     pub fn help_template<S: Into<&'help str>>(mut self, s: S) -> Self {
893         self.template = Some(s.into());
894         self
895     }
896 
897     /// Deprecated, see [`App::help_template`]
898     #[deprecated(since = "3.0.0", note = "Replaced with `App::help_template`")]
template<S: Into<&'help str>>(self, s: S) -> Self899     pub fn template<S: Into<&'help str>>(self, s: S) -> Self {
900         self.help_template(s)
901     }
902 
903     /// Enables a single settings for the current (this `App` instance) command or subcommand.
904     ///
905     /// See [`AppSettings`] for a full list of possibilities and examples.
906     ///
907     /// # Examples
908     ///
909     /// ```no_run
910     /// # use clap::{App, AppSettings};
911     /// App::new("myprog")
912     ///     .setting(AppSettings::SubcommandRequired)
913     ///     .setting(AppSettings::WaitOnError)
914     /// # ;
915     /// ```
916     ///
917     /// ```no_run
918     /// # use clap::{App, AppSettings};
919     /// App::new("myprog")
920     ///     .setting(AppSettings::SubcommandRequired | AppSettings::WaitOnError)
921     /// # ;
922     /// ```
923     #[inline]
setting<F>(mut self, setting: F) -> Self where F: Into<AppFlags>,924     pub fn setting<F>(mut self, setting: F) -> Self
925     where
926         F: Into<AppFlags>,
927     {
928         self.settings.insert(setting.into());
929         self
930     }
931 
932     /// Disables a single setting for the current (this `App` instance) command or subcommand.
933     ///
934     /// See [`AppSettings`] for a full list of possibilities and examples.
935     ///
936     /// # Examples
937     ///
938     /// ```no_run
939     /// # use clap::{App, AppSettings};
940     /// App::new("myprog")
941     ///     .unset_setting(AppSettings::SubcommandRequired)
942     ///     .unset_setting(AppSettings::WaitOnError)
943     /// # ;
944     /// ```
945     ///
946     /// ```no_run
947     /// # use clap::{App, AppSettings};
948     /// App::new("myprog")
949     ///     .unset_setting(AppSettings::SubcommandRequired | AppSettings::WaitOnError)
950     /// # ;
951     /// ```
952     #[inline]
unset_setting<F>(mut self, setting: F) -> Self where F: Into<AppFlags>,953     pub fn unset_setting<F>(mut self, setting: F) -> Self
954     where
955         F: Into<AppFlags>,
956     {
957         self.settings.remove(setting.into());
958         self
959     }
960 
961     /// Enables a single setting that is propagated **down** through all child
962     /// subcommands.
963     ///
964     /// See [`AppSettings`] for a full list of possibilities and examples.
965     ///
966     /// **NOTE**: The setting is *only* propagated *down* and not up through parent commands.
967     ///
968     /// # Examples
969     ///
970     /// ```no_run
971     /// # use clap::{App, AppSettings};
972     /// App::new("myprog")
973     ///     .global_setting(AppSettings::SubcommandRequired)
974     /// # ;
975     /// ```
976     #[inline]
global_setting(mut self, setting: AppSettings) -> Self977     pub fn global_setting(mut self, setting: AppSettings) -> Self {
978         self.settings.set(setting);
979         self.g_settings.set(setting);
980         self
981     }
982 
983     /// Disables a global setting, and stops propagating down to child
984     /// subcommands.
985     ///
986     /// See [`AppSettings`] for a full list of possibilities and examples.
987     ///
988     /// **NOTE:** The setting being unset will be unset from both local and
989     /// [global] settings.
990     ///
991     /// # Examples
992     ///
993     /// ```no_run
994     /// # use clap::{App, AppSettings};
995     /// App::new("myprog")
996     ///     .unset_global_setting(AppSettings::AllowNegativeNumbers)
997     /// # ;
998     /// ```
999     /// [global]: App::global_setting()
1000     #[inline]
unset_global_setting(mut self, setting: AppSettings) -> Self1001     pub fn unset_global_setting(mut self, setting: AppSettings) -> Self {
1002         self.settings.unset(setting);
1003         self.g_settings.unset(setting);
1004         self
1005     }
1006 
1007     /// Sets the behaviour of colored output during runtime.
1008     ///
1009     /// **NOTE:** This choice is propagated to all child subcommands.
1010     ///
1011     /// **NOTE:** Default behaviour is [`ColorChoice::Auto`].
1012     ///
1013     /// # Examples
1014     ///
1015     /// ```no_run
1016     /// # use clap::{App, ColorChoice};
1017     /// App::new("myprog")
1018     ///     .color(ColorChoice::Never)
1019     ///     .get_matches();
1020     /// ```
1021     /// [`ColorChoice::Auto`]: crate::ColorChoice::Auto
1022     #[cfg(feature = "color")]
1023     #[inline]
color(mut self, color: ColorChoice) -> Self1024     pub fn color(mut self, color: ColorChoice) -> Self {
1025         self.color = color;
1026         self
1027     }
1028 
1029     /// Sets the terminal width at which to wrap help messages. Defaults to
1030     /// `100`. Using `0` will ignore terminal widths and use source formatting.
1031     ///
1032     /// `clap` automatically tries to determine the terminal width on Unix,
1033     /// Linux, OSX and Windows if the `wrap_help` cargo "feature" has been enabled
1034     /// at compile time. If the terminal width cannot be determined, `clap`
1035     /// fall back to `100`.
1036     ///
1037     /// **NOTE:** This setting applies globally and *not* on a per-command basis.
1038     ///
1039     /// **NOTE:** This setting must be set **before** any subcommands are added!
1040     ///
1041     /// # Platform Specific
1042     ///
1043     /// Only Unix, Linux, OSX and Windows support automatic determination of
1044     /// terminal width. Even on those platforms, this setting is useful if for
1045     /// any reason the terminal width cannot be determined.
1046     ///
1047     /// # Examples
1048     ///
1049     /// ```no_run
1050     /// # use clap::App;
1051     /// App::new("myprog")
1052     ///     .term_width(80)
1053     /// # ;
1054     /// ```
1055     #[inline]
term_width(mut self, width: usize) -> Self1056     pub fn term_width(mut self, width: usize) -> Self {
1057         self.term_w = Some(width);
1058         self
1059     }
1060 
1061     /// Deprecated, see [`App::term_width`]
1062     #[deprecated(since = "3.0.0", note = "Replaced with `App::term_width`")]
set_term_width(self, width: usize) -> Self1063     pub fn set_term_width(self, width: usize) -> Self {
1064         self.term_width(width)
1065     }
1066 
1067     /// Sets the maximum terminal width at which to wrap help messages. Using `0`
1068     /// will ignore terminal widths and use source formatting.
1069     ///
1070     /// `clap` automatically tries to determine the terminal width on Unix,
1071     /// Linux, OSX and Windows if the `wrap_help` cargo "feature" has been
1072     /// enabled at compile time, but one might want to limit the size to some
1073     /// maximum (e.g. when the terminal is running fullscreen).
1074     ///
1075     /// **NOTE:** This setting applies globally and *not* on a per-command basis.
1076     ///
1077     /// **NOTE:** This setting must be set **before** any subcommands are added!
1078     ///
1079     /// # Platform Specific
1080     ///
1081     /// Only Unix, Linux, OSX and Windows support automatic determination of terminal width.
1082     ///
1083     /// # Examples
1084     ///
1085     /// ```no_run
1086     /// # use clap::App;
1087     /// App::new("myprog")
1088     ///     .max_term_width(100)
1089     /// # ;
1090     /// ```
1091     #[inline]
max_term_width(mut self, w: usize) -> Self1092     pub fn max_term_width(mut self, w: usize) -> Self {
1093         self.max_w = Some(w);
1094         self
1095     }
1096 
1097     /// Adds an [argument] to the list of valid possibilities.
1098     ///
1099     /// # Examples
1100     ///
1101     /// ```no_run
1102     /// # use clap::{App, Arg};
1103     /// App::new("myprog")
1104     ///     // Adding a single "flag" argument with a short and help text, using Arg::new()
1105     ///     .arg(
1106     ///         Arg::new("debug")
1107     ///            .short('d')
1108     ///            .about("turns on debugging mode")
1109     ///     )
1110     ///     // Adding a single "option" argument with a short, a long, and help text using the less
1111     ///     // verbose Arg::from()
1112     ///     .arg(
1113     ///         Arg::from("-c --config=[CONFIG] 'Optionally sets a config file to use'")
1114     ///     )
1115     /// # ;
1116     /// ```
1117     /// [argument]: Arg
arg<A: Into<Arg<'help>>>(mut self, a: A) -> Self1118     pub fn arg<A: Into<Arg<'help>>>(mut self, a: A) -> Self {
1119         let mut arg = a.into();
1120         arg.help_heading.get_or_insert(self.current_help_heading);
1121         self.args.push(arg);
1122         self
1123     }
1124 
1125     /// Set the default section heading for future args.
1126     ///
1127     /// This will be used for any arg that hasn't had [`Arg::help_heading`] called.
1128     ///
1129     /// This is useful if the default `OPTIONS` or `ARGS` headings are
1130     /// not specific enough for one's use case.
1131     ///
1132     /// [`App::arg`]: App::arg()
1133     /// [`Arg::help_heading`]: crate::Arg::help_heading()
1134     #[inline]
help_heading<O>(mut self, heading: O) -> Self where O: Into<Option<&'help str>>,1135     pub fn help_heading<O>(mut self, heading: O) -> Self
1136     where
1137         O: Into<Option<&'help str>>,
1138     {
1139         self.current_help_heading = heading.into();
1140         self
1141     }
1142 
1143     /// Adds multiple [arguments] to the list of valid possibilities.
1144     ///
1145     /// # Examples
1146     ///
1147     /// ```no_run
1148     /// # use clap::{App, Arg};
1149     /// App::new("myprog")
1150     ///     .args(&[
1151     ///         Arg::from("[debug] -d 'turns on debugging info'"),
1152     ///         Arg::new("input").index(1).about("the input file to use")
1153     ///     ])
1154     /// # ;
1155     /// ```
1156     /// [arguments]: Arg
args<I, T>(mut self, args: I) -> Self where I: IntoIterator<Item = T>, T: Into<Arg<'help>>,1157     pub fn args<I, T>(mut self, args: I) -> Self
1158     where
1159         I: IntoIterator<Item = T>,
1160         T: Into<Arg<'help>>,
1161     {
1162         // @TODO @perf @p4 @v3-beta: maybe extend_from_slice would be possible and perform better?
1163         // But that may also not let us do `&["-a 'some'", "-b 'other']` because of not Into<Arg>
1164         for arg in args.into_iter() {
1165             self = self.arg(arg);
1166         }
1167         self
1168     }
1169 
1170     /// Deprecated, see [`App::arg`]
1171     #[deprecated(since = "3.0.0", note = "Replaced with `App::arg`")]
arg_from_usage(self, usage: &'help str) -> Self1172     pub fn arg_from_usage(self, usage: &'help str) -> Self {
1173         self.arg(usage)
1174     }
1175 
1176     /// If this `App` instance is a subcommand, this method adds an alias, which
1177     /// allows this subcommand to be accessed via *either* the original name, or
1178     /// this given alias. This is more efficient and easier than creating
1179     /// multiple hidden subcommands as one only needs to check for the existence
1180     /// of this command, and not all aliased variants.
1181     ///
1182     /// **NOTE:** Aliases defined with this method are *hidden* from the help
1183     /// message. If you're looking for aliases that will be displayed in the help
1184     /// message, see [`App::visible_alias`].
1185     ///
1186     /// **NOTE:** When using aliases and checking for the existence of a
1187     /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1188     /// search for the original name and not all aliases.
1189     ///
1190     /// # Examples
1191     ///
1192     /// ```rust
1193     /// # use clap::{App, Arg, };
1194     /// let m = App::new("myprog")
1195     ///     .subcommand(App::new("test")
1196     ///         .alias("do-stuff"))
1197     ///     .get_matches_from(vec!["myprog", "do-stuff"]);
1198     /// assert_eq!(m.subcommand_name(), Some("test"));
1199     /// ```
1200     /// [`App::visible_alias`]: App::visible_alias()
alias<S: Into<&'help str>>(mut self, name: S) -> Self1201     pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
1202         self.aliases.push((name.into(), false));
1203         self
1204     }
1205 
1206     /// Allows adding an alias, which function as "hidden" short flag subcommands that
1207     /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1208     /// than creating multiple hidden subcommands as one only needs to check for the existence of
1209     /// this command, and not all variants.
1210     ///
1211     /// # Examples
1212     ///
1213     /// ```no_run
1214     /// # use clap::{App, Arg, };
1215     /// let m = App::new("myprog")
1216     ///             .subcommand(App::new("test").short_flag('t')
1217     ///                 .short_flag_alias('d'))
1218     ///             .get_matches_from(vec!["myprog", "-d"]);
1219     /// assert_eq!(m.subcommand_name(), Some("test"));
1220     /// ```
short_flag_alias(mut self, name: char) -> Self1221     pub fn short_flag_alias(mut self, name: char) -> Self {
1222         assert!(!(name == '-'), "short alias name cannot be `-`");
1223         self.short_flag_aliases.push((name, false));
1224         self
1225     }
1226 
1227     /// Allows adding an alias, which function as "hidden" long flag subcommands that
1228     /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1229     /// than creating multiple hidden subcommands as one only needs to check for the existence of
1230     /// this command, and not all variants.
1231     ///
1232     /// # Examples
1233     ///
1234     /// ```no_run
1235     /// # use clap::{App, Arg, };
1236     /// let m = App::new("myprog")
1237     ///             .subcommand(App::new("test").long_flag("test")
1238     ///                 .long_flag_alias("testing"))
1239     ///             .get_matches_from(vec!["myprog", "--testing"]);
1240     /// assert_eq!(m.subcommand_name(), Some("test"));
1241     /// ```
long_flag_alias(mut self, name: &'help str) -> Self1242     pub fn long_flag_alias(mut self, name: &'help str) -> Self {
1243         self.long_flag_aliases.push((name, false));
1244         self
1245     }
1246 
1247     /// If this `App` instance is a subcommand, this method adds a multiple
1248     /// aliases, which allows this subcommand to be accessed via *either* the
1249     /// original name or any of the given aliases. This is more efficient, and
1250     /// easier than creating multiple hidden subcommands as one only needs to
1251     /// check for the existence of this command and not all aliased variants.
1252     ///
1253     /// **NOTE:** Aliases defined with this method are *hidden* from the help
1254     /// message. If looking for aliases that will be displayed in the help
1255     /// message, see [`App::visible_aliases`].
1256     ///
1257     /// **NOTE:** When using aliases and checking for the existence of a
1258     /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1259     /// search for the original name and not all aliases.
1260     ///
1261     /// # Examples
1262     ///
1263     /// ```rust
1264     /// # use clap::{App, Arg};
1265     /// let m = App::new("myprog")
1266     ///     .subcommand(App::new("test")
1267     ///         .aliases(&["do-stuff", "do-tests", "tests"]))
1268     ///         .arg(Arg::new("input")
1269     ///             .about("the file to add")
1270     ///             .index(1)
1271     ///             .required(false))
1272     ///     .get_matches_from(vec!["myprog", "do-tests"]);
1273     /// assert_eq!(m.subcommand_name(), Some("test"));
1274     /// ```
1275     /// [`App::visible_aliases`]: App::visible_aliases()
aliases(mut self, names: &[&'help str]) -> Self1276     pub fn aliases(mut self, names: &[&'help str]) -> Self {
1277         self.aliases.extend(names.iter().map(|n| (*n, false)));
1278         self
1279     }
1280 
1281     /// Allows adding aliases, which function as "hidden" short flag subcommands that
1282     /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1283     /// than creating multiple hidden subcommands as one only needs to check for the existence of
1284     /// this command, and not all variants.
1285     ///
1286     /// # Examples
1287     ///
1288     /// ```rust
1289     /// # use clap::{App, Arg, };
1290     /// let m = App::new("myprog")
1291     ///     .subcommand(App::new("test").short_flag('t')
1292     ///         .short_flag_aliases(&['a', 'b', 'c']))
1293     ///         .arg(Arg::new("input")
1294     ///             .about("the file to add")
1295     ///             .index(1)
1296     ///             .required(false))
1297     ///     .get_matches_from(vec!["myprog", "-a"]);
1298     /// assert_eq!(m.subcommand_name(), Some("test"));
1299     /// ```
short_flag_aliases(mut self, names: &[char]) -> Self1300     pub fn short_flag_aliases(mut self, names: &[char]) -> Self {
1301         for s in names {
1302             assert!(s != &'-', "short alias name cannot be `-`");
1303             self.short_flag_aliases.push((*s, false));
1304         }
1305         self
1306     }
1307 
1308     /// Allows adding aliases, which function as "hidden" long flag subcommands that
1309     /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1310     /// than creating multiple hidden subcommands as one only needs to check for the existence of
1311     /// this command, and not all variants.
1312     ///
1313     /// # Examples
1314     ///
1315     /// ```rust
1316     /// # use clap::{App, Arg, };
1317     /// let m = App::new("myprog")
1318     ///             .subcommand(App::new("test").long_flag("test")
1319     ///                 .long_flag_aliases(&["testing", "testall", "test_all"]))
1320     ///                 .arg(Arg::new("input")
1321     ///                             .about("the file to add")
1322     ///                             .index(1)
1323     ///                             .required(false))
1324     ///             .get_matches_from(vec!["myprog", "--testing"]);
1325     /// assert_eq!(m.subcommand_name(), Some("test"));
1326     /// ```
long_flag_aliases(mut self, names: &[&'help str]) -> Self1327     pub fn long_flag_aliases(mut self, names: &[&'help str]) -> Self {
1328         for s in names {
1329             self.long_flag_aliases.push((s, false));
1330         }
1331         self
1332     }
1333 
1334     /// If this `App` instance is a subcommand, this method adds a visible
1335     /// alias, which allows this subcommand to be accessed via *either* the
1336     /// original name or the given alias. This is more efficient and easier
1337     /// than creating hidden subcommands as one only needs to check for
1338     /// the existence of this command and not all aliased variants.
1339     ///
1340     /// **NOTE:** The alias defined with this method is *visible* from the help
1341     /// message and displayed as if it were just another regular subcommand. If
1342     /// looking for an alias that will not be displayed in the help message, see
1343     /// [`App::alias`].
1344     ///
1345     /// **NOTE:** When using aliases and checking for the existence of a
1346     /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1347     /// search for the original name and not all aliases.
1348     ///
1349     /// # Examples
1350     ///
1351     /// ```no_run
1352     /// # use clap::{App, Arg};
1353     /// let m = App::new("myprog")
1354     ///     .subcommand(App::new("test")
1355     ///         .visible_alias("do-stuff"))
1356     ///     .get_matches_from(vec!["myprog", "do-stuff"]);
1357     /// assert_eq!(m.subcommand_name(), Some("test"));
1358     /// ```
1359     /// [`App::alias`]: App::alias()
visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self1360     pub fn visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self {
1361         self.aliases.push((name.into(), true));
1362         self
1363     }
1364 
1365     /// Allows adding an alias that functions exactly like those defined with
1366     /// [`App::short_flag_alias`], except that they are visible inside the help message.
1367     ///
1368     /// # Examples
1369     ///
1370     /// ```no_run
1371     /// # use clap::{App, Arg, };
1372     /// let m = App::new("myprog")
1373     ///             .subcommand(App::new("test").short_flag('t')
1374     ///                 .visible_short_flag_alias('d'))
1375     ///             .get_matches_from(vec!["myprog", "-d"]);
1376     /// assert_eq!(m.subcommand_name(), Some("test"));
1377     /// ```
1378     /// [`App::short_flag_alias`]: App::short_flag_alias()
visible_short_flag_alias(mut self, name: char) -> Self1379     pub fn visible_short_flag_alias(mut self, name: char) -> Self {
1380         assert!(name != '-', "short alias name cannot be `-`");
1381         self.short_flag_aliases.push((name, true));
1382         self
1383     }
1384 
1385     /// Allows adding an alias that functions exactly like those defined with
1386     /// [`App::long_flag_alias`], except that they are visible inside the help message.
1387     ///
1388     /// # Examples
1389     ///
1390     /// ```no_run
1391     /// # use clap::{App, Arg, };
1392     /// let m = App::new("myprog")
1393     ///             .subcommand(App::new("test").long_flag("test")
1394     ///                 .visible_long_flag_alias("testing"))
1395     ///             .get_matches_from(vec!["myprog", "--testing"]);
1396     /// assert_eq!(m.subcommand_name(), Some("test"));
1397     /// ```
1398     /// [`App::long_flag_alias`]: App::long_flag_alias()
visible_long_flag_alias(mut self, name: &'help str) -> Self1399     pub fn visible_long_flag_alias(mut self, name: &'help str) -> Self {
1400         self.long_flag_aliases.push((name, true));
1401         self
1402     }
1403 
1404     /// If this `App` instance is a subcommand, this method adds multiple visible
1405     /// aliases, which allows this subcommand to be accessed via *either* the
1406     /// original name or any of the given aliases. This is more efficient and easier
1407     /// than creating multiple hidden subcommands as one only needs to check for
1408     /// the existence of this command and not all aliased variants.
1409     ///
1410     /// **NOTE:** The alias defined with this method is *visible* from the help
1411     /// message and displayed as if it were just another regular subcommand. If
1412     /// looking for an alias that will not be displayed in the help message, see
1413     /// [`App::alias`].
1414     ///
1415     /// **NOTE:** When using aliases, and checking for the existence of a
1416     /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1417     /// search for the original name and not all aliases.
1418     ///
1419     /// # Examples
1420     ///
1421     /// ```no_run
1422     /// # use clap::{App, Arg, };
1423     /// let m = App::new("myprog")
1424     ///     .subcommand(App::new("test")
1425     ///         .visible_aliases(&["do-stuff", "tests"]))
1426     ///     .get_matches_from(vec!["myprog", "do-stuff"]);
1427     /// assert_eq!(m.subcommand_name(), Some("test"));
1428     /// ```
1429     /// [`App::alias`]: App::alias()
visible_aliases(mut self, names: &[&'help str]) -> Self1430     pub fn visible_aliases(mut self, names: &[&'help str]) -> Self {
1431         self.aliases.extend(names.iter().map(|n| (*n, true)));
1432         self
1433     }
1434 
1435     /// Allows adding multiple short flag aliases that functions exactly like those defined
1436     /// with [`App::short_flag_aliases`], except that they are visible inside the help message.
1437     ///
1438     /// # Examples
1439     ///
1440     /// ```no_run
1441     /// # use clap::{App, Arg, };
1442     /// let m = App::new("myprog")
1443     ///             .subcommand(App::new("test").short_flag('b')
1444     ///                 .visible_short_flag_aliases(&['t']))
1445     ///             .get_matches_from(vec!["myprog", "-t"]);
1446     /// assert_eq!(m.subcommand_name(), Some("test"));
1447     /// ```
1448     /// [`App::short_flag_aliases`]: App::short_flag_aliases()
visible_short_flag_aliases(mut self, names: &[char]) -> Self1449     pub fn visible_short_flag_aliases(mut self, names: &[char]) -> Self {
1450         for s in names {
1451             assert!(!(s == &'-'), "short alias name cannot be `-`");
1452             self.short_flag_aliases.push((*s, true));
1453         }
1454         self
1455     }
1456 
1457     /// Allows adding multiple long flag aliases that functions exactly like those defined
1458     /// with [`App::long_flag_aliases`], except that they are visible inside the help message.
1459     ///
1460     /// # Examples
1461     ///
1462     /// ```no_run
1463     /// # use clap::{App, Arg, };
1464     /// let m = App::new("myprog")
1465     ///             .subcommand(App::new("test").long_flag("test")
1466     ///                 .visible_long_flag_aliases(&["testing", "testall", "test_all"]))
1467     ///             .get_matches_from(vec!["myprog", "--testing"]);
1468     /// assert_eq!(m.subcommand_name(), Some("test"));
1469     /// ```
1470     /// [`App::long_flag_aliases`]: App::long_flag_aliases()
visible_long_flag_aliases(mut self, names: &[&'help str]) -> Self1471     pub fn visible_long_flag_aliases(mut self, names: &[&'help str]) -> Self {
1472         for s in names {
1473             self.long_flag_aliases.push((s, true));
1474         }
1475         self
1476     }
1477 
1478     /// Replaces an argument or subcommand used on the CLI at runtime with other arguments or subcommands.
1479     ///
1480     /// **Note:** This is gated behind [`unstable-replace`](https://github.com/clap-rs/clap/issues/2836)
1481     ///
1482     /// When this method is used, `name` is removed from the CLI, and `target`
1483     /// is inserted in its place. Parsing continues as if the user typed
1484     /// `target` instead of `name`.
1485     ///
1486     /// This can be used to create "shortcuts" for subcommands, or if a
1487     /// particular argument has the semantic meaning of several other specific
1488     /// arguments and values.
1489     ///
1490     /// Some examples may help to clear this up.
1491     ///
1492     /// # Examples
1493     ///
1494     /// We'll start with the "subcommand short" example. In this example, let's
1495     /// assume we have a program with a subcommand `module` which can be invoked
1496     /// via `app module`. Now let's also assume `module` also has a subcommand
1497     /// called `install` which can be invoked `app module install`. If for some
1498     /// reason users needed to be able to reach `app module install` via the
1499     /// short-hand `app install`, we'd have several options.
1500     ///
1501     /// We *could* create another sibling subcommand to `module` called
1502     /// `install`, but then we would need to manage another subcommand and manually
1503     /// dispatch to `app module install` handling code. This is error prone and
1504     /// tedious.
1505     ///
1506     /// We could instead use [`App::replace`] so that, when the user types `app
1507     /// install`, `clap` will replace `install` with `module install` which will
1508     /// end up getting parsed as if the user typed the entire incantation.
1509     ///
1510     /// ```rust
1511     /// # use clap::App;
1512     /// let m = App::new("app")
1513     ///     .subcommand(App::new("module")
1514     ///         .subcommand(App::new("install")))
1515     ///     .replace("install", &["module", "install"])
1516     ///     .get_matches_from(vec!["app", "install"]);
1517     ///
1518     /// assert!(m.subcommand_matches("module").is_some());
1519     /// assert!(m.subcommand_matches("module").unwrap().subcommand_matches("install").is_some());
1520     /// ```
1521     ///
1522     /// Now let's show an argument example!
1523     ///
1524     /// Let's assume we have an application with two flags `--save-context` and
1525     /// `--save-runtime`. But often users end up needing to do *both* at the
1526     /// same time. We can add a third flag `--save-all` which semantically means
1527     /// the same thing as `app --save-context --save-runtime`. To implement that,
1528     /// we have several options.
1529     ///
1530     /// We could create this third argument and manually check if that argument
1531     /// and in our own consumer code handle the fact that both `--save-context`
1532     /// and `--save-runtime` *should* have been used. But again this is error
1533     /// prone and tedious. If we had code relying on checking `--save-context`
1534     /// and we forgot to update that code to *also* check `--save-all` it'd mean
1535     /// an error!
1536     ///
1537     /// Luckily we can use [`App::replace`] so that when the user types
1538     /// `--save-all`, `clap` will replace that argument with `--save-context
1539     /// --save-runtime`, and parsing will continue like normal. Now all our code
1540     /// that was originally checking for things like `--save-context` doesn't
1541     /// need to change!
1542     ///
1543     /// ```rust
1544     /// # use clap::{App, Arg};
1545     /// let m = App::new("app")
1546     ///     .arg(Arg::new("save-context")
1547     ///         .long("save-context"))
1548     ///     .arg(Arg::new("save-runtime")
1549     ///         .long("save-runtime"))
1550     ///     .replace("--save-all", &["--save-context", "--save-runtime"])
1551     ///     .get_matches_from(vec!["app", "--save-all"]);
1552     ///
1553     /// assert!(m.is_present("save-context"));
1554     /// assert!(m.is_present("save-runtime"));
1555     /// ```
1556     ///
1557     /// This can also be used with options, for example if our application with
1558     /// `--save-*` above also had a `--format=TYPE` option. Let's say it
1559     /// accepted `txt` or `json` values. However, when `--save-all` is used,
1560     /// only `--format=json` is allowed, or valid. We could change the example
1561     /// above to enforce this:
1562     ///
1563     /// ```rust
1564     /// # use clap::{App, Arg};
1565     /// let m = App::new("app")
1566     ///     .arg(Arg::new("save-context")
1567     ///         .long("save-context"))
1568     ///     .arg(Arg::new("save-runtime")
1569     ///         .long("save-runtime"))
1570     ///     .arg(Arg::new("format")
1571     ///         .long("format")
1572     ///         .takes_value(true)
1573     ///         .possible_values(["txt", "json"]))
1574     ///     .replace("--save-all", &["--save-context", "--save-runtime", "--format=json"])
1575     ///     .get_matches_from(vec!["app", "--save-all"]);
1576     ///
1577     /// assert!(m.is_present("save-context"));
1578     /// assert!(m.is_present("save-runtime"));
1579     /// assert_eq!(m.value_of("format"), Some("json"));
1580     /// ```
1581     ///
1582     /// [`App::replace`]: App::replace()
1583     #[inline]
1584     #[cfg(feature = "unstable-replace")]
replace(mut self, name: &'help str, target: &'help [&'help str]) -> Self1585     pub fn replace(mut self, name: &'help str, target: &'help [&'help str]) -> Self {
1586         self.replacers.insert(name, target);
1587         self
1588     }
1589 
1590     /// Adds an [`ArgGroup`] to the application. [`ArgGroup`]s are a family of related arguments.
1591     /// By placing them in a logical group, you can build easier requirement and exclusion rules.
1592     /// For instance, you can make an entire [`ArgGroup`] required, meaning that one (and *only*
1593     /// one) argument from that group must be present at runtime.
1594     ///
1595     /// You can also do things such as name an [`ArgGroup`] as a conflict to another argument.
1596     /// Meaning any of the arguments that belong to that group will cause a failure if present with
1597     /// the conflicting argument.
1598     ///
1599     /// Another added benefit of [`ArgGroup`]s is that you can extract a value from a group instead
1600     /// of determining exactly which argument was used.
1601     ///
1602     /// Finally, using [`ArgGroup`]s to ensure exclusion between arguments is another very common
1603     /// use.
1604     ///
1605     /// # Examples
1606     ///
1607     /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one,
1608     /// of the arguments from the specified group is present at runtime.
1609     ///
1610     /// ```no_run
1611     /// # use clap::{App, ArgGroup};
1612     /// App::new("app")
1613     ///     .arg("--set-ver [ver] 'set the version manually'")
1614     ///     .arg("--major 'auto increase major'")
1615     ///     .arg("--minor 'auto increase minor'")
1616     ///     .arg("--patch 'auto increase patch'")
1617     ///     .group(ArgGroup::new("vers")
1618     ///          .args(&["set-ver", "major", "minor","patch"])
1619     ///          .required(true))
1620     /// # ;
1621     /// ```
1622     #[inline]
group<G: Into<ArgGroup<'help>>>(mut self, group: G) -> Self1623     pub fn group<G: Into<ArgGroup<'help>>>(mut self, group: G) -> Self {
1624         self.groups.push(group.into());
1625         self
1626     }
1627 
1628     /// Adds multiple [`ArgGroup`]s to the [`App`] at once.
1629     ///
1630     /// # Examples
1631     ///
1632     /// ```no_run
1633     /// # use clap::{App, ArgGroup};
1634     /// App::new("app")
1635     ///     .arg("--set-ver [ver] 'set the version manually'")
1636     ///     .arg("--major         'auto increase major'")
1637     ///     .arg("--minor         'auto increase minor'")
1638     ///     .arg("--patch         'auto increase patch'")
1639     ///     .arg("-c [FILE]       'a config file'")
1640     ///     .arg("-i [IFACE]      'an interface'")
1641     ///     .groups(&[
1642     ///         ArgGroup::new("vers")
1643     ///             .args(&["set-ver", "major", "minor","patch"])
1644     ///             .required(true),
1645     ///         ArgGroup::new("input")
1646     ///             .args(&["c", "i"])
1647     ///     ])
1648     /// # ;
1649     /// ```
groups<I, T>(mut self, groups: I) -> Self where I: IntoIterator<Item = T>, T: Into<ArgGroup<'help>>,1650     pub fn groups<I, T>(mut self, groups: I) -> Self
1651     where
1652         I: IntoIterator<Item = T>,
1653         T: Into<ArgGroup<'help>>,
1654     {
1655         for g in groups.into_iter() {
1656             self = self.group(g.into());
1657         }
1658         self
1659     }
1660 
1661     /// Adds a subcommand to the list of valid possibilities. Subcommands are effectively
1662     /// sub-[`App`]s, because they can contain their own arguments, subcommands, version, usage,
1663     /// etc. They also function just like [`App`]s, in that they get their own auto generated help,
1664     /// version, and usage.
1665     ///
1666     /// # Examples
1667     ///
1668     /// ```no_run
1669     /// # use clap::{App, Arg, };
1670     /// App::new("myprog")
1671     ///     .subcommand(App::new("config")
1672     ///         .about("Controls configuration features")
1673     ///         .arg("<config> 'Required configuration file to use'"))
1674     /// # ;
1675     /// ```
1676     #[inline]
subcommand<S: Into<App<'help>>>(mut self, subcmd: S) -> Self1677     pub fn subcommand<S: Into<App<'help>>>(mut self, subcmd: S) -> Self {
1678         self.subcommands.push(subcmd.into());
1679         self
1680     }
1681 
1682     /// Adds multiple subcommands to the list of valid possibilities by iterating over an
1683     /// [`IntoIterator`] of [`App`]s.
1684     ///
1685     /// # Examples
1686     ///
1687     /// ```rust
1688     /// # use clap::{App, Arg, };
1689     /// # App::new("myprog")
1690     /// .subcommands( vec![
1691     ///        App::new("config").about("Controls configuration functionality")
1692     ///                                 .arg(Arg::new("config_file").index(1)),
1693     ///        App::new("debug").about("Controls debug functionality")])
1694     /// # ;
1695     /// ```
1696     /// [`IntoIterator`]: std::iter::IntoIterator
subcommands<I, T>(mut self, subcmds: I) -> Self where I: IntoIterator<Item = T>, T: Into<App<'help>>,1697     pub fn subcommands<I, T>(mut self, subcmds: I) -> Self
1698     where
1699         I: IntoIterator<Item = T>,
1700         T: Into<App<'help>>,
1701     {
1702         for subcmd in subcmds.into_iter() {
1703             self.subcommands.push(subcmd.into());
1704         }
1705         self
1706     }
1707 
1708     /// Allows custom ordering of subcommands within the help message. Subcommands with a lower
1709     /// value will be displayed first in the help message. This is helpful when one would like to
1710     /// emphasize frequently used subcommands, or prioritize those towards the top of the list.
1711     /// Duplicate values **are** allowed. Subcommands with duplicate display orders will be
1712     /// displayed in alphabetical order.
1713     ///
1714     /// **NOTE:** The default is 999 for all subcommands.
1715     ///
1716     /// # Examples
1717     ///
1718     /// ```rust
1719     /// # use clap::{App, };
1720     /// let m = App::new("cust-ord")
1721     ///     .subcommand(App::new("alpha") // typically subcommands are grouped
1722     ///                                                // alphabetically by name. Subcommands
1723     ///                                                // without a display_order have a value of
1724     ///                                                // 999 and are displayed alphabetically with
1725     ///                                                // all other 999 subcommands
1726     ///         .about("Some help and text"))
1727     ///     .subcommand(App::new("beta")
1728     ///         .display_order(1)   // In order to force this subcommand to appear *first*
1729     ///                             // all we have to do is give it a value lower than 999.
1730     ///                             // Any other subcommands with a value of 1 will be displayed
1731     ///                             // alphabetically with this one...then 2 values, then 3, etc.
1732     ///         .about("I should be first!"))
1733     ///     .get_matches_from(vec![
1734     ///         "cust-ord", "--help"
1735     ///     ]);
1736     /// ```
1737     ///
1738     /// The above example displays the following help message
1739     ///
1740     /// ```text
1741     /// cust-ord
1742     ///
1743     /// USAGE:
1744     ///     cust-ord [OPTIONS]
1745     ///
1746     /// OPTIONS:
1747     ///     -h, --help       Print help information
1748     ///     -V, --version    Print version information
1749     ///
1750     /// SUBCOMMANDS:
1751     ///     beta    I should be first!
1752     ///     alpha   Some help and text
1753     /// ```
1754     #[inline]
display_order(mut self, ord: usize) -> Self1755     pub fn display_order(mut self, ord: usize) -> Self {
1756         self.disp_ord = ord;
1757         self
1758     }
1759 
1760     /// Allows one to mutate an [`Arg`] after it's been added to an [`App`].
1761     ///
1762     /// # Examples
1763     ///
1764     /// ```rust
1765     /// # use clap::{App, Arg};
1766     ///
1767     /// let mut app = App::new("foo")
1768     ///     .arg(Arg::new("bar")
1769     ///         .short('b'))
1770     ///     .mut_arg("bar", |a| a.short('B'));
1771     ///
1772     /// let res = app.try_get_matches_from_mut(vec!["foo", "-b"]);
1773     ///
1774     /// // Since we changed `bar`'s short to "B" this should err as there
1775     /// // is no `-b` anymore, only `-B`
1776     ///
1777     /// assert!(res.is_err());
1778     ///
1779     /// let res = app.try_get_matches_from_mut(vec!["foo", "-B"]);
1780     /// assert!(res.is_ok());
1781     /// ```
mut_arg<T, F>(mut self, arg_id: T, f: F) -> Self where F: FnOnce(Arg<'help>) -> Arg<'help>, T: Key + Into<&'help str>,1782     pub fn mut_arg<T, F>(mut self, arg_id: T, f: F) -> Self
1783     where
1784         F: FnOnce(Arg<'help>) -> Arg<'help>,
1785         T: Key + Into<&'help str>,
1786     {
1787         let arg_id: &str = arg_id.into();
1788         let id = Id::from(arg_id);
1789 
1790         let mut a = self.args.remove_by_name(&id).unwrap_or_else(|| Arg {
1791             id,
1792             name: arg_id,
1793             ..Arg::default()
1794         });
1795 
1796         if a.provider == ArgProvider::Generated {
1797             a.provider = ArgProvider::GeneratedMutated;
1798         }
1799 
1800         self.args.push(f(a));
1801         self
1802     }
1803 
1804     /// Custom error message for post-parsing validation
1805     ///
1806     /// # Examples
1807     ///
1808     /// ```rust
1809     /// # use clap::{App, ErrorKind};
1810     /// let mut app = App::new("myprog");
1811     /// let err = app.error(ErrorKind::InvalidValue, "Some failure case");
1812     /// ```
error(&mut self, kind: ErrorKind, message: impl std::fmt::Display) -> Error1813     pub fn error(&mut self, kind: ErrorKind, message: impl std::fmt::Display) -> Error {
1814         self._build();
1815         let usage = self.render_usage();
1816         Error::user_error(self, usage, kind, message)
1817     }
1818 
1819     /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same
1820     /// method as if someone ran `-h` to request the help message.
1821     ///
1822     /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1823     /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1824     ///
1825     /// # Examples
1826     ///
1827     /// ```rust
1828     /// # use clap::App;
1829     /// let mut app = App::new("myprog");
1830     /// app.print_help();
1831     /// ```
1832     /// [`io::stdout()`]: std::io::stdout()
1833     /// [`BufWriter`]: std::io::BufWriter
1834     /// [`-h` (short)]: Arg::about()
1835     /// [`--help` (long)]: Arg::long_about()
print_help(&mut self) -> io::Result<()>1836     pub fn print_help(&mut self) -> io::Result<()> {
1837         self._build();
1838         let color = self.get_color();
1839 
1840         let p = Parser::new(self);
1841         let mut c = Colorizer::new(false, color);
1842         Help::new(HelpWriter::Buffer(&mut c), &p, false).write_help()?;
1843         c.print()
1844     }
1845 
1846     /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same
1847     /// method as if someone ran `--help` to request the help message.
1848     ///
1849     /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1850     /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1851     ///
1852     /// # Examples
1853     ///
1854     /// ```rust
1855     /// # use clap::App;
1856     /// let mut app = App::new("myprog");
1857     /// app.print_long_help();
1858     /// ```
1859     /// [`io::stdout()`]: std::io::stdout()
1860     /// [`BufWriter`]: std::io::BufWriter
1861     /// [`-h` (short)]: Arg::about()
1862     /// [`--help` (long)]: Arg::long_about()
print_long_help(&mut self) -> io::Result<()>1863     pub fn print_long_help(&mut self) -> io::Result<()> {
1864         self._build();
1865         let color = self.get_color();
1866 
1867         let p = Parser::new(self);
1868         let mut c = Colorizer::new(false, color);
1869         Help::new(HelpWriter::Buffer(&mut c), &p, true).write_help()?;
1870         c.print()
1871     }
1872 
1873     /// Writes the full help message to the user to a [`io::Write`] object in the same method as if
1874     /// the user ran `-h`.
1875     ///
1876     /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1877     /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1878     ///
1879     /// # Examples
1880     ///
1881     /// ```rust
1882     /// # use clap::App;
1883     /// use std::io;
1884     /// let mut app = App::new("myprog");
1885     /// let mut out = io::stdout();
1886     /// app.write_help(&mut out).expect("failed to write to stdout");
1887     /// ```
1888     /// [`io::Write`]: std::io::Write
1889     /// [`-h` (short)]: Arg::about()
1890     /// [`--help` (long)]: Arg::long_about()
write_help<W: Write>(&mut self, w: &mut W) -> io::Result<()>1891     pub fn write_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
1892         self._build();
1893 
1894         let p = Parser::new(self);
1895         Help::new(HelpWriter::Normal(w), &p, false).write_help()?;
1896         w.flush()
1897     }
1898 
1899     /// Writes the full help message to the user to a [`io::Write`] object in the same method as if
1900     /// the user ran `--help`.
1901     ///
1902     /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1903     /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1904     ///
1905     /// # Examples
1906     ///
1907     /// ```rust
1908     /// # use clap::App;
1909     /// use std::io;
1910     /// let mut app = App::new("myprog");
1911     /// let mut out = io::stdout();
1912     /// app.write_long_help(&mut out).expect("failed to write to stdout");
1913     /// ```
1914     /// [`io::Write`]: std::io::Write
1915     /// [`-h` (short)]: Arg::about()
1916     /// [`--help` (long)]: Arg::long_about()
write_long_help<W: Write>(&mut self, w: &mut W) -> io::Result<()>1917     pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
1918         self._build();
1919 
1920         let p = Parser::new(self);
1921         Help::new(HelpWriter::Normal(w), &p, true).write_help()?;
1922         w.flush()
1923     }
1924 
1925     /// Returns the version message rendered as if the user ran `-V`.
1926     ///
1927     /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages
1928     /// depending on if the user ran [`-V` (short)] or [`--version` (long)].
1929     ///
1930     /// ### Coloring
1931     ///
1932     /// This function does not try to color the message nor it inserts any [ANSI escape codes].
1933     ///
1934     /// ### Examples
1935     ///
1936     /// ```rust
1937     /// # use clap::App;
1938     /// use std::io;
1939     /// let app = App::new("myprog");
1940     /// println!("{}", app.render_version());
1941     /// ```
1942     /// [`io::Write`]: std::io::Write
1943     /// [`-V` (short)]: App::version()
1944     /// [`--version` (long)]: App::long_version()
1945     /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
render_version(&self) -> String1946     pub fn render_version(&self) -> String {
1947         self._render_version(false)
1948     }
1949 
1950     /// Returns the version message rendered as if the user ran `--version`.
1951     ///
1952     /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages
1953     /// depending on if the user ran [`-V` (short)] or [`--version` (long)].
1954     ///
1955     /// ### Coloring
1956     ///
1957     /// This function does not try to color the message nor it inserts any [ANSI escape codes].
1958     ///
1959     /// ### Examples
1960     ///
1961     /// ```rust
1962     /// # use clap::App;
1963     /// use std::io;
1964     /// let app = App::new("myprog");
1965     /// println!("{}", app.render_long_version());
1966     /// ```
1967     /// [`io::Write`]: std::io::Write
1968     /// [`-V` (short)]: App::version()
1969     /// [`--version` (long)]: App::long_version()
1970     /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
render_long_version(&self) -> String1971     pub fn render_long_version(&self) -> String {
1972         self._render_version(true)
1973     }
1974 
1975     /// Returns the usage statement
1976     ///
1977     /// ### Examples
1978     ///
1979     /// ```rust
1980     /// # use clap::App;
1981     /// use std::io;
1982     /// let mut app = App::new("myprog");
1983     /// println!("{}", app.render_usage());
1984     /// ```
render_usage(&mut self) -> String1985     pub fn render_usage(&mut self) -> String {
1986         // If there are global arguments, or settings we need to propagate them down to subcommands
1987         // before parsing incase we run into a subcommand
1988         self._build();
1989 
1990         let mut parser = Parser::new(self);
1991         parser._build();
1992         Usage::new(&parser).create_usage_with_title(&[])
1993     }
1994 
1995     /// Starts the parsing process, upon a failed parse an error will be displayed to the user and
1996     /// the process will exit with the appropriate error code. By default this method gets all user
1997     /// provided arguments from [`env::args_os`] in order to allow for invalid UTF-8 code points,
1998     /// which are legal on many platforms.
1999     ///
2000     /// # Examples
2001     ///
2002     /// ```no_run
2003     /// # use clap::{App, Arg};
2004     /// let matches = App::new("myprog")
2005     ///     // Args and options go here...
2006     ///     .get_matches();
2007     /// ```
2008     /// [`env::args_os`]: std::env::args_os()
2009     /// [`App::try_get_matches_from_mut`]: App::try_get_matches_from_mut()
2010     #[inline]
get_matches(self) -> ArgMatches2011     pub fn get_matches(self) -> ArgMatches {
2012         self.get_matches_from(&mut env::args_os())
2013     }
2014 
2015     /// Starts the parsing process, just like [`App::get_matches`] but doesn't consume the `App`.
2016     ///
2017     /// # Examples
2018     ///
2019     /// ```no_run
2020     /// # use clap::{App, Arg};
2021     /// let mut app = App::new("myprog")
2022     ///     // Args and options go here...
2023     ///     ;
2024     /// let matches = app.get_matches_mut();
2025     /// ```
2026     /// [`env::args_os`]: std::env::args_os()
2027     /// [`App::get_matches`]: App::get_matches()
get_matches_mut(&mut self) -> ArgMatches2028     pub fn get_matches_mut(&mut self) -> ArgMatches {
2029         self.try_get_matches_from_mut(&mut env::args_os())
2030             .unwrap_or_else(|e| {
2031                 // Otherwise, write to stderr and exit
2032                 if e.use_stderr() {
2033                     e.message.print().expect("Error writing Error to stderr");
2034 
2035                     if self.settings.is_set(AppSettings::WaitOnError) {
2036                         wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
2037                         let mut s = String::new();
2038                         let i = io::stdin();
2039                         i.lock().read_line(&mut s).unwrap();
2040                     }
2041 
2042                     drop(e);
2043                     safe_exit(USAGE_CODE);
2044                 }
2045 
2046                 e.exit()
2047             })
2048     }
2049 
2050     /// Starts the parsing process. This method will return a [`clap::Result`] type instead of exiting
2051     /// the process on failed parse. By default this method gets matches from [`env::args_os`].
2052     ///
2053     /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
2054     /// used. It will return a [`clap::Error`], where the [`kind`] is a
2055     /// [`ErrorKind::DisplayHelp`] or [`ErrorKind::DisplayVersion`] respectively. You must call
2056     /// [`Error::exit`] or perform a [`std::process::exit`].
2057     ///
2058     /// # Examples
2059     ///
2060     /// ```no_run
2061     /// # use clap::{App, Arg};
2062     /// let matches = App::new("myprog")
2063     ///     // Args and options go here...
2064     ///     .try_get_matches()
2065     ///     .unwrap_or_else(|e| e.exit());
2066     /// ```
2067     /// [`env::args_os`]: std::env::args_os()
2068     /// [`Error::exit`]: crate::Error::exit()
2069     /// [`std::process::exit`]: std::process::exit()
2070     /// [`clap::Result`]: Result
2071     /// [`clap::Error`]: crate::Error
2072     /// [`kind`]: crate::Error
2073     /// [`ErrorKind::DisplayHelp`]: crate::ErrorKind::DisplayHelp
2074     /// [`ErrorKind::DisplayVersion`]: crate::ErrorKind::DisplayVersion
2075     #[inline]
try_get_matches(self) -> ClapResult<ArgMatches>2076     pub fn try_get_matches(self) -> ClapResult<ArgMatches> {
2077         // Start the parsing
2078         self.try_get_matches_from(&mut env::args_os())
2079     }
2080 
2081     /// Deprecated, see [`App::try_get_matches`]
2082     #[deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches`")]
get_matches_safe(self) -> ClapResult<ArgMatches>2083     pub fn get_matches_safe(self) -> ClapResult<ArgMatches> {
2084         self.try_get_matches()
2085     }
2086 
2087     /// Starts the parsing process. Like [`App::get_matches`] this method does not return a [`clap::Result`]
2088     /// and will automatically exit with an error message. This method, however, lets you specify
2089     /// what iterator to use when performing matches, such as a [`Vec`] of your making.
2090     ///
2091     /// **NOTE:** The first argument will be parsed as the binary name unless
2092     /// [`AppSettings::NoBinaryName`] is used.
2093     ///
2094     /// # Examples
2095     ///
2096     /// ```no_run
2097     /// # use clap::{App, Arg};
2098     /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2099     ///
2100     /// let matches = App::new("myprog")
2101     ///     // Args and options go here...
2102     ///     .get_matches_from(arg_vec);
2103     /// ```
2104     /// [`App::get_matches`]: App::get_matches()
2105     /// [`clap::Result`]: Result
2106     /// [`Vec`]: std::vec::Vec
get_matches_from<I, T>(mut self, itr: I) -> ArgMatches where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,2107     pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches
2108     where
2109         I: IntoIterator<Item = T>,
2110         T: Into<OsString> + Clone,
2111     {
2112         self.try_get_matches_from_mut(itr).unwrap_or_else(|e| {
2113             // Otherwise, write to stderr and exit
2114             if e.use_stderr() {
2115                 e.message.print().expect("Error writing Error to stderr");
2116 
2117                 if self.settings.is_set(AppSettings::WaitOnError) {
2118                     wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
2119                     let mut s = String::new();
2120                     let i = io::stdin();
2121                     i.lock().read_line(&mut s).unwrap();
2122                 }
2123 
2124                 drop(self);
2125                 drop(e);
2126                 safe_exit(USAGE_CODE);
2127             }
2128 
2129             drop(self);
2130             e.exit()
2131         })
2132     }
2133 
2134     /// Starts the parsing process. A combination of [`App::get_matches_from`], and
2135     /// [`App::try_get_matches`].
2136     ///
2137     /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
2138     /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`]
2139     /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or
2140     /// perform a [`std::process::exit`] yourself.
2141     ///
2142     /// **NOTE:** The first argument will be parsed as the binary name unless
2143     /// [`AppSettings::NoBinaryName`] is used.
2144     ///
2145     /// # Examples
2146     ///
2147     /// ```no_run
2148     /// # use clap::{App, Arg};
2149     /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2150     ///
2151     /// let matches = App::new("myprog")
2152     ///     // Args and options go here...
2153     ///     .try_get_matches_from(arg_vec)
2154     ///     .unwrap_or_else(|e| e.exit());
2155     /// ```
2156     /// [`App::get_matches_from`]: App::get_matches_from()
2157     /// [`App::try_get_matches`]: App::try_get_matches()
2158     /// [`Error::exit`]: crate::Error::exit()
2159     /// [`std::process::exit`]: std::process::exit()
2160     /// [`clap::Error`]: crate::Error
2161     /// [`Error::exit`]: crate::Error::exit()
2162     /// [`kind`]: crate::Error
2163     /// [`ErrorKind::DisplayHelp`]: crate::ErrorKind::DisplayHelp
2164     /// [`ErrorKind::DisplayVersion`]: crate::ErrorKind::DisplayVersion
try_get_matches_from<I, T>(mut self, itr: I) -> ClapResult<ArgMatches> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,2165     pub fn try_get_matches_from<I, T>(mut self, itr: I) -> ClapResult<ArgMatches>
2166     where
2167         I: IntoIterator<Item = T>,
2168         T: Into<OsString> + Clone,
2169     {
2170         self.try_get_matches_from_mut(itr)
2171     }
2172 
2173     /// Deprecated, see [`App::try_get_matches_from`]
2174     #[deprecated(since = "3.0.0", note = "Replaced with `App::try_get_matches_from`")]
get_matches_from_safe<I, T>(self, itr: I) -> ClapResult<ArgMatches> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,2175     pub fn get_matches_from_safe<I, T>(self, itr: I) -> ClapResult<ArgMatches>
2176     where
2177         I: IntoIterator<Item = T>,
2178         T: Into<OsString> + Clone,
2179     {
2180         self.try_get_matches_from(itr)
2181     }
2182 
2183     /// Starts the parsing process without consuming the [`App`] struct `self`. This is normally not
2184     /// the desired functionality, instead prefer [`App::try_get_matches_from`] which *does*
2185     /// consume `self`.
2186     ///
2187     /// **NOTE:** The first argument will be parsed as the binary name unless
2188     /// [`AppSettings::NoBinaryName`] is used.
2189     ///
2190     /// # Examples
2191     ///
2192     /// ```no_run
2193     /// # use clap::{App, Arg};
2194     /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2195     ///
2196     /// let mut app = App::new("myprog");
2197     ///     // Args and options go here...
2198     /// let matches = app.try_get_matches_from_mut(arg_vec)
2199     ///     .unwrap_or_else(|e| e.exit());
2200     /// ```
2201     /// [`App::try_get_matches_from`]: App::try_get_matches_from()
try_get_matches_from_mut<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,2202     pub fn try_get_matches_from_mut<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches>
2203     where
2204         I: IntoIterator<Item = T>,
2205         T: Into<OsString> + Clone,
2206     {
2207         let mut it = Input::from(itr.into_iter());
2208 
2209         #[cfg(feature = "unstable-multicall")]
2210         if self.settings.is_set(AppSettings::Multicall) {
2211             if let Some((argv0, _)) = it.next() {
2212                 let argv0 = Path::new(&argv0);
2213                 if let Some(command) = argv0.file_name().and_then(|f| f.to_str()) {
2214                     // Stop borrowing command so we can get another mut ref to it.
2215                     let command = command.to_owned();
2216                     debug!(
2217                         "App::try_get_matches_from_mut: Parsed command {} from argv",
2218                         command
2219                     );
2220 
2221                     let subcommand = self
2222                         .subcommands
2223                         .iter_mut()
2224                         .find(|subcommand| subcommand.aliases_to(&command));
2225                     debug!(
2226                         "App::try_get_matches_from_mut: Matched subcommand {:?}",
2227                         subcommand
2228                     );
2229 
2230                     match subcommand {
2231                         None if command == self.name => {
2232                             debug!("App::try_get_matches_from_mut: no existing applet but matches name");
2233                             debug!(
2234                                 "App::try_get_matches_from_mut: Setting bin_name to command name"
2235                             );
2236                             self.bin_name.get_or_insert(command);
2237                             debug!(
2238                                 "App::try_get_matches_from_mut: Continuing with top-level parser."
2239                             );
2240                             return self._do_parse(&mut it);
2241                         }
2242                         _ => {
2243                             debug!(
2244                                 "App::try_get_matches_from_mut: existing applet or no program name"
2245                             );
2246                             debug!("App::try_get_matches_from_mut: Reinserting command into arguments so subcommand parser matches it");
2247                             it.insert(&[&command]);
2248                             debug!("App::try_get_matches_from_mut: Clearing name and bin_name so that displayed command name starts with applet name");
2249                             self.name.clear();
2250                             self.bin_name = None;
2251                             return self._do_parse(&mut it);
2252                         }
2253                     };
2254                 }
2255             }
2256         };
2257         // Get the name of the program (argument 1 of env::args()) and determine the
2258         // actual file
2259         // that was used to execute the program. This is because a program called
2260         // ./target/release/my_prog -a
2261         // will have two arguments, './target/release/my_prog', '-a' but we don't want
2262         // to display
2263         // the full path when displaying help messages and such
2264         if !self.settings.is_set(AppSettings::NoBinaryName) {
2265             if let Some((name, _)) = it.next() {
2266                 let p = Path::new(name);
2267 
2268                 if let Some(f) = p.file_name() {
2269                     if let Some(s) = f.to_str() {
2270                         if self.bin_name.is_none() {
2271                             self.bin_name = Some(s.to_owned());
2272                         }
2273                     }
2274                 }
2275             }
2276         }
2277 
2278         self._do_parse(&mut it)
2279     }
2280 
2281     /// Deprecated, see [`App::try_get_matches_from_mut`]
2282     #[deprecated(
2283         since = "3.0.0",
2284         note = "Replaced with `App::try_get_matches_from_mut`"
2285     )]
get_matches_from_safe_borrow<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches> where I: IntoIterator<Item = T>, T: Into<OsString> + Clone,2286     pub fn get_matches_from_safe_borrow<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches>
2287     where
2288         I: IntoIterator<Item = T>,
2289         T: Into<OsString> + Clone,
2290     {
2291         self.try_get_matches_from_mut(itr)
2292     }
2293 
2294     /// Sets the placeholder text used for subcommands when printing usage and help.
2295     /// By default, this is "SUBCOMMAND" with a header of "SUBCOMMANDS".
2296     ///
2297     /// # Examples
2298     ///
2299     /// ```no_run
2300     /// # use clap::{App, Arg};
2301     /// App::new("myprog")
2302     ///     .subcommand(App::new("sub1"))
2303     ///     .print_help()
2304     /// # ;
2305     /// ```
2306     ///
2307     /// will produce
2308     ///
2309     /// ```text
2310     /// myprog
2311     ///
2312     /// USAGE:
2313     ///     myprog [SUBCOMMAND]
2314     ///
2315     /// OPTIONS:
2316     ///     -h, --help       Print help information
2317     ///     -V, --version    Print version information
2318     ///
2319     /// SUBCOMMANDS:
2320     ///     help    Print this message or the help of the given subcommand(s)
2321     ///     sub1
2322     /// ```
2323     ///
2324     /// but usage of `subcommand_placeholder`
2325     ///
2326     /// ```no_run
2327     /// # use clap::{App, Arg};
2328     /// App::new("myprog")
2329     ///     .subcommand(App::new("sub1"))
2330     ///     .subcommand_placeholder("THING", "THINGS")
2331     ///     .print_help()
2332     /// # ;
2333     /// ```
2334     ///
2335     /// will produce
2336     ///
2337     /// ```text
2338     /// myprog
2339     ///
2340     /// USAGE:
2341     ///     myprog [THING]
2342     ///
2343     /// OPTIONS:
2344     ///     -h, --help       Print help information
2345     ///     -V, --version    Print version information
2346     ///
2347     /// THINGS:
2348     ///     help    Print this message or the help of the given subcommand(s)
2349     ///     sub1
2350     /// ```
subcommand_placeholder<S, T>(mut self, placeholder: S, header: T) -> Self where S: Into<&'help str>, T: Into<&'help str>,2351     pub fn subcommand_placeholder<S, T>(mut self, placeholder: S, header: T) -> Self
2352     where
2353         S: Into<&'help str>,
2354         T: Into<&'help str>,
2355     {
2356         self.subcommand_placeholder = Some(placeholder.into());
2357         self.subcommand_header = Some(header.into());
2358         self
2359     }
2360 }
2361 
2362 // Internally used only
2363 impl<'help> App<'help> {
get_used_global_args(&self, matcher: &ArgMatcher) -> Vec<Id>2364     fn get_used_global_args(&self, matcher: &ArgMatcher) -> Vec<Id> {
2365         let global_args: Vec<_> = self
2366             .args
2367             .args()
2368             .filter(|a| a.global)
2369             .map(|ga| ga.id.clone())
2370             .collect();
2371         if let Some(used_subcommand) = matcher.0.subcommand.as_ref() {
2372             if let Some(used_subcommand) = self
2373                 .subcommands
2374                 .iter()
2375                 .find(|subcommand| subcommand.id == used_subcommand.id)
2376             {
2377                 return [global_args, used_subcommand.get_used_global_args(matcher)].concat();
2378             }
2379         }
2380         global_args
2381     }
2382 
_do_parse(&mut self, it: &mut Input) -> ClapResult<ArgMatches>2383     fn _do_parse(&mut self, it: &mut Input) -> ClapResult<ArgMatches> {
2384         debug!("App::_do_parse");
2385         let mut matcher = ArgMatcher::default();
2386 
2387         // If there are global arguments, or settings we need to propagate them down to subcommands
2388         // before parsing in case we run into a subcommand
2389         self._build();
2390 
2391         // do the real parsing
2392         let mut parser = Parser::new(self);
2393         if let Err(error) = parser.get_matches_with(&mut matcher, it) {
2394             if self.is_set(AppSettings::IgnoreErrors) {
2395                 debug!("App::_do_parse: ignoring error: {}", error);
2396             } else {
2397                 return Err(error);
2398             }
2399         }
2400 
2401         let global_arg_vec: Vec<Id> = self.get_used_global_args(&matcher);
2402 
2403         matcher.propagate_globals(&global_arg_vec);
2404 
2405         Ok(matcher.into_inner())
2406     }
2407 
2408     // used in clap_generate (https://github.com/clap-rs/clap_generate)
2409     #[doc(hidden)]
_build_all(&mut self)2410     pub fn _build_all(&mut self) {
2411         self._build();
2412         for subcmd in self.get_subcommands_mut() {
2413             subcmd._build();
2414         }
2415         self._build_bin_names();
2416     }
2417 
2418     // used in clap_generate (https://github.com/clap-rs/clap_generate)
2419     #[doc(hidden)]
_build(&mut self)2420     pub fn _build(&mut self) {
2421         debug!("App::_build");
2422         if !self.settings.is_set(AppSettings::Built) {
2423             // Make sure all the globally set flags apply to us as well
2424             self.settings = self.settings | self.g_settings;
2425 
2426             self._propagate();
2427             self._check_help_and_version();
2428             self._propagate_global_args();
2429             self._derive_display_order();
2430 
2431             let mut pos_counter = 1;
2432             for a in self.args.args_mut() {
2433                 // Fill in the groups
2434                 for g in &a.groups {
2435                     if let Some(ag) = self.groups.iter_mut().find(|grp| grp.id == *g) {
2436                         ag.args.push(a.id.clone());
2437                     } else {
2438                         let mut ag = ArgGroup::with_id(g.clone());
2439                         ag.args.push(a.id.clone());
2440                         self.groups.push(ag);
2441                     }
2442                 }
2443 
2444                 // Figure out implied settings
2445                 if a.is_set(ArgSettings::Last) {
2446                     // if an arg has `Last` set, we need to imply DontCollapseArgsInUsage so that args
2447                     // in the usage string don't get confused or left out.
2448                     self.settings.set(AppSettings::DontCollapseArgsInUsage);
2449                 }
2450                 a._build();
2451                 if a.is_positional() && a.index.is_none() {
2452                     a.index = Some(pos_counter);
2453                     pos_counter += 1;
2454                 }
2455             }
2456 
2457             self.args._build();
2458 
2459             #[cfg(debug_assertions)]
2460             self::debug_asserts::assert_app(self);
2461             self.settings.set(AppSettings::Built);
2462         } else {
2463             debug!("App::_build: already built");
2464         }
2465     }
2466 
_panic_on_missing_help(&self, help_required_globally: bool)2467     fn _panic_on_missing_help(&self, help_required_globally: bool) {
2468         if self.is_set(AppSettings::HelpRequired) || help_required_globally {
2469             let args_missing_help: Vec<String> = self
2470                 .args
2471                 .args()
2472                 .filter(|arg| arg.about.is_none() && arg.long_about.is_none())
2473                 .map(|arg| String::from(arg.name))
2474                 .collect();
2475 
2476             assert!(args_missing_help.is_empty(),
2477                     "AppSettings::HelpRequired is enabled for the App {}, but at least one of its arguments does not have either `help` or `long_help` set. List of such arguments: {}",
2478                     self.name,
2479                     args_missing_help.join(", ")
2480                 );
2481         }
2482 
2483         for sub_app in &self.subcommands {
2484             sub_app._panic_on_missing_help(help_required_globally);
2485         }
2486     }
2487 
2488     #[cfg(debug_assertions)]
two_args_of<F>(&self, condition: F) -> Option<(&Arg<'help>, &Arg<'help>)> where F: Fn(&Arg) -> bool,2489     fn two_args_of<F>(&self, condition: F) -> Option<(&Arg<'help>, &Arg<'help>)>
2490     where
2491         F: Fn(&Arg) -> bool,
2492     {
2493         two_elements_of(self.args.args().filter(|a: &&Arg| condition(a)))
2494     }
2495 
2496     // just in case
2497     #[allow(unused)]
two_groups_of<F>(&self, condition: F) -> Option<(&ArgGroup, &ArgGroup)> where F: Fn(&ArgGroup) -> bool,2498     fn two_groups_of<F>(&self, condition: F) -> Option<(&ArgGroup, &ArgGroup)>
2499     where
2500         F: Fn(&ArgGroup) -> bool,
2501     {
2502         two_elements_of(self.groups.iter().filter(|a| condition(a)))
2503     }
2504 
2505     /// Propagate global args
_propagate_global_args(&mut self)2506     pub(crate) fn _propagate_global_args(&mut self) {
2507         debug!("App::_propagate_global_args:{}", self.name);
2508 
2509         for sc in &mut self.subcommands {
2510             for a in self.args.args().filter(|a| a.global) {
2511                 let mut propagate = false;
2512                 let is_generated = matches!(
2513                     a.provider,
2514                     ArgProvider::Generated | ArgProvider::GeneratedMutated
2515                 );
2516 
2517                 // Remove generated help and version args in the subcommand
2518                 //
2519                 // Don't remove if those args are futher mutated
2520                 if is_generated {
2521                     let generated_pos = sc
2522                         .args
2523                         .args()
2524                         .position(|x| x.id == a.id && x.provider == ArgProvider::Generated);
2525 
2526                     if let Some(index) = generated_pos {
2527                         sc.args.remove(index);
2528                         propagate = true;
2529                     }
2530                 }
2531 
2532                 if propagate || sc.find(&a.id).is_none() {
2533                     sc.args.push(a.clone());
2534                 }
2535             }
2536         }
2537     }
2538 
2539     /// Propagate settings
_propagate(&mut self)2540     pub(crate) fn _propagate(&mut self) {
2541         macro_rules! propagate_subcmd {
2542             ($_self:expr, $sc:expr) => {{
2543                 // We have to create a new scope in order to tell rustc the borrow of `sc` is
2544                 // done and to recursively call this method
2545                 {
2546                     if $_self.settings.is_set(AppSettings::PropagateVersion) {
2547                         if $sc.version.is_none() && $_self.version.is_some() {
2548                             $sc.version = Some($_self.version.unwrap());
2549                         }
2550                         if $sc.long_version.is_none() && $_self.long_version.is_some() {
2551                             $sc.long_version = Some($_self.long_version.unwrap());
2552                         }
2553                     }
2554 
2555                     $sc.settings = $sc.settings | $_self.g_settings;
2556                     $sc.g_settings = $sc.g_settings | $_self.g_settings;
2557                     $sc.term_w = $_self.term_w;
2558                     $sc.max_w = $_self.max_w;
2559                 }
2560             }};
2561         }
2562 
2563         debug!("App::_propagate:{}", self.name);
2564 
2565         for sc in &mut self.subcommands {
2566             propagate_subcmd!(self, sc);
2567         }
2568     }
2569 
2570     #[allow(clippy::blocks_in_if_conditions)]
_check_help_and_version(&mut self)2571     pub(crate) fn _check_help_and_version(&mut self) {
2572         debug!("App::_check_help_and_version");
2573 
2574         if self.is_set(AppSettings::DisableHelpFlag)
2575             || self.args.args().any(|x| {
2576                 x.provider == ArgProvider::User
2577                     && (x.long == Some("help") || x.id == Id::help_hash())
2578             })
2579             || self
2580                 .subcommands
2581                 .iter()
2582                 .any(|sc| sc.long_flag == Some("help"))
2583         {
2584             debug!("App::_check_help_and_version: Removing generated help");
2585 
2586             let generated_help_pos = self
2587                 .args
2588                 .args()
2589                 .position(|x| x.id == Id::help_hash() && x.provider == ArgProvider::Generated);
2590 
2591             if let Some(index) = generated_help_pos {
2592                 self.args.remove(index);
2593             }
2594         } else {
2595             let other_arg_has_short = self.args.args().any(|x| x.short == Some('h'));
2596             let help = self
2597                 .args
2598                 .args_mut()
2599                 .find(|x| x.id == Id::help_hash())
2600                 .expect(INTERNAL_ERROR_MSG);
2601 
2602             if !(help.short.is_some()
2603                 || other_arg_has_short
2604                 || self.subcommands.iter().any(|sc| sc.short_flag == Some('h')))
2605             {
2606                 help.short = Some('h');
2607             }
2608         }
2609 
2610         // Determine if we should remove the generated --version flag
2611         //
2612         // Note that if only mut_arg() was used, the first expression will evaluate to `true`
2613         // however inside the condition block, we only check for Generated args, not
2614         // GeneratedMutated args, so the `mut_arg("version", ..) will be skipped and fall through
2615         // to the following condition below (Adding the short `-V`)
2616         if self.settings.is_set(AppSettings::DisableVersionFlag)
2617             || (self.version.is_none() && self.long_version.is_none())
2618             || self.args.args().any(|x| {
2619                 x.provider == ArgProvider::User
2620                     && (x.long == Some("version") || x.id == Id::version_hash())
2621             })
2622             || self
2623                 .subcommands
2624                 .iter()
2625                 .any(|sc| sc.long_flag == Some("version"))
2626         {
2627             debug!("App::_check_help_and_version: Removing generated version");
2628 
2629             // This is the check mentioned above that only checks for Generated, not
2630             // GeneratedMuated args by design.
2631             let generated_version_pos = self
2632                 .args
2633                 .args()
2634                 .position(|x| x.id == Id::version_hash() && x.provider == ArgProvider::Generated);
2635 
2636             if let Some(index) = generated_version_pos {
2637                 self.args.remove(index);
2638             }
2639         }
2640 
2641         // If we still have a generated --version flag, determine if we can apply the short `-V`
2642         if self.args.args().any(|x| {
2643             x.id == Id::version_hash()
2644                 && matches!(
2645                     x.provider,
2646                     ArgProvider::Generated | ArgProvider::GeneratedMutated
2647                 )
2648         }) {
2649             let other_arg_has_short = self.args.args().any(|x| x.short == Some('V'));
2650             let version = self
2651                 .args
2652                 .args_mut()
2653                 .find(|x| x.id == Id::version_hash())
2654                 .expect(INTERNAL_ERROR_MSG);
2655 
2656             if !(version.short.is_some()
2657                 || other_arg_has_short
2658                 || self.subcommands.iter().any(|sc| sc.short_flag == Some('V')))
2659             {
2660                 version.short = Some('V');
2661             }
2662         }
2663 
2664         if !self.is_set(AppSettings::DisableHelpSubcommand)
2665             && self.has_subcommands()
2666             && !self.subcommands.iter().any(|s| s.id == Id::help_hash())
2667         {
2668             debug!("App::_check_help_and_version: Building help subcommand");
2669             self.subcommands.push(
2670                 App::new("help").about("Print this message or the help of the given subcommand(s)"),
2671             );
2672         }
2673     }
2674 
_derive_display_order(&mut self)2675     pub(crate) fn _derive_display_order(&mut self) {
2676         debug!("App::_derive_display_order:{}", self.name);
2677 
2678         if self.settings.is_set(AppSettings::DeriveDisplayOrder) {
2679             for (i, a) in self
2680                 .args
2681                 .args_mut()
2682                 .filter(|a| !a.is_positional())
2683                 .filter(|a| a.disp_ord == 999)
2684                 .filter(|a| a.provider != ArgProvider::Generated)
2685                 .enumerate()
2686             {
2687                 a.disp_ord = i;
2688             }
2689             for (i, mut sc) in &mut self
2690                 .subcommands
2691                 .iter_mut()
2692                 .enumerate()
2693                 .filter(|&(_, ref sc)| sc.disp_ord == 999)
2694             {
2695                 sc.disp_ord = i;
2696             }
2697         }
2698         for sc in &mut self.subcommands {
2699             sc._derive_display_order();
2700         }
2701     }
2702 
2703     // used in clap_generate (https://github.com/clap-rs/clap_generate)
2704     #[doc(hidden)]
_build_bin_names(&mut self)2705     pub fn _build_bin_names(&mut self) {
2706         debug!("App::_build_bin_names");
2707 
2708         if !self.is_set(AppSettings::BinNameBuilt) {
2709             for mut sc in &mut self.subcommands {
2710                 debug!("App::_build_bin_names:iter: bin_name set...");
2711 
2712                 if sc.bin_name.is_none() {
2713                     debug!("No");
2714                     let bin_name = format!(
2715                         "{}{}{}",
2716                         self.bin_name.as_ref().unwrap_or(&self.name.clone()),
2717                         if self.bin_name.is_some() { " " } else { "" },
2718                         &*sc.name
2719                     );
2720                     debug!(
2721                         "App::_build_bin_names:iter: Setting bin_name of {} to {}",
2722                         self.name, bin_name
2723                     );
2724                     sc.bin_name = Some(bin_name);
2725                 } else {
2726                     debug!("yes ({:?})", sc.bin_name);
2727                 }
2728                 debug!(
2729                     "App::_build_bin_names:iter: Calling build_bin_names from...{}",
2730                     sc.name
2731                 );
2732                 sc._build_bin_names();
2733             }
2734             self.set(AppSettings::BinNameBuilt);
2735         } else {
2736             debug!("App::_build_bin_names: already built");
2737         }
2738     }
2739 
_render_version(&self, use_long: bool) -> String2740     pub(crate) fn _render_version(&self, use_long: bool) -> String {
2741         debug!("App::_render_version");
2742 
2743         let ver = if use_long {
2744             self.long_version
2745                 .unwrap_or_else(|| self.version.unwrap_or(""))
2746         } else {
2747             self.version
2748                 .unwrap_or_else(|| self.long_version.unwrap_or(""))
2749         };
2750         if let Some(bn) = self.bin_name.as_ref() {
2751             if bn.contains(' ') {
2752                 // In case we're dealing with subcommands i.e. git mv is translated to git-mv
2753                 format!("{} {}\n", bn.replace(" ", "-"), ver)
2754             } else {
2755                 format!("{} {}\n", &self.name[..], ver)
2756             }
2757         } else {
2758             format!("{} {}\n", &self.name[..], ver)
2759         }
2760     }
2761 
format_group(&self, g: &Id) -> String2762     pub(crate) fn format_group(&self, g: &Id) -> String {
2763         let g_string = self
2764             .unroll_args_in_group(g)
2765             .iter()
2766             .filter_map(|x| self.find(x))
2767             .map(|x| {
2768                 if x.is_positional() {
2769                     // Print val_name for positional arguments. e.g. <file_name>
2770                     x.name_no_brackets().to_string()
2771                 } else {
2772                     // Print useage string for flags arguments, e.g. <--help>
2773                     x.to_string()
2774                 }
2775             })
2776             .collect::<Vec<_>>()
2777             .join("|");
2778         format!("<{}>", &*g_string)
2779     }
2780 }
2781 
2782 /// A workaround:
2783 /// https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
2784 pub(crate) trait Captures<'a> {}
2785 impl<'a, T> Captures<'a> for T {}
2786 
2787 // Internal Query Methods
2788 impl<'help> App<'help> {
2789     /// Iterate through the *flags* & *options* arguments.
get_non_positionals(&self) -> impl Iterator<Item = &Arg<'help>>2790     pub(crate) fn get_non_positionals(&self) -> impl Iterator<Item = &Arg<'help>> {
2791         self.get_arguments().filter(|a| !a.is_positional())
2792     }
2793 
2794     /// Iterate through the *positionals* that don't have custom heading.
get_positionals_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>>2795     pub(crate) fn get_positionals_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>> {
2796         self.get_positionals()
2797             .filter(|a| a.get_help_heading().is_none())
2798     }
2799 
2800     /// Iterate through the *flags* & *options* that don't have custom heading.
get_non_positionals_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>>2801     pub(crate) fn get_non_positionals_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>> {
2802         self.get_non_positionals()
2803             .filter(|a| a.get_help_heading().is_none())
2804     }
2805 
find(&self, arg_id: &Id) -> Option<&Arg<'help>>2806     pub(crate) fn find(&self, arg_id: &Id) -> Option<&Arg<'help>> {
2807         self.args.args().find(|a| a.id == *arg_id)
2808     }
2809 
2810     #[inline]
get_color(&self) -> ColorChoice2811     pub(crate) fn get_color(&self) -> ColorChoice {
2812         self.color
2813     }
2814 
2815     #[inline]
contains_short(&self, s: char) -> bool2816     pub(crate) fn contains_short(&self, s: char) -> bool {
2817         assert!(
2818             self.is_set(AppSettings::Built),
2819             "If App::_build hasn't been called, manually search through Arg shorts"
2820         );
2821 
2822         self.args.contains(s)
2823     }
2824 
2825     #[inline]
set(&mut self, s: AppSettings)2826     pub(crate) fn set(&mut self, s: AppSettings) {
2827         self.settings.set(s)
2828     }
2829 
2830     #[inline]
has_args(&self) -> bool2831     pub(crate) fn has_args(&self) -> bool {
2832         !self.args.is_empty()
2833     }
2834 
has_positionals(&self) -> bool2835     pub(crate) fn has_positionals(&self) -> bool {
2836         self.args.keys().any(|x| x.is_position())
2837     }
2838 
has_visible_subcommands(&self) -> bool2839     pub(crate) fn has_visible_subcommands(&self) -> bool {
2840         self.subcommands
2841             .iter()
2842             .any(|sc| sc.name != "help" && !sc.is_set(AppSettings::Hidden))
2843     }
2844 
2845     /// Check if this subcommand can be referred to as `name`. In other words,
2846     /// check if `name` is the name of this subcommand or is one of its aliases.
2847     #[inline]
aliases_to<T>(&self, name: &T) -> bool where T: PartialEq<str> + ?Sized,2848     pub(crate) fn aliases_to<T>(&self, name: &T) -> bool
2849     where
2850         T: PartialEq<str> + ?Sized,
2851     {
2852         *name == *self.get_name() || self.get_all_aliases().any(|alias| *name == *alias)
2853     }
2854 
2855     /// Check if this subcommand can be referred to as `name`. In other words,
2856     /// check if `name` is the name of this short flag subcommand or is one of its short flag aliases.
2857     #[inline]
short_flag_aliases_to(&self, flag: char) -> bool2858     pub(crate) fn short_flag_aliases_to(&self, flag: char) -> bool {
2859         Some(flag) == self.short_flag
2860             || self.get_all_short_flag_aliases().any(|alias| flag == alias)
2861     }
2862 
2863     /// Check if this subcommand can be referred to as `name`. In other words,
2864     /// check if `name` is the name of this long flag subcommand or is one of its long flag aliases.
2865     #[inline]
long_flag_aliases_to<T>(&self, flag: &T) -> bool where T: PartialEq<str> + ?Sized,2866     pub(crate) fn long_flag_aliases_to<T>(&self, flag: &T) -> bool
2867     where
2868         T: PartialEq<str> + ?Sized,
2869     {
2870         match self.long_flag {
2871             Some(long_flag) => {
2872                 flag == long_flag || self.get_all_long_flag_aliases().any(|alias| flag == alias)
2873             }
2874             None => self.get_all_long_flag_aliases().any(|alias| flag == alias),
2875         }
2876     }
2877 
2878     #[cfg(debug_assertions)]
id_exists(&self, id: &Id) -> bool2879     pub(crate) fn id_exists(&self, id: &Id) -> bool {
2880         self.args.args().any(|x| x.id == *id) || self.groups.iter().any(|x| x.id == *id)
2881     }
2882 
2883     /// Iterate through the groups this arg is member of.
groups_for_arg<'a>(&'a self, arg: &Id) -> impl Iterator<Item = Id> + 'a2884     pub(crate) fn groups_for_arg<'a>(&'a self, arg: &Id) -> impl Iterator<Item = Id> + 'a {
2885         debug!("App::groups_for_arg: id={:?}", arg);
2886         let arg = arg.clone();
2887         self.groups
2888             .iter()
2889             .filter(move |grp| grp.args.iter().any(|a| a == &arg))
2890             .map(|grp| grp.id.clone())
2891     }
2892 
2893     /// Iterate through all the names of all subcommands (not recursively), including aliases.
2894     /// Used for suggestions.
all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures<'help>2895     pub(crate) fn all_subcommand_names(&self) -> impl Iterator<Item = &str> + Captures<'help> {
2896         self.get_subcommands().flat_map(|sc| {
2897             let name = sc.get_name();
2898             let aliases = sc.get_all_aliases();
2899             std::iter::once(name).chain(aliases)
2900         })
2901     }
2902 
unroll_args_in_group(&self, group: &Id) -> Vec<Id>2903     pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec<Id> {
2904         debug!("App::unroll_args_in_group: group={:?}", group);
2905         let mut g_vec = vec![group];
2906         let mut args = vec![];
2907 
2908         while let Some(g) = g_vec.pop() {
2909             for n in self
2910                 .groups
2911                 .iter()
2912                 .find(|grp| grp.id == *g)
2913                 .expect(INTERNAL_ERROR_MSG)
2914                 .args
2915                 .iter()
2916             {
2917                 debug!("App::unroll_args_in_group:iter: entity={:?}", n);
2918                 if !args.contains(n) {
2919                     if self.find(n).is_some() {
2920                         debug!("App::unroll_args_in_group:iter: this is an arg");
2921                         args.push(n.clone())
2922                     } else {
2923                         debug!("App::unroll_args_in_group:iter: this is a group");
2924                         g_vec.push(n);
2925                     }
2926                 }
2927             }
2928         }
2929 
2930         args
2931     }
2932 
unroll_requirements_for_arg(&self, arg: &Id, matcher: &ArgMatcher) -> Vec<Id>2933     pub(crate) fn unroll_requirements_for_arg(&self, arg: &Id, matcher: &ArgMatcher) -> Vec<Id> {
2934         let requires_if_or_not = |(val, req_arg): &(Option<&str>, Id)| -> Option<Id> {
2935             if let Some(v) = val {
2936                 if matcher
2937                     .get(arg)
2938                     .map(|ma| ma.contains_val(v))
2939                     .unwrap_or(false)
2940                 {
2941                     Some(req_arg.clone())
2942                 } else {
2943                     None
2944                 }
2945             } else {
2946                 Some(req_arg.clone())
2947             }
2948         };
2949 
2950         let mut processed = vec![];
2951         let mut r_vec = vec![arg];
2952         let mut args = vec![];
2953 
2954         while let Some(a) = r_vec.pop() {
2955             if processed.contains(&a) {
2956                 continue;
2957             }
2958 
2959             processed.push(a);
2960 
2961             if let Some(arg) = self.find(a) {
2962                 for r in arg.requires.iter().filter_map(requires_if_or_not) {
2963                     if let Some(req) = self.find(&r) {
2964                         if !req.requires.is_empty() {
2965                             r_vec.push(&req.id)
2966                         }
2967                     }
2968                     args.push(r);
2969                 }
2970             }
2971         }
2972 
2973         args
2974     }
2975 
2976     /// Find a flag subcommand name by short flag or an alias
find_short_subcmd(&self, c: char) -> Option<&str>2977     pub(crate) fn find_short_subcmd(&self, c: char) -> Option<&str> {
2978         self.get_subcommands()
2979             .find(|sc| sc.short_flag_aliases_to(c))
2980             .map(|sc| sc.get_name())
2981     }
2982 
2983     /// Find a flag subcommand name by long flag or an alias
find_long_subcmd(&self, long: &RawOsStr) -> Option<&str>2984     pub(crate) fn find_long_subcmd(&self, long: &RawOsStr) -> Option<&str> {
2985         self.get_subcommands()
2986             .find(|sc| sc.long_flag_aliases_to(long))
2987             .map(|sc| sc.get_name())
2988     }
2989 }
2990 
2991 impl<'help> Index<&'_ Id> for App<'help> {
2992     type Output = Arg<'help>;
2993 
index(&self, key: &Id) -> &Self::Output2994     fn index(&self, key: &Id) -> &Self::Output {
2995         self.find(key).expect(INTERNAL_ERROR_MSG)
2996     }
2997 }
2998 
2999 #[cfg(feature = "yaml")]
3000 impl<'help> From<&'help Yaml> for App<'help> {
3001     #[allow(clippy::cognitive_complexity)]
from(y: &'help Yaml) -> Self3002     fn from(y: &'help Yaml) -> Self {
3003         let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
3004         // We WANT this to panic on error...so expect() is good.
3005         let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() {
3006             (App::new(name), yaml_file_hash, "app".into())
3007         } else {
3008             let (name_yaml, value_yaml) = yaml_file_hash
3009                 .iter()
3010                 .next()
3011                 .expect("There must be one subcommand in the YAML file");
3012             let name_str = name_yaml
3013                 .as_str()
3014                 .expect("Subcommand name must be a string");
3015 
3016             (
3017                 App::new(name_str),
3018                 value_yaml.as_hash().expect("Subcommand must be a hash"),
3019                 format!("subcommand '{}'", name_str),
3020             )
3021         };
3022 
3023         let mut has_metadata = false;
3024 
3025         for (k, v) in yaml {
3026             a = match k.as_str().expect("App fields must be strings") {
3027                 "_has_metadata" => {
3028                     has_metadata = true;
3029                     a
3030                 }
3031                 "bin_name" => yaml_to_str!(a, v, bin_name),
3032                 "version" => yaml_to_str!(a, v, version),
3033                 "long_version" => yaml_to_str!(a, v, long_version),
3034                 "author" => yaml_to_str!(a, v, author),
3035                 "about" => yaml_to_str!(a, v, about),
3036                 "before_help" => yaml_to_str!(a, v, before_help),
3037                 "before_long_help" => yaml_to_str!(a, v, before_long_help),
3038                 "after_help" => yaml_to_str!(a, v, after_help),
3039                 "after_long_help" => yaml_to_str!(a, v, after_long_help),
3040                 "help_heading" => yaml_to_str!(a, v, help_heading),
3041                 "help_template" => yaml_to_str!(a, v, help_template),
3042                 "override_help" => yaml_to_str!(a, v, override_help),
3043                 "override_usage" => yaml_to_str!(a, v, override_usage),
3044                 "alias" => yaml_to_str!(a, v, alias),
3045                 "aliases" => yaml_vec_or_str!(a, v, alias),
3046                 "visible_alias" => yaml_to_str!(a, v, visible_alias),
3047                 "visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
3048                 "display_order" => yaml_to_usize!(a, v, display_order),
3049                 "term_width" => yaml_to_usize!(a, v, term_width),
3050                 "max_term_width" => yaml_to_usize!(a, v, max_term_width),
3051                 "args" => {
3052                     if let Some(vec) = v.as_vec() {
3053                         for arg_yaml in vec {
3054                             a = a.arg(Arg::from(arg_yaml));
3055                         }
3056                     } else {
3057                         panic!("Failed to convert YAML value {:?} to a vec", v);
3058                     }
3059                     a
3060                 }
3061                 "subcommands" => {
3062                     if let Some(vec) = v.as_vec() {
3063                         for sc_yaml in vec {
3064                             a = a.subcommand(App::from(sc_yaml));
3065                         }
3066                     } else {
3067                         panic!("Failed to convert YAML value {:?} to a vec", v);
3068                     }
3069                     a
3070                 }
3071                 "groups" => {
3072                     if let Some(vec) = v.as_vec() {
3073                         for ag_yaml in vec {
3074                             a = a.group(ArgGroup::from(ag_yaml));
3075                         }
3076                     } else {
3077                         panic!("Failed to convert YAML value {:?} to a vec", v);
3078                     }
3079                     a
3080                 }
3081                 "setting" | "settings" => {
3082                     yaml_to_setting!(a, v, setting, AppSettings, "AppSetting", err)
3083                 }
3084                 "global_setting" | "global_settings" => {
3085                     yaml_to_setting!(a, v, global_setting, AppSettings, "AppSetting", err)
3086                 }
3087                 "name" => continue,
3088                 s => {
3089                     if !has_metadata {
3090                         panic!("Unknown setting '{}' in YAML file for {}", s, err)
3091                     }
3092                     continue;
3093                 }
3094             }
3095         }
3096 
3097         a
3098     }
3099 }
3100 
3101 impl fmt::Display for App<'_> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result3102     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3103         write!(f, "{}", self.name)
3104     }
3105 }
3106 
two_elements_of<I, T>(mut iter: I) -> Option<(T, T)> where I: Iterator<Item = T>,3107 fn two_elements_of<I, T>(mut iter: I) -> Option<(T, T)>
3108 where
3109     I: Iterator<Item = T>,
3110 {
3111     let first = iter.next();
3112     let second = iter.next();
3113 
3114     match (first, second) {
3115         (Some(first), Some(second)) => Some((first, second)),
3116         _ => None,
3117     }
3118 }
3119