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