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