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