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