• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

clap-rs / clap / 935109890

pending completion
935109890

Pull #2480

github

GitHub
Merge 171dcbe42 into 36c972a30
Pull Request #2480: setting: IgnoreErrors - Allow parsing despite missing option values

48 of 48 new or added lines in 3 files covered. (100.0%)

11256 of 13081 relevant lines covered (86.05%)

11.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.9
/src/build/app/mod.rs
1
#[cfg(debug_assertions)]
2
mod debug_asserts;
3
mod settings;
4
#[cfg(test)]
5
mod tests;
6

7
pub use self::settings::AppSettings;
8

9
// Std
10
use std::{
11
    collections::HashMap,
12
    env,
13
    ffi::OsString,
14
    fmt,
15
    io::{self, BufRead, Write},
16
    ops::Index,
17
    path::Path,
18
};
19

20
// Third Party
21
#[cfg(feature = "yaml")]
22
use yaml_rust::Yaml;
23

24
// Internal
25
use crate::{
26
    build::{app::settings::AppFlags, arg::ArgProvider, Arg, ArgGroup, ArgSettings},
27
    mkeymap::MKeyMap,
28
    output::{fmt::Colorizer, Help, HelpWriter, Usage},
29
    parse::{ArgMatcher, ArgMatches, Input, Parser},
30
    util::{safe_exit, termcolor::ColorChoice, ArgStr, Id, Key},
31
    Result as ClapResult, INTERNAL_ERROR_MSG,
32
};
33

34
/// Represents a command line interface which is made up of all possible
35
/// command line arguments and subcommands. Interface arguments and settings are
36
/// configured using the "builder pattern." Once all configuration is complete,
37
/// the [`App::get_matches`] family of methods starts the runtime-parsing
38
/// process. These methods then return information about the user supplied
39
/// arguments (or lack thereof).
40
///
41
/// **NOTE:** There aren't any mandatory "options" that one must set. The "options" may
42
/// also appear in any order (so long as one of the [`App::get_matches`] methods is the last method
43
/// called).
44
///
45
/// # Examples
46
///
47
/// ```no_run
48
/// # use clap::{App, Arg};
49
/// let m = App::new("My Program")
50
///     .author("Me, me@mail.com")
51
///     .version("1.0.2")
52
///     .about("Explains in brief what the program does")
53
///     .arg(
54
///         Arg::new("in_file").index(1)
55
///     )
56
///     .after_help("Longer explanation to appear after the options when \
57
///                  displaying the help information from --help or -h")
58
///     .get_matches();
59
///
60
/// // Your program logic starts here...
61
/// ```
62
/// [`App::get_matches`]: App::get_matches()
63
#[derive(Default, Debug, Clone, PartialEq, Eq)]
64
pub struct App<'help> {
65
    pub(crate) id: Id,
66
    pub(crate) name: String,
67
    pub(crate) long_flag: Option<&'help str>,
68
    pub(crate) short_flag: Option<char>,
69
    pub(crate) bin_name: Option<String>,
70
    pub(crate) author: Option<&'help str>,
71
    pub(crate) version: Option<&'help str>,
72
    pub(crate) long_version: Option<&'help str>,
73
    pub(crate) license: Option<&'help str>,
74
    pub(crate) about: Option<&'help str>,
75
    pub(crate) long_about: Option<&'help str>,
76
    pub(crate) before_help: Option<&'help str>,
77
    pub(crate) before_long_help: Option<&'help str>,
78
    pub(crate) after_help: Option<&'help str>,
79
    pub(crate) after_long_help: Option<&'help str>,
80
    pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible)
81
    pub(crate) short_flag_aliases: Vec<(char, bool)>, // (name, visible)
82
    pub(crate) long_flag_aliases: Vec<(&'help str, bool)>, // (name, visible)
83
    pub(crate) usage_str: Option<&'help str>,
84
    pub(crate) usage: Option<String>,
85
    pub(crate) help_str: Option<&'help str>,
86
    pub(crate) disp_ord: usize,
87
    pub(crate) term_w: Option<usize>,
88
    pub(crate) max_w: Option<usize>,
89
    pub(crate) template: Option<&'help str>,
90
    pub(crate) settings: AppFlags,
91
    pub(crate) g_settings: AppFlags,
92
    pub(crate) args: MKeyMap<'help>,
93
    pub(crate) subcommands: Vec<App<'help>>,
94
    pub(crate) replacers: HashMap<&'help str, &'help [&'help str]>,
95
    pub(crate) groups: Vec<ArgGroup<'help>>,
96
    pub(crate) current_help_heading: Option<&'help str>,
97
    pub(crate) subcommand_placeholder: Option<&'help str>,
98
    pub(crate) subcommand_header: Option<&'help str>,
99
}
100

101
impl<'help> App<'help> {
102
    /// Get the name of the app.
103
    #[inline]
104
    pub fn get_name(&self) -> &str {
40✔
105
        &self.name
41✔
106
    }
107

108
    /// Get the short flag of the subcommand.
109
    #[inline]
110
    pub fn get_short_flag(&self) -> Option<char> {
×
111
        self.short_flag
×
112
    }
113

114
    /// Get the long flag of the subcommand.
115
    #[inline]
116
    pub fn get_long_flag(&self) -> Option<&str> {
×
117
        self.long_flag
×
118
    }
119

120
    /// Get the name of the binary.
121
    #[inline]
122
    pub fn get_bin_name(&self) -> Option<&str> {
3✔
123
        self.bin_name.as_deref()
3✔
124
    }
125

126
    /// Set binary name. Uses `&mut self` instead of `self`.
127
    pub fn set_bin_name<S: Into<String>>(&mut self, name: S) {
3✔
128
        self.bin_name = Some(name.into());
3✔
129
    }
130

131
    /// Get the help message specified via [`App::about`].
132
    ///
133
    /// [`App::about`]: App::about()
134
    #[inline]
135
    pub fn get_about(&self) -> Option<&str> {
2✔
136
        self.about.as_deref()
2✔
137
    }
138

139
    /// Iterate through the *visible* aliases for this subcommand.
140
    #[inline]
141
    pub fn get_visible_aliases(&self) -> impl Iterator<Item = &str> {
3✔
142
        self.aliases.iter().filter(|(_, vis)| *vis).map(|a| a.0)
9✔
143
    }
144

145
    /// Iterate through the *visible* short aliases for this subcommand.
146
    #[inline]
147
    pub fn get_visible_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_ {
1✔
148
        self.short_flag_aliases
1✔
149
            .iter()
150
            .filter(|(_, vis)| *vis)
×
151
            .map(|a| a.0)
×
152
    }
153

154
    /// Iterate through the *visible* long aliases for this subcommand.
155
    #[inline]
156
    pub fn get_visible_long_flag_aliases(&self) -> impl Iterator<Item = &'help str> + '_ {
×
157
        self.long_flag_aliases
×
158
            .iter()
159
            .filter(|(_, vis)| *vis)
×
160
            .map(|a| a.0)
×
161
    }
162

163
    /// Iterate through the set of *all* the aliases for this subcommand, both visible and hidden.
164
    #[inline]
165
    pub fn get_all_aliases(&self) -> impl Iterator<Item = &str> {
28✔
166
        self.aliases.iter().map(|a| a.0)
36✔
167
    }
168

169
    /// Iterate through the set of *all* the short aliases for this subcommand, both visible and hidden.
170
    #[inline]
171
    pub fn get_all_short_flag_aliases(&self) -> impl Iterator<Item = char> + '_ {
1✔
172
        self.short_flag_aliases.iter().map(|a| a.0)
3✔
173
    }
174

175
    /// Iterate through the set of *all* the long aliases for this subcommand, both visible and hidden.
176
    #[inline]
177
    pub fn get_all_long_flag_aliases(&self) -> impl Iterator<Item = &'help str> + '_ {
5✔
178
        self.long_flag_aliases.iter().map(|a| a.0)
7✔
179
    }
180

181
    /// Iterate through the set of subcommands, getting a reference to each.
182
    #[inline]
183
    pub fn get_subcommands(&self) -> impl Iterator<Item = &App<'help>> {
89✔
184
        self.subcommands.iter()
89✔
185
    }
186

187
    /// Iterate through the set of subcommands, getting a mutable reference to each.
188
    #[inline]
189
    pub fn get_subcommands_mut(&mut self) -> impl Iterator<Item = &mut App<'help>> {
1✔
190
        self.subcommands.iter_mut()
1✔
191
    }
192

193
    /// Iterate through the set of arguments.
194
    #[inline]
195
    pub fn get_arguments(&self) -> impl Iterator<Item = &Arg<'help>> {
107✔
196
        self.args.args()
107✔
197
    }
198

199
    /// Iterate through the *positionals*.
200
    #[inline]
201
    pub fn get_positionals(&self) -> impl Iterator<Item = &Arg<'help>> {
101✔
202
        self.get_arguments().filter(|a| a.is_positional())
305✔
203
    }
204

205
    /// Iterate through the *flags*.
206
    pub fn get_flags(&self) -> impl Iterator<Item = &Arg<'help>> {
57✔
207
        self.get_arguments()
57✔
208
            .filter(|a| !a.is_set(ArgSettings::TakesValue) && a.get_index().is_none())
116✔
209
    }
210

211
    /// Iterate through the *options*.
212
    pub fn get_opts(&self) -> impl Iterator<Item = &Arg<'help>> {
96✔
213
        self.get_arguments()
96✔
214
            .filter(|a| a.is_set(ArgSettings::TakesValue) && a.get_index().is_none())
192✔
215
    }
216

217
    /// Iterate through the *positionals* that don't have custom heading.
218
    pub fn get_positionals_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>> {
35✔
219
        self.get_positionals()
35✔
220
            .filter(|a| a.get_help_heading().is_none())
26✔
221
    }
222

223
    /// Iterate through the *flags* that don't have custom heading.
224
    pub fn get_flags_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>> {
58✔
225
        self.get_flags().filter(|a| a.get_help_heading().is_none())
174✔
226
    }
227

228
    /// Iterate through the *options* that don't have custom heading.
229
    pub fn get_opts_with_no_heading(&self) -> impl Iterator<Item = &Arg<'help>> {
58✔
230
        self.get_opts().filter(|a| a.get_help_heading().is_none())
119✔
231
    }
232

233
    // Get a list of subcommands which contain the provided Argument
234
    //
235
    // This command will only include subcommands in its list for which the subcommands
236
    // parent also contains the Argument.
237
    //
238
    // This search follows the propagation rules of global arguments.
239
    // It is useful to finding subcommands, that have inherited a global argument.
240
    //
241
    // **NOTE:** In this case only Sucommand_1 will be included
242
    //   Subcommand_1 (contains Arg)
243
    //     Subcommand_1.1 (doesn't contain Arg)
244
    //       Subcommand_1.1.1 (contains Arg)
245
    //
246
    fn get_subcommands_containing(&self, arg: &Arg) -> Vec<&App<'help>> {
1✔
247
        let mut vec = std::vec::Vec::new();
1✔
248
        for idx in 0..self.subcommands.len() {
2✔
249
            if self.subcommands[idx].args.args().any(|ar| ar.id == arg.id) {
4✔
250
                vec.push(&self.subcommands[idx]);
2✔
251
                vec.append(&mut self.subcommands[idx].get_subcommands_containing(arg));
1✔
252
            }
253
        }
254
        vec
×
255
    }
256

257
    // Get a unique list of all arguments of all commands and continuous subcommands the given argument conflicts with.
258
    //
259
    // This behavior follows the propagation rules of global arguments.
260
    // It is useful for finding conflicts for arguments declared as global.
261
    //
262
    // ### Panics
263
    //
264
    // If the given arg contains a conflict with an argument that is unknown to
265
    // this `App`.
266
    fn get_global_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator
2✔
267
    {
268
        arg.blacklist
4✔
269
            .iter()
270
            .map(|id| {
3✔
271
                self.args
3✔
272
                    .args()
×
273
                    .chain(
×
274
                        self.get_subcommands_containing(arg)
1✔
275
                            .iter()
×
276
                            .flat_map(|x| x.args.args()),
×
277
                    )
278
                    .find(|arg| arg.id == *id)
3✔
279
                    .expect(
×
280
                        "App::get_arg_conflicts_with: \
×
281
                    The passed arg conflicts with an arg unknown to the app",
×
282
                    )
283
            })
284
            .collect()
285
    }
286

287
    /// Get a list of all arguments the given argument conflicts with.
288
    ///
289
    /// If the provided argument is declared as global, the conflicts will be determined
290
    /// based on the propagation rules of global arguments.
291
    ///
292
    /// ### Panics
293
    ///
294
    /// If the given arg contains a conflict with an argument that is unknown to
295
    /// this `App`.
296
    pub fn get_arg_conflicts_with(&self, arg: &Arg) -> Vec<&Arg<'help>> // FIXME: This could probably have been an iterator
3✔
297
    {
298
        if arg.global {
3✔
299
            self.get_global_arg_conflicts_with(arg)
2✔
300
        } else {
301
            arg.blacklist
4✔
302
                .iter()
303
                .map(|id| {
2✔
304
                    self.args.args().find(|arg| arg.id == *id).expect(
×
305
                        "App::get_arg_conflicts_with: \
×
306
                    The passed arg conflicts with an arg unknown to the app",
×
307
                    )
308
                })
309
                .collect()
310
        }
311
    }
312

313
    /// Returns `true` if the given [`AppSettings`] variant is currently set in
314
    /// this `App` (checks both [local] and [global settings]).
315
    ///
316
    /// [local]: App::setting()
317
    /// [global settings]: App::global_setting()
318
    #[inline]
319
    pub fn is_set(&self, s: AppSettings) -> bool {
104✔
320
        self.settings.is_set(s) || self.g_settings.is_set(s)
206✔
321
    }
322

323
    /// Returns `true` if this `App` has subcommands.
324
    #[inline]
325
    pub fn has_subcommands(&self) -> bool {
109✔
326
        !self.subcommands.is_empty()
109✔
327
    }
328

329
    /// Find subcommand such that its name or one of aliases equals `name`.
330
    ///
331
    /// This does not recurse through subcommands of subcommands.
332
    #[inline]
333
    pub fn find_subcommand<T>(&self, name: &T) -> Option<&App<'help>>
117✔
334
    where
335
        T: PartialEq<str> + ?Sized,
336
    {
337
        self.get_subcommands().find(|s| s.aliases_to(name))
249✔
338
    }
339
}
340

341
impl<'help> App<'help> {
342
    /// Creates a new instance of an `App` requiring a `name`.
343
    ///
344
    /// It is common, but not required, to use binary name as the `name`. This
345
    /// name will only be displayed to the user when they request to print
346
    /// version or help and usage information.
347
    ///
348
    /// An `App` represents a command line interface (CLI) which is made up of
349
    /// all possible command line arguments and subcommands. "Subcommands" are
350
    /// sub-CLIs with their own arguments, settings, and even subcommands
351
    /// forming a sort of hierarchy.
352
    ///
353
    /// # Examples
354
    ///
355
    /// ```no_run
356
    /// # use clap::App;
357
    /// App::new("My Program")
358
    /// # ;
359
    /// ```
360
    pub fn new<S: Into<String>>(name: S) -> Self {
101✔
361
        let name = name.into();
105✔
362

363
        App {
364
            id: Id::from(&*name),
106✔
365
            name,
366
            disp_ord: 999,
367
            ..Default::default()
368
        }
369
        .arg(
370
            Arg::new("help")
107✔
371
                .long("help")
×
372
                .about("Prints help information")
×
373
                .global(true)
×
374
                .generated(),
×
375
        )
376
        .arg(
377
            Arg::new("version")
107✔
378
                .long("version")
×
379
                .about("Prints version information")
×
380
                .global(true)
×
381
                .generated(),
×
382
        )
383
    }
384

385
    /// Sets a string of author(s) that will be displayed to the user when they
386
    /// request the help message.
387
    ///
388
    /// **Pro-tip:** Use `clap`s convenience macro [`crate_authors!`] to
389
    /// automatically set your application's author(s) to the same thing as your
390
    /// crate at compile time.
391
    ///
392
    /// See the [`examples/`] directory for more information.
393
    ///
394
    /// # Examples
395
    ///
396
    /// ```no_run
397
    /// # use clap::App;
398
    /// App::new("myprog")
399
    ///      .author("Me, me@mymain.com")
400
    /// # ;
401
    /// ```
402
    /// [`crate_authors!`]: ./macro.crate_authors!.html
403
    /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples
404
    pub fn author<S: Into<&'help str>>(mut self, author: S) -> Self {
21✔
405
        self.author = Some(author.into());
21✔
406
        self
21✔
407
    }
408

409
    /// Overrides the runtime-determined name of the binary. This should only be
410
    /// used when absolutely necessary, such as when the binary name for your
411
    /// application is misleading, or perhaps *not* how the user should invoke
412
    /// your program.
413
    ///
414
    /// Normally, the binary name is used in help and error messages. `clap`
415
    /// automatically determines the binary name at runtime, however by manually
416
    /// setting the binary name, one can effectively override what will be
417
    /// displayed in the help or error messages.
418
    ///
419
    /// **Pro-tip:** When building things such as third party `cargo`
420
    /// subcommands, this setting **should** be used!
421
    ///
422
    /// **NOTE:** This *does not* change or set the name of the binary file on
423
    /// disk. It only changes what clap thinks the name is for the purposes of
424
    /// error or help messages.
425
    ///
426
    /// # Examples
427
    ///
428
    /// ```no_run
429
    /// # use clap::App;
430
    /// App::new("My Program")
431
    ///      .bin_name("my_binary")
432
    /// # ;
433
    /// ```
434
    pub fn bin_name<S: Into<String>>(mut self, name: S) -> Self {
3✔
435
        self.bin_name = Some(name.into());
3✔
436
        self
3✔
437
    }
438

439
    /// Sets a string describing what the program does. This will be displayed
440
    /// when the user requests the short format help message (`-h`).
441
    ///
442
    /// `clap` can display two different help messages, a [long format] and a
443
    /// [short format] depending on whether the user used `-h` (short) or
444
    /// `--help` (long). This method sets the message during the short format
445
    /// (`-h`) message. However, if no long format message is configured, this
446
    /// message will be displayed for *both* the long format, or short format
447
    /// help message.
448
    ///
449
    /// **NOTE:** Only [`App::about`] (short format) is used in completion
450
    /// script generation in order to be concise.
451
    ///
452
    /// # Examples
453
    ///
454
    /// ```no_run
455
    /// # use clap::App;
456
    /// App::new("myprog")
457
    ///     .about("Does really amazing things for great people")
458
    /// # ;
459
    /// ```
460
    /// [long format]: App::long_about()
461
    /// [short format]: App::about()
462
    /// [`App::about`]: App::about()
463
    pub fn about<S: Into<&'help str>>(mut self, about: S) -> Self {
47✔
464
        self.about = Some(about.into());
47✔
465
        self
47✔
466
    }
467

468
    /// Sets a long format string describing what the program does. This will be
469
    /// displayed when the user requests the long format help message (`--help`).
470
    ///
471
    /// ## Advanced
472
    ///
473
    /// `clap` can display two different help messages, a [long format] and a
474
    /// [short format] depending on whether the user used `-h` (short) or
475
    /// `--help` (long). This method sets the message during the long format
476
    /// (`--help`) message. However, if no short format message is configured,
477
    /// this message will be displayed for *both* the long format, or short
478
    /// format help message.
479
    ///
480
    /// **NOTE:** Only [`App::about`] (short format) is used in completion
481
    /// script generation in order to be concise.
482
    ///
483
    /// # Examples
484
    ///
485
    /// ```no_run
486
    /// # use clap::App;
487
    /// App::new("myprog")
488
    ///     .long_about(
489
    /// "Does really amazing things to great people. Now let's talk a little
490
    ///  more in depth about how this subcommand really works. It may take about
491
    ///  a few lines of text, but that's ok!")
492
    /// # ;
493
    /// ```
494
    /// [long format]: App::long_about()
495
    /// [short format]: App::about()
496
    /// [`App::about`]: App::about()
497
    pub fn long_about<S: Into<&'help str>>(mut self, about: S) -> Self {
3✔
498
        self.long_about = Some(about.into());
3✔
499
        self
3✔
500
    }
501

502
    /// (Re)Sets the program's name. This will be displayed when displaying help
503
    /// or version messages.
504
    ///
505
    /// **Pro-tip:** This function is particularly useful when configuring a
506
    /// program via `App::from(yaml)` in conjunction with the [`crate_name!`]
507
    /// macro to derive the program's name from its `Cargo.toml`.
508
    ///
509
    /// # Examples
510
    ///
511
    /// ```ignore
512
    /// # use clap::{App, load_yaml};
513
    /// let yaml = load_yaml!("app.yaml");
514
    /// let app = App::from(yaml)
515
    ///     .name(crate_name!());
516
    ///
517
    /// // continued logic goes here, such as `app.get_matches()` etc.
518
    /// ```
519
    ///
520
    pub fn name<S: Into<String>>(mut self, name: S) -> Self {
1✔
521
        self.name = name.into();
1✔
522
        self
1✔
523
    }
524

525
    /// Adds additional help information to be displayed at the end of the
526
    /// auto-generated help. This is often used to describe how to use the
527
    /// arguments, caveats to be noted, or license and contact information.
528
    ///
529
    /// **NOTE:** If only `after_long_help` is provided, and not [`App::after_help`] but the user requests
530
    /// `-h` clap will still display the contents of `after_help` appropriately.
531
    ///
532
    /// # Examples
533
    ///
534
    /// ```no_run
535
    /// # use clap::App;
536
    /// App::new("myprog")
537
    ///     .after_help("Does really amazing things for great people... but be careful with -R!")
538
    /// # ;
539
    /// ```
540
    ///
541
    /// [`App::after_help`]: App::after_help()
542
    pub fn after_help<S: Into<&'help str>>(mut self, help: S) -> Self {
2✔
543
        self.after_help = Some(help.into());
2✔
544
        self
2✔
545
    }
546

547
    /// Adds additional help information to be displayed in addition to auto-generated help. This
548
    /// information is displayed **after** the auto-generated help information and is meant to be
549
    /// more verbose than `after_help`. This is often used to describe how to use the arguments, or
550
    /// caveats to be noted in man pages.
551
    ///
552
    /// **NOTE:** If only `after_help` is provided, and not [`App::after_long_help`] but the user
553
    /// requests `--help`, clap will still display the contents of `after_help` appropriately.
554
    ///
555
    /// # Examples
556
    ///
557
    /// ```no_run
558
    /// # use clap::App;
559
    /// App::new("myprog")
560
    ///     .after_long_help("Does really amazing things to great people... but be careful with -R, \
561
    ///                      like, for real, be careful with this!")
562
    /// # ;
563
    /// ```
564
    /// [`App::after_long_help`]: App::after_long_help()
565
    pub fn after_long_help<S: Into<&'help str>>(mut self, help: S) -> Self {
1✔
566
        self.after_long_help = Some(help.into());
1✔
567
        self
1✔
568
    }
569

570
    /// Adds additional help information to be displayed prior to the
571
    /// auto-generated help. This is often used for header, copyright, or
572
    /// license information.
573
    ///
574
    /// **NOTE:** If only `before_long_help` is provided, and not [`App::before_help`] but the user
575
    /// requests `-h` clap will still display the contents of `before_long_help` appropriately.
576
    ///
577
    /// # Examples
578
    ///
579
    /// ```no_run
580
    /// # use clap::App;
581
    /// App::new("myprog")
582
    ///     .before_help("Some info I'd like to appear before the help info")
583
    /// # ;
584
    /// ```
585
    /// [`App::before_help`]: App::before_help()
586
    pub fn before_help<S: Into<&'help str>>(mut self, help: S) -> Self {
1✔
587
        self.before_help = Some(help.into());
1✔
588
        self
1✔
589
    }
590

591
    /// Adds additional help information to be displayed prior to the
592
    /// auto-generated help. This is often used for header, copyright, or
593
    /// license information.
594
    ///
595
    /// **NOTE:** If only `before_help` is provided, and not [`App::before_long_help`] but the user
596
    /// requests `--help`, clap will still display the contents of `before_help` appropriately.
597
    ///
598
    /// # Examples
599
    ///
600
    /// ```no_run
601
    /// # use clap::App;
602
    /// App::new("myprog")
603
    ///     .before_long_help("Some verbose and long info I'd like to appear before the help info")
604
    /// # ;
605
    /// ```
606
    /// [`App::before_long_help`]: App::before_long_help()
607
    pub fn before_long_help<S: Into<&'help str>>(mut self, help: S) -> Self {
1✔
608
        self.before_long_help = Some(help.into());
1✔
609
        self
1✔
610
    }
611

612
    /// Allows the subcommand to be used as if it were an [`Arg::short`].
613
    ///
614
    /// Sets the short version of the subcommand flag without the preceding `-`.
615
    ///
616
    /// # Examples
617
    ///
618
    /// ```
619
    /// # use clap::{App, Arg};
620
    /// let matches = App::new("pacman")
621
    ///     .subcommand(
622
    ///         App::new("sync").short_flag('S').arg(
623
    ///             Arg::new("search")
624
    ///                 .short('s')
625
    ///                 .long("search")
626
    ///                 .about("search remote repositories for matching strings"),
627
    ///         ),
628
    ///     )
629
    ///     .get_matches_from(vec!["pacman", "-Ss"]);
630
    ///
631
    /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
632
    /// let sync_matches = matches.subcommand_matches("sync").unwrap();
633
    /// assert!(sync_matches.is_present("search"));
634
    /// ```
635
    /// [`Arg::short`]: Arg::short()
636
    pub fn short_flag(mut self, short: char) -> Self {
2✔
637
        self.short_flag = Some(short);
2✔
638
        self
2✔
639
    }
640

641
    /// Allows the subcommand to be used as if it were an [`Arg::long`].
642
    ///
643
    /// Sets the long version of the subcommand flag without the preceding `--`.
644
    ///
645
    /// **NOTE:** Any leading `-` characters will be stripped.
646
    ///
647
    /// # Examples
648
    ///
649
    /// To set `long_flag` use a word containing valid UTF-8 codepoints. If you supply a double leading
650
    /// `--` such as `--sync` they will be stripped. Hyphens in the middle of the word; however,
651
    /// will *not* be stripped (i.e. `sync-file` is allowed).
652
    ///
653
    /// ```
654
    /// # use clap::{App, Arg};
655
    /// let matches = App::new("pacman")
656
    ///     .subcommand(
657
    ///         App::new("sync").long_flag("sync").arg(
658
    ///             Arg::new("search")
659
    ///                 .short('s')
660
    ///                 .long("search")
661
    ///                 .about("search remote repositories for matching strings"),
662
    ///         ),
663
    ///     )
664
    ///     .get_matches_from(vec!["pacman", "--sync", "--search"]);
665
    ///
666
    /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
667
    /// let sync_matches = matches.subcommand_matches("sync").unwrap();
668
    /// assert!(sync_matches.is_present("search"));
669
    /// ```
670
    ///
671
    /// [`Arg::long`]: Arg::long()
672
    pub fn long_flag(mut self, long: &'help str) -> Self {
2✔
673
        self.long_flag = Some(long.trim_start_matches(|c| c == '-'));
6✔
674
        self
2✔
675
    }
676

677
    /// Sets a string of the version number to be displayed when displaying the
678
    /// short format version message (`-V`) or the help message.
679
    ///
680
    /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
681
    /// automatically set your application's version to the same thing as your
682
    /// crate at compile time. See the [`examples/`] directory for more
683
    /// information.
684
    ///
685
    /// `clap` can display two different version messages, a [long format] and a
686
    /// [short format] depending on whether the user used `-V` (short) or
687
    /// `--version` (long). This method sets the message during the short format
688
    /// (`-V`). However, if no long format message is configured, this
689
    /// message will be displayed for *both* the long format, or short format
690
    /// version message.
691
    ///
692
    /// # Examples
693
    ///
694
    /// ```no_run
695
    /// # use clap::App;
696
    /// App::new("myprog")
697
    ///     .version("v0.1.24")
698
    /// # ;
699
    /// ```
700
    /// [`crate_version!`]: ./macro.crate_version!.html
701
    /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples
702
    /// [`App::long_version`]: App::long_version()
703
    pub fn version<S: Into<&'help str>>(mut self, ver: S) -> Self {
27✔
704
        self.version = Some(ver.into());
28✔
705
        self
28✔
706
    }
707

708
    /// Sets a string of the version number to be displayed when the user
709
    /// requests the long format version message (`--version`) or the help
710
    /// message.
711
    ///
712
    /// This is often used to display things such as commit ID, or compile time
713
    /// configured options.
714
    ///
715
    /// **Pro-tip:** Use `clap`s convenience macro [`crate_version!`] to
716
    /// automatically set your application's version to the same thing as your
717
    /// crate at compile time. See the [`examples/`] directory for more
718
    /// information.
719
    ///
720
    /// `clap` can display two different version messages, a [long format] and a
721
    /// [short format] depending on whether the user used `-V` (short) or
722
    /// `--version` (long). This method sets the message during the long format
723
    /// (`--version`). However, if no short format message is configured, this
724
    /// message will be displayed for *both* the long format, or short format
725
    /// version message.
726
    ///
727
    /// # Examples
728
    ///
729
    /// ```no_run
730
    /// # use clap::App;
731
    /// App::new("myprog")
732
    ///     .long_version(
733
    /// "v0.1.24
734
    ///  commit: abcdef89726d
735
    ///  revision: 123
736
    ///  release: 2
737
    ///  binary: myprog")
738
    /// # ;
739
    /// ```
740
    /// [`crate_version!`]: ./macro.crate_version!.html
741
    /// [`examples/`]: https://github.com/kbknapp/clap-rs/tree/master/examples
742
    /// [`App::version`]: App::version()
743
    pub fn long_version<S: Into<&'help str>>(mut self, ver: S) -> Self {
1✔
744
        self.long_version = Some(ver.into());
1✔
745
        self
1✔
746
    }
747

748
    /// Sets a string of the license to be displayed when displaying help information.
749
    ///
750
    /// **Pro-tip:** Use `clap`s convenience macro [`crate_license!`] to automatically set your
751
    /// application's license to the same thing as your crate at compile time. See the
752
    /// [`examples/`] directory for more information
753
    ///
754
    /// # Examples
755
    ///
756
    /// ```no_run
757
    /// # use clap::{App, Arg};
758
    /// App::new("myprog")
759
    ///     .license("MIT OR Apache-2.0")
760
    /// # ;
761
    /// ```
762
    /// [`crate_license!`]: ./macro.crate_license!.html
763
    /// [`examples/`]: https://github.com/clap-rs/clap/tree/master/examples
764
    pub fn license<S: Into<&'help str>>(mut self, license: S) -> Self {
1✔
765
        self.license = Some(license.into());
1✔
766
        self
1✔
767
    }
768

769
    /// Overrides the `clap` generated usage string.
770
    ///
771
    /// This will be displayed to the user when errors are found in argument parsing.
772
    ///
773
    /// **CAUTION:** Using this setting disables `clap`s "context-aware" usage
774
    /// strings. After this setting is set, this will be *the only* usage string
775
    /// displayed to the user!
776
    ///
777
    /// **NOTE:** This will not replace the entire help message, *only* the portion
778
    /// showing the usage.
779
    ///
780
    /// # Examples
781
    ///
782
    /// ```no_run
783
    /// # use clap::{App, Arg};
784
    /// App::new("myprog")
785
    ///     .override_usage("myapp [-clDas] <some_file>")
786
    /// # ;
787
    /// ```
788
    /// [`ArgMatches::usage`]: ArgMatches::usage()
789
    pub fn override_usage<S: Into<&'help str>>(mut self, usage: S) -> Self {
1✔
790
        self.usage_str = Some(usage.into());
1✔
791
        self
1✔
792
    }
793

794
    /// Overrides the `clap` generated help message. This should only be used
795
    /// when the auto-generated message does not suffice.
796
    ///
797
    /// This will be displayed to the user when they use `--help` or `-h`.
798
    ///
799
    /// **NOTE:** This replaces the **entire** help message, so nothing will be
800
    /// auto-generated.
801
    ///
802
    /// **NOTE:** This **only** replaces the help message for the current
803
    /// command, meaning if you are using subcommands, those help messages will
804
    /// still be auto-generated unless you specify a [`Arg::override_help`] for
805
    /// them as well.
806
    ///
807
    /// # Examples
808
    ///
809
    /// ```no_run
810
    /// # use clap::{App, Arg};
811
    /// App::new("myapp")
812
    ///     .override_help("myapp v1.0\n\
813
    ///            Does awesome things\n\
814
    ///            (C) me@mail.com\n\n\
815
    ///
816
    ///            USAGE: myapp <opts> <comamnd>\n\n\
817
    ///
818
    ///            Options:\n\
819
    ///            -h, --help       Display this message\n\
820
    ///            -V, --version    Display version info\n\
821
    ///            -s <stuff>       Do something with stuff\n\
822
    ///            -v               Be verbose\n\n\
823
    ///
824
    ///            Commmands:\n\
825
    ///            help             Prints this message\n\
826
    ///            work             Do some work")
827
    /// # ;
828
    /// ```
829
    /// [`Arg::override_help`]: Arg::override_help()
830
    pub fn override_help<S: Into<&'help str>>(mut self, help: S) -> Self {
1✔
831
        self.help_str = Some(help.into());
1✔
832
        self
1✔
833
    }
834

835
    /// Sets the help template to be used, overriding the default format.
836
    ///
837
    /// **NOTE:** The template system is by design very simple. Therefore, the
838
    /// tags have to be written in the lowercase and without spacing.
839
    ///
840
    /// Tags are given inside curly brackets.
841
    ///
842
    /// Valid tags are:
843
    ///
844
    ///   * `{bin}`                 - Binary name.
845
    ///   * `{version}`             - Version number.
846
    ///   * `{author}`              - Author information.
847
    ///   * `{author-with-newline}` - Author followed by `\n`.
848
    ///   * `{author-section}`      - Author preceded and followed by `\n`.
849
    ///   * `{about}`               - General description (from [`App::about`] or
850
    ///                               [`App::long_about`]).
851
    ///   * `{about-with-newline}`  - About followed by `\n`.
852
    ///   * `{about-section}`       - About preceded and followed by '\n'.
853
    ///   * `{usage-heading}`       - Automatically generated usage heading.
854
    ///   * `{usage}`               - Automatically generated or given usage string.
855
    ///   * `{all-args}`            - Help for all arguments (options, flags, positional
856
    ///                               arguments, and subcommands) including titles.
857
    ///   * `{unified}`             - Unified help for options and flags. Note, you must *also*
858
    ///                               set [`AppSettings::UnifiedHelpMessage`] to fully merge both
859
    ///                               options and flags, otherwise the ordering is "best effort".
860
    ///   * `{flags}`               - Help for flags.
861
    ///   * `{options}`             - Help for options.
862
    ///   * `{positionals}`         - Help for positional arguments.
863
    ///   * `{subcommands}`         - Help for subcommands.
864
    ///   * `{after-help}`          - Help from [`App::after_help`] or [`App::after_long_help`].
865
    ///   * `{before-help}`         - Help from [`App::before_help`] or [`App::before_long_help`].
866
    ///
867
    /// # Examples
868
    ///
869
    /// ```no_run
870
    /// # use clap::App;
871
    /// App::new("myprog")
872
    ///     .version("1.0")
873
    ///     .help_template("{bin} ({version}) - {usage}")
874
    /// # ;
875
    /// ```
876
    /// [`App::about`]: App::about()
877
    /// [`App::long_about`]: App::long_about()
878
    /// [`App::after_help`]: App::after_help()
879
    /// [`App::after_long_help`]: App::after_long_help()
880
    /// [`App::before_help`]: App::before_help()
881
    /// [`App::before_long_help`]: App::before_long_help()
882
    pub fn help_template<S: Into<&'help str>>(mut self, s: S) -> Self {
2✔
883
        self.template = Some(s.into());
2✔
884
        self
2✔
885
    }
886

887
    /// Enables a single settings for the current (this `App` instance) command or subcommand.
888
    ///
889
    /// See [`AppSettings`] for a full list of possibilities and examples.
890
    ///
891
    /// # Examples
892
    ///
893
    /// ```no_run
894
    /// # use clap::{App, AppSettings};
895
    /// App::new("myprog")
896
    ///     .setting(AppSettings::SubcommandRequired)
897
    ///     .setting(AppSettings::WaitOnError)
898
    /// # ;
899
    /// ```
900
    #[inline]
901
    pub fn setting(mut self, setting: AppSettings) -> Self {
27✔
902
        self.settings.set(setting);
27✔
903
        self
28✔
904
    }
905

906
    /// Disables a single setting for the current (this `App` instance) command or subcommand.
907
    ///
908
    /// See [`AppSettings`] for a full list of possibilities and examples.
909
    ///
910
    /// # Examples
911
    ///
912
    /// ```no_run
913
    /// # use clap::{App, AppSettings};
914
    /// App::new("myprog")
915
    ///     .unset_setting(AppSettings::ColorAuto)
916
    /// # ;
917
    /// ```
918
    #[inline]
919
    pub fn unset_setting(mut self, setting: AppSettings) -> Self {
1✔
920
        self.settings.unset(setting);
1✔
921
        self
1✔
922
    }
923

924
    /// Enables a single setting that is propagated **down** through all child
925
    /// subcommands.
926
    ///
927
    /// See [`AppSettings`] for a full list of possibilities and examples.
928
    ///
929
    /// **NOTE**: The setting is *only* propagated *down* and not up through parent commands.
930
    ///
931
    /// # Examples
932
    ///
933
    /// ```no_run
934
    /// # use clap::{App, AppSettings};
935
    /// App::new("myprog")
936
    ///     .global_setting(AppSettings::SubcommandRequired)
937
    /// # ;
938
    /// ```
939
    #[inline]
940
    pub fn global_setting(mut self, setting: AppSettings) -> Self {
6✔
941
        self.settings.set(setting);
6✔
942
        self.g_settings.set(setting);
6✔
943
        self
6✔
944
    }
945

946
    /// Disables a global setting, and stops propagating down to child
947
    /// subcommands.
948
    ///
949
    /// See [`AppSettings`] for a full list of possibilities and examples.
950
    ///
951
    /// **NOTE:** The setting being unset will be unset from both local and
952
    /// [global] settings.
953
    ///
954
    /// # Examples
955
    ///
956
    /// ```no_run
957
    /// # use clap::{App, AppSettings};
958
    /// App::new("myprog")
959
    ///     .unset_global_setting(AppSettings::ColorAuto)
960
    /// # ;
961
    /// ```
962
    /// [global]: App::global_setting()
963
    #[inline]
964
    pub fn unset_global_setting(mut self, setting: AppSettings) -> Self {
1✔
965
        self.settings.unset(setting);
1✔
966
        self.g_settings.unset(setting);
1✔
967
        self
1✔
968
    }
969

970
    /// Sets the terminal width at which to wrap help messages. Defaults to
971
    /// `100`. Using `0` will ignore terminal widths and use source formatting.
972
    ///
973
    /// `clap` automatically tries to determine the terminal width on Unix,
974
    /// Linux, OSX and Windows if the `wrap_help` cargo "feature" has been enabled
975
    /// at compile time. If the terminal width cannot be determined, `clap`
976
    /// fall back to `100`.
977
    ///
978
    /// **NOTE:** This setting applies globally and *not* on a per-command basis.
979
    ///
980
    /// **NOTE:** This setting must be set **before** any subcommands are added!
981
    ///
982
    /// # Platform Specific
983
    ///
984
    /// Only Unix, Linux, OSX and Windows support automatic determination of
985
    /// terminal width. Even on those platforms, this setting is useful if for
986
    /// any reason the terminal width cannot be determined.
987
    ///
988
    /// # Examples
989
    ///
990
    /// ```no_run
991
    /// # use clap::App;
992
    /// App::new("myprog")
993
    ///     .term_width(80)
994
    /// # ;
995
    /// ```
996
    #[inline]
997
    pub fn term_width(mut self, width: usize) -> Self {
1✔
998
        self.term_w = Some(width);
1✔
999
        self
1✔
1000
    }
1001

1002
    /// Sets the maximum terminal width at which to wrap help messages. Using `0`
1003
    /// will ignore terminal widths and use source formatting.
1004
    ///
1005
    /// `clap` automatically tries to determine the terminal width on Unix,
1006
    /// Linux, OSX and Windows if the `wrap_help` cargo "feature" has been
1007
    /// enabled at compile time, but one might want to limit the size to some
1008
    /// maximum (e.g. when the terminal is running fullscreen).
1009
    ///
1010
    /// **NOTE:** This setting applies globally and *not* on a per-command basis.
1011
    ///
1012
    /// **NOTE:** This setting must be set **before** any subcommands are added!
1013
    ///
1014
    /// # Platform Specific
1015
    ///
1016
    /// Only Unix, Linux, OSX and Windows support automatic determination of terminal width.
1017
    ///
1018
    /// # Examples
1019
    ///
1020
    /// ```no_run
1021
    /// # use clap::App;
1022
    /// App::new("myprog")
1023
    ///     .max_term_width(100)
1024
    /// # ;
1025
    /// ```
1026
    #[inline]
1027
    pub fn max_term_width(mut self, w: usize) -> Self {
×
1028
        self.max_w = Some(w);
×
1029
        self
×
1030
    }
1031

1032
    /// Adds an [argument] to the list of valid possibilities.
1033
    ///
1034
    /// # Examples
1035
    ///
1036
    /// ```no_run
1037
    /// # use clap::{App, Arg};
1038
    /// App::new("myprog")
1039
    ///     // Adding a single "flag" argument with a short and help text, using Arg::new()
1040
    ///     .arg(
1041
    ///         Arg::new("debug")
1042
    ///            .short('d')
1043
    ///            .about("turns on debugging mode")
1044
    ///     )
1045
    ///     // Adding a single "option" argument with a short, a long, and help text using the less
1046
    ///     // verbose Arg::from()
1047
    ///     .arg(
1048
    ///         Arg::from("-c --config=[CONFIG] 'Optionally sets a config file to use'")
1049
    ///     )
1050
    /// # ;
1051
    /// ```
1052
    /// [argument]: Arg
1053
    pub fn arg<A: Into<Arg<'help>>>(mut self, a: A) -> Self {
122✔
1054
        let mut arg = a.into();
122✔
1055
        if let Some(help_heading) = self.current_help_heading {
123✔
1056
            arg = arg.help_heading(Some(help_heading));
2✔
1057
        }
1058
        self.args.push(arg);
123✔
1059
        self
123✔
1060
    }
1061

1062
    /// Set a custom section heading for future args. Every call to [`App::arg`]
1063
    /// (and its related methods) will use this header (instead of the default
1064
    /// header for the specified argument type) until a subsequent call to
1065
    /// [`App::help_heading`] or [`App::stop_custom_headings`].
1066
    ///
1067
    /// This is useful if the default `FLAGS`, `OPTIONS`, or `ARGS` headings are
1068
    /// not specific enough for one's use case.
1069
    ///
1070
    /// [`App::arg`]: App::arg()
1071
    /// [`App::help_heading`]: App::help_heading()
1072
    /// [`App::stop_custom_headings`]: App::stop_custom_headings()
1073
    #[inline]
1074
    pub fn help_heading(mut self, heading: &'help str) -> Self {
2✔
1075
        self.current_help_heading = Some(heading);
2✔
1076
        self
2✔
1077
    }
1078

1079
    /// Stop using [custom argument headings] and return to default headings.
1080
    ///
1081
    /// [custom argument headings]: App::help_heading()
1082
    #[inline]
1083
    pub fn stop_custom_headings(mut self) -> Self {
1✔
1084
        self.current_help_heading = None;
1✔
1085
        self
1✔
1086
    }
1087

1088
    /// Adds multiple [arguments] to the list of valid possibilities.
1089
    ///
1090
    /// # Examples
1091
    ///
1092
    /// ```no_run
1093
    /// # use clap::{App, Arg};
1094
    /// App::new("myprog")
1095
    ///     .args(&[
1096
    ///         Arg::from("[debug] -d 'turns on debugging info'"),
1097
    ///         Arg::new("input").index(1).about("the input file to use")
1098
    ///     ])
1099
    /// # ;
1100
    /// ```
1101
    /// [arguments]: Arg
1102
    pub fn args<I, T>(mut self, args: I) -> Self
25✔
1103
    where
1104
        I: IntoIterator<Item = T>,
1105
        T: Into<Arg<'help>>,
1106
    {
1107
        // @TODO @perf @p4 @v3-beta: maybe extend_from_slice would be possible and perform better?
1108
        // But that may also not let us do `&["-a 'some'", "-b 'other']` because of not Into<Arg>
1109
        for arg in args.into_iter() {
26✔
1110
            self.args.push(arg.into());
26✔
1111
        }
1112
        self
27✔
1113
    }
1114

1115
    /// If this `App` instance is a subcommand, this method adds an alias, which
1116
    /// allows this subcommand to be accessed via *either* the original name, or
1117
    /// this given alias. This is more efficient and easier than creating
1118
    /// multiple hidden subcommands as one only needs to check for the existence
1119
    /// of this command, and not all aliased variants.
1120
    ///
1121
    /// **NOTE:** Aliases defined with this method are *hidden* from the help
1122
    /// message. If you're looking for aliases that will be displayed in the help
1123
    /// message, see [`App::visible_alias`].
1124
    ///
1125
    /// **NOTE:** When using aliases and checking for the existence of a
1126
    /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1127
    /// search for the original name and not all aliases.
1128
    ///
1129
    /// # Examples
1130
    ///
1131
    /// ```rust
1132
    /// # use clap::{App, Arg, };
1133
    /// let m = App::new("myprog")
1134
    ///     .subcommand(App::new("test")
1135
    ///         .alias("do-stuff"))
1136
    ///     .get_matches_from(vec!["myprog", "do-stuff"]);
1137
    /// assert_eq!(m.subcommand_name(), Some("test"));
1138
    /// ```
1139
    /// [`App::visible_alias`]: App::visible_alias()
1140
    pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
3✔
1141
        self.aliases.push((name.into(), false));
3✔
1142
        self
3✔
1143
    }
1144

1145
    /// Allows adding an alias, which function as "hidden" short flag subcommands that
1146
    /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1147
    /// than creating multiple hidden subcommands as one only needs to check for the existence of
1148
    /// this command, and not all variants.
1149
    ///
1150
    /// # Examples
1151
    ///
1152
    /// ```no_run
1153
    /// # use clap::{App, Arg, };
1154
    /// let m = App::new("myprog")
1155
    ///             .subcommand(App::new("test").short_flag('t')
1156
    ///                 .short_flag_alias('d'))
1157
    ///             .get_matches_from(vec!["myprog", "-d"]);
1158
    /// assert_eq!(m.subcommand_name(), Some("test"));
1159
    /// ```
1160
    pub fn short_flag_alias(mut self, name: char) -> Self {
2✔
1161
        if name == '-' {
1✔
1162
            panic!("short alias name cannot be `-`");
1✔
1163
        }
1164
        self.short_flag_aliases.push((name, false));
1✔
1165
        self
1✔
1166
    }
1167

1168
    /// Allows adding an alias, which function as "hidden" long flag subcommands that
1169
    /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1170
    /// than creating multiple hidden subcommands as one only needs to check for the existence of
1171
    /// this command, and not all variants.
1172
    ///
1173
    /// # Examples
1174
    ///
1175
    /// ```no_run
1176
    /// # use clap::{App, Arg, };
1177
    /// let m = App::new("myprog")
1178
    ///             .subcommand(App::new("test").long_flag("test")
1179
    ///                 .long_flag_alias("testing"))
1180
    ///             .get_matches_from(vec!["myprog", "--testing"]);
1181
    /// assert_eq!(m.subcommand_name(), Some("test"));
1182
    /// ```
1183
    pub fn long_flag_alias(mut self, name: &'help str) -> Self {
1✔
1184
        self.long_flag_aliases.push((name, false));
1✔
1185
        self
1✔
1186
    }
1187

1188
    /// If this `App` instance is a subcommand, this method adds a multiple
1189
    /// aliases, which allows this subcommand to be accessed via *either* the
1190
    /// original name or any of the given aliases. This is more efficient, and
1191
    /// easier than creating multiple hidden subcommands as one only needs to
1192
    /// check for the existence of this command and not all aliased variants.
1193
    ///
1194
    /// **NOTE:** Aliases defined with this method are *hidden* from the help
1195
    /// message. If looking for aliases that will be displayed in the help
1196
    /// message, see [`App::visible_aliases`].
1197
    ///
1198
    /// **NOTE:** When using aliases and checking for the existence of a
1199
    /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1200
    /// search for the original name and not all aliases.
1201
    ///
1202
    /// # Examples
1203
    ///
1204
    /// ```rust
1205
    /// # use clap::{App, Arg};
1206
    /// let m = App::new("myprog")
1207
    ///     .subcommand(App::new("test")
1208
    ///         .aliases(&["do-stuff", "do-tests", "tests"]))
1209
    ///         .arg(Arg::new("input")
1210
    ///             .about("the file to add")
1211
    ///             .index(1)
1212
    ///             .required(false))
1213
    ///     .get_matches_from(vec!["myprog", "do-tests"]);
1214
    /// assert_eq!(m.subcommand_name(), Some("test"));
1215
    /// ```
1216
    /// [`App::visible_aliases`]: App::visible_aliases()
1217
    pub fn aliases(mut self, names: &[&'help str]) -> Self {
1✔
1218
        self.aliases.extend(names.iter().map(|n| (*n, false)));
3✔
1219
        self
1✔
1220
    }
1221

1222
    /// Allows adding aliases, which function as "hidden" short flag subcommands that
1223
    /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1224
    /// than creating multiple hidden subcommands as one only needs to check for the existence of
1225
    /// this command, and not all variants.
1226
    ///
1227
    /// # Examples
1228
    ///
1229
    /// ```rust
1230
    /// # use clap::{App, Arg, };
1231
    /// let m = App::new("myprog")
1232
    ///     .subcommand(App::new("test").short_flag('t')
1233
    ///         .short_flag_aliases(&['a', 'b', 'c']))
1234
    ///         .arg(Arg::new("input")
1235
    ///             .about("the file to add")
1236
    ///             .index(1)
1237
    ///             .required(false))
1238
    ///     .get_matches_from(vec!["myprog", "-a"]);
1239
    /// assert_eq!(m.subcommand_name(), Some("test"));
1240
    /// ```
1241
    pub fn short_flag_aliases(mut self, names: &[char]) -> Self {
3✔
1242
        for s in names {
3✔
1243
            if s == &'-' {
2✔
1244
                panic!("short alias name cannot be `-`");
1✔
1245
            }
1246
            self.short_flag_aliases.push((*s, false));
1✔
1247
        }
1248
        self
1✔
1249
    }
1250

1251
    /// Allows adding aliases, which function as "hidden" long flag subcommands that
1252
    /// automatically dispatch as if this subcommand was used. This is more efficient, and easier
1253
    /// than creating multiple hidden subcommands as one only needs to check for the existence of
1254
    /// this command, and not all variants.
1255
    ///
1256
    /// # Examples
1257
    ///
1258
    /// ```rust
1259
    /// # use clap::{App, Arg, };
1260
    /// let m = App::new("myprog")
1261
    ///             .subcommand(App::new("test").long_flag("test")
1262
    ///                 .long_flag_aliases(&["testing", "testall", "test_all"]))
1263
    ///                 .arg(Arg::new("input")
1264
    ///                             .about("the file to add")
1265
    ///                             .index(1)
1266
    ///                             .required(false))
1267
    ///             .get_matches_from(vec!["myprog", "--testing"]);
1268
    /// assert_eq!(m.subcommand_name(), Some("test"));
1269
    /// ```
1270
    pub fn long_flag_aliases(mut self, names: &[&'help str]) -> Self {
1✔
1271
        for s in names {
2✔
1272
            self.long_flag_aliases.push((s, false));
1✔
1273
        }
1274
        self
1✔
1275
    }
1276

1277
    /// If this `App` instance is a subcommand, this method adds a visible
1278
    /// alias, which allows this subcommand to be accessed via *either* the
1279
    /// original name or the given alias. This is more efficient and easier
1280
    /// than creating hidden subcommands as one only needs to check for
1281
    /// the existence of this command and not all aliased variants.
1282
    ///
1283
    /// **NOTE:** The alias defined with this method is *visible* from the help
1284
    /// message and displayed as if it were just another regular subcommand. If
1285
    /// looking for an alias that will not be displayed in the help message, see
1286
    /// [`App::alias`].
1287
    ///
1288
    /// **NOTE:** When using aliases and checking for the existence of a
1289
    /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1290
    /// search for the original name and not all aliases.
1291
    ///
1292
    /// # Examples
1293
    ///
1294
    /// ```no_run
1295
    /// # use clap::{App, Arg};
1296
    /// let m = App::new("myprog")
1297
    ///     .subcommand(App::new("test")
1298
    ///         .visible_alias("do-stuff"))
1299
    ///     .get_matches_from(vec!["myprog", "do-stuff"]);
1300
    /// assert_eq!(m.subcommand_name(), Some("test"));
1301
    /// ```
1302
    /// [`App::alias`]: App::alias()
1303
    pub fn visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self {
1✔
1304
        self.aliases.push((name.into(), true));
1✔
1305
        self
1✔
1306
    }
1307

1308
    /// Allows adding an alias that functions exactly like those defined with
1309
    /// [`App::short_flag_alias`], except that they are visible inside the help message.
1310
    ///
1311
    /// # Examples
1312
    ///
1313
    /// ```no_run
1314
    /// # use clap::{App, Arg, };
1315
    /// let m = App::new("myprog")
1316
    ///             .subcommand(App::new("test").short_flag('t')
1317
    ///                 .visible_short_flag_alias('d'))
1318
    ///             .get_matches_from(vec!["myprog", "-d"]);
1319
    /// assert_eq!(m.subcommand_name(), Some("test"));
1320
    /// ```
1321
    /// [`App::short_flag_alias`]: App::short_flag_alias()
1322
    pub fn visible_short_flag_alias(mut self, name: char) -> Self {
×
1323
        if name == '-' {
×
1324
            panic!("short alias name cannot be `-`");
×
1325
        }
1326
        self.short_flag_aliases.push((name, true));
×
1327
        self
×
1328
    }
1329

1330
    /// Allows adding an alias that functions exactly like those defined with
1331
    /// [`App::long_flag_alias`], except that they are visible inside the help message.
1332
    ///
1333
    /// # Examples
1334
    ///
1335
    /// ```no_run
1336
    /// # use clap::{App, Arg, };
1337
    /// let m = App::new("myprog")
1338
    ///             .subcommand(App::new("test").long_flag("test")
1339
    ///                 .visible_long_flag_alias("testing"))
1340
    ///             .get_matches_from(vec!["myprog", "--testing"]);
1341
    /// assert_eq!(m.subcommand_name(), Some("test"));
1342
    /// ```
1343
    /// [`App::long_flag_alias`]: App::long_flag_alias()
1344
    pub fn visible_long_flag_alias(mut self, name: &'help str) -> Self {
×
1345
        self.long_flag_aliases.push((name, true));
×
1346
        self
×
1347
    }
1348

1349
    /// If this `App` instance is a subcommand, this method adds multiple visible
1350
    /// aliases, which allows this subcommand to be accessed via *either* the
1351
    /// original name or any of the given aliases. This is more efficient and easier
1352
    /// than creating multiple hidden subcommands as one only needs to check for
1353
    /// the existence of this command and not all aliased variants.
1354
    ///
1355
    /// **NOTE:** The alias defined with this method is *visible* from the help
1356
    /// message and displayed as if it were just another regular subcommand. If
1357
    /// looking for an alias that will not be displayed in the help message, see
1358
    /// [`App::alias`].
1359
    ///
1360
    /// **NOTE:** When using aliases, and checking for the existence of a
1361
    /// particular subcommand within an [`ArgMatches`] struct, one only needs to
1362
    /// search for the original name and not all aliases.
1363
    ///
1364
    /// # Examples
1365
    ///
1366
    /// ```no_run
1367
    /// # use clap::{App, Arg, };
1368
    /// let m = App::new("myprog")
1369
    ///     .subcommand(App::new("test")
1370
    ///         .visible_aliases(&["do-stuff", "tests"]))
1371
    ///     .get_matches_from(vec!["myprog", "do-stuff"]);
1372
    /// assert_eq!(m.subcommand_name(), Some("test"));
1373
    /// ```
1374
    /// [`App::alias`]: App::alias()
1375
    pub fn visible_aliases(mut self, names: &[&'help str]) -> Self {
×
1376
        self.aliases.extend(names.iter().map(|n| (*n, true)));
×
1377
        self
×
1378
    }
1379

1380
    /// Allows adding multiple short flag aliases that functions exactly like those defined
1381
    /// with [`App::short_flag_aliases`], except that they are visible inside the help message.
1382
    ///
1383
    /// # Examples
1384
    ///
1385
    /// ```no_run
1386
    /// # use clap::{App, Arg, };
1387
    /// let m = App::new("myprog")
1388
    ///             .subcommand(App::new("test").short_flag('b')
1389
    ///                 .visible_short_flag_aliases(&['t']))
1390
    ///             .get_matches_from(vec!["myprog", "-t"]);
1391
    /// assert_eq!(m.subcommand_name(), Some("test"));
1392
    /// ```
1393
    /// [`App::short_flag_aliases`]: App::short_flag_aliases()
1394
    pub fn visible_short_flag_aliases(mut self, names: &[char]) -> Self {
1✔
1395
        for s in names {
2✔
1396
            if s == &'-' {
1✔
1397
                panic!("short alias name cannot be `-`");
×
1398
            }
1399
            self.short_flag_aliases.push((*s, true));
1✔
1400
        }
1401
        self
1✔
1402
    }
1403

1404
    /// Allows adding multiple long flag aliases that functions exactly like those defined
1405
    /// with [`App::long_flag_aliases`], except that they are visible inside the help message.
1406
    ///
1407
    /// # Examples
1408
    ///
1409
    /// ```no_run
1410
    /// # use clap::{App, Arg, };
1411
    /// let m = App::new("myprog")
1412
    ///             .subcommand(App::new("test").long_flag("test")
1413
    ///                 .visible_long_flag_aliases(&["testing", "testall", "test_all"]))
1414
    ///             .get_matches_from(vec!["myprog", "--testing"]);
1415
    /// assert_eq!(m.subcommand_name(), Some("test"));
1416
    /// ```
1417
    /// [`App::long_flag_aliases`]: App::long_flag_aliases()
1418
    pub fn visible_long_flag_aliases(mut self, names: &[&'help str]) -> Self {
×
1419
        for s in names {
×
1420
            self.long_flag_aliases.push((s, true));
×
1421
        }
1422
        self
×
1423
    }
1424

1425
    /// Replaces an argument or subcommand used on the CLI at runtime with other arguments or subcommands.
1426
    ///
1427
    /// When this method is used, `name` is removed from the CLI, and `target`
1428
    /// is inserted in its place. Parsing continues as if the user typed
1429
    /// `target` instead of `name`.
1430
    ///
1431
    /// This can be used to create "shortcuts" for subcommands, or if a
1432
    /// particular argument has the semantic meaning of several other specific
1433
    /// arguments and values.
1434
    ///
1435
    /// Some examples may help to clear this up.
1436
    ///
1437
    /// # Examples
1438
    ///
1439
    /// We'll start with the "subcommand short" example. In this example, let's
1440
    /// assume we have a program with a subcommand `module` which can be invoked
1441
    /// via `app module`. Now let's also assume `module` also has a subcommand
1442
    /// called `install` which can be invoked `app module install`. If for some
1443
    /// reason users needed to be able to reach `app module install` via the
1444
    /// short-hand `app install`, we'd have several options.
1445
    ///
1446
    /// We *could* create another sibling subcommand to `module` called
1447
    /// `install`, but then we would need to manage another subcommand and manually
1448
    /// dispatch to `app module install` handling code. This is error prone and
1449
    /// tedious.
1450
    ///
1451
    /// We could instead use [`App::replace`] so that, when the user types `app
1452
    /// install`, `clap` will replace `install` with `module install` which will
1453
    /// end up getting parsed as if the user typed the entire incantation.
1454
    ///
1455
    /// ```rust
1456
    /// # use clap::App;
1457
    /// let m = App::new("app")
1458
    ///     .subcommand(App::new("module")
1459
    ///         .subcommand(App::new("install")))
1460
    ///     .replace("install", &["module", "install"])
1461
    ///     .get_matches_from(vec!["app", "install"]);
1462
    ///
1463
    /// assert!(m.subcommand_matches("module").is_some());
1464
    /// assert!(m.subcommand_matches("module").unwrap().subcommand_matches("install").is_some());
1465
    /// ```
1466
    ///
1467
    /// Now let's show an argument example!
1468
    ///
1469
    /// Let's assume we have an application with two flags `--save-context` and
1470
    /// `--save-runtime`. But often users end up needing to do *both* at the
1471
    /// same time. We can add a third flag `--save-all` which semantically means
1472
    /// the same thing as `app --save-context --save-runtime`. To implement that,
1473
    /// we have several options.
1474
    ///
1475
    /// We could create this third argument and manually check if that argument
1476
    /// and in our own consumer code handle the fact that both `--save-context`
1477
    /// and `--save-runtime` *should* have been used. But again this is error
1478
    /// prone and tedious. If we had code relying on checking `--save-context`
1479
    /// and we forgot to update that code to *also* check `--save-all` it'd mean
1480
    /// an error!
1481
    ///
1482
    /// Luckily we can use [`App::replace`] so that when the user types
1483
    /// `--save-all`, `clap` will replace that argument with `--save-context
1484
    /// --save-runtime`, and parsing will continue like normal. Now all our code
1485
    /// that was originally checking for things like `--save-context` doesn't
1486
    /// need to change!
1487
    ///
1488
    /// ```rust
1489
    /// # use clap::{App, Arg};
1490
    /// let m = App::new("app")
1491
    ///     .arg(Arg::new("save-context")
1492
    ///         .long("save-context"))
1493
    ///     .arg(Arg::new("save-runtime")
1494
    ///         .long("save-runtime"))
1495
    ///     .replace("--save-all", &["--save-context", "--save-runtime"])
1496
    ///     .get_matches_from(vec!["app", "--save-all"]);
1497
    ///
1498
    /// assert!(m.is_present("save-context"));
1499
    /// assert!(m.is_present("save-runtime"));
1500
    /// ```
1501
    ///
1502
    /// This can also be used with options, for example if our application with
1503
    /// `--save-*` above also had a `--format=TYPE` option. Let's say it
1504
    /// accepted `txt` or `json` values. However, when `--save-all` is used,
1505
    /// only `--format=json` is allowed, or valid. We could change the example
1506
    /// above to enforce this:
1507
    ///
1508
    /// ```rust
1509
    /// # use clap::{App, Arg};
1510
    /// let m = App::new("app")
1511
    ///     .arg(Arg::new("save-context")
1512
    ///         .long("save-context"))
1513
    ///     .arg(Arg::new("save-runtime")
1514
    ///         .long("save-runtime"))
1515
    ///     .arg(Arg::new("format")
1516
    ///         .long("format")
1517
    ///         .takes_value(true)
1518
    ///         .possible_values(&["txt", "json"]))
1519
    ///     .replace("--save-all", &["--save-context", "--save-runtime", "--format=json"])
1520
    ///     .get_matches_from(vec!["app", "--save-all"]);
1521
    ///
1522
    /// assert!(m.is_present("save-context"));
1523
    /// assert!(m.is_present("save-runtime"));
1524
    /// assert_eq!(m.value_of("format"), Some("json"));
1525
    /// ```
1526
    ///
1527
    /// [`App::replace`]: App::replace()
1528
    #[inline]
1529
    pub fn replace(mut self, name: &'help str, target: &'help [&'help str]) -> Self {
1✔
1530
        self.replacers.insert(name, target);
1✔
1531
        self
1✔
1532
    }
1533

1534
    /// Adds an [`ArgGroup`] to the application. [`ArgGroup`]s are a family of related arguments.
1535
    /// By placing them in a logical group, you can build easier requirement and exclusion rules.
1536
    /// For instance, you can make an entire [`ArgGroup`] required, meaning that one (and *only*
1537
    /// one) argument from that group must be present at runtime.
1538
    ///
1539
    /// You can also do things such as name an [`ArgGroup`] as a conflict to another argument.
1540
    /// Meaning any of the arguments that belong to that group will cause a failure if present with
1541
    /// the conflicting argument.
1542
    ///
1543
    /// Another added benefit of [`ArgGroup`]s is that you can extract a value from a group instead
1544
    /// of determining exactly which argument was used.
1545
    ///
1546
    /// Finally, using [`ArgGroup`]s to ensure exclusion between arguments is another very common
1547
    /// use.
1548
    ///
1549
    /// # Examples
1550
    ///
1551
    /// The following example demonstrates using an [`ArgGroup`] to ensure that one, and only one,
1552
    /// of the arguments from the specified group is present at runtime.
1553
    ///
1554
    /// ```no_run
1555
    /// # use clap::{App, ArgGroup};
1556
    /// App::new("app")
1557
    ///     .arg("--set-ver [ver] 'set the version manually'")
1558
    ///     .arg("--major 'auto increase major'")
1559
    ///     .arg("--minor 'auto increase minor'")
1560
    ///     .arg("--patch 'auto increase patch'")
1561
    ///     .group(ArgGroup::new("vers")
1562
    ///          .args(&["set-ver", "major", "minor","patch"])
1563
    ///          .required(true))
1564
    /// # ;
1565
    /// ```
1566
    #[inline]
1567
    pub fn group<G: Into<ArgGroup<'help>>>(mut self, group: G) -> Self {
9✔
1568
        self.groups.push(group.into());
9✔
1569
        self
9✔
1570
    }
1571

1572
    /// Adds multiple [`ArgGroup`]s to the [`App`] at once.
1573
    ///
1574
    /// # Examples
1575
    ///
1576
    /// ```no_run
1577
    /// # use clap::{App, ArgGroup};
1578
    /// App::new("app")
1579
    ///     .arg("--set-ver [ver] 'set the version manually'")
1580
    ///     .arg("--major         'auto increase major'")
1581
    ///     .arg("--minor         'auto increase minor'")
1582
    ///     .arg("--patch         'auto increase patch'")
1583
    ///     .arg("-c [FILE]       'a config file'")
1584
    ///     .arg("-i [IFACE]      'an interface'")
1585
    ///     .groups(&[
1586
    ///         ArgGroup::new("vers")
1587
    ///             .args(&["set-ver", "major", "minor","patch"])
1588
    ///             .required(true),
1589
    ///         ArgGroup::new("input")
1590
    ///             .args(&["c", "i"])
1591
    ///     ])
1592
    /// # ;
1593
    /// ```
1594
    pub fn groups<I, T>(mut self, groups: I) -> Self
1595
    where
1596
        I: IntoIterator<Item = T>,
1597
        T: Into<ArgGroup<'help>>,
1598
    {
1599
        for g in groups.into_iter() {
×
1600
            self = self.group(g.into());
×
1601
        }
1602
        self
×
1603
    }
1604

1605
    /// Adds a subcommand to the list of valid possibilities. Subcommands are effectively
1606
    /// sub-[`App`]s, because they can contain their own arguments, subcommands, version, usage,
1607
    /// etc. They also function just like [`App`]s, in that they get their own auto generated help,
1608
    /// version, and usage.
1609
    ///
1610
    /// # Examples
1611
    ///
1612
    /// ```no_run
1613
    /// # use clap::{App, Arg, };
1614
    /// App::new("myprog")
1615
    ///     .subcommand(App::new("config")
1616
    ///         .about("Controls configuration features")
1617
    ///         .arg("<config> 'Required configuration file to use'"))
1618
    /// # ;
1619
    /// ```
1620
    #[inline]
1621
    pub fn subcommand<S: Into<App<'help>>>(mut self, subcmd: S) -> Self {
39✔
1622
        self.subcommands.push(subcmd.into());
39✔
1623
        self
39✔
1624
    }
1625

1626
    /// Adds multiple subcommands to the list of valid possibilities by iterating over an
1627
    /// [`IntoIterator`] of [`App`]s.
1628
    ///
1629
    /// # Examples
1630
    ///
1631
    /// ```rust
1632
    /// # use clap::{App, Arg, };
1633
    /// # App::new("myprog")
1634
    /// .subcommands( vec![
1635
    ///        App::new("config").about("Controls configuration functionality")
1636
    ///                                 .arg(Arg::new("config_file").index(1)),
1637
    ///        App::new("debug").about("Controls debug functionality")])
1638
    /// # ;
1639
    /// ```
1640
    /// [`IntoIterator`]: std::iter::IntoIterator
1641
    pub fn subcommands<I, T>(mut self, subcmds: I) -> Self
1✔
1642
    where
1643
        I: IntoIterator<Item = T>,
1644
        T: Into<App<'help>>,
1645
    {
1646
        for subcmd in subcmds.into_iter() {
1✔
1647
            self.subcommands.push(subcmd.into());
1✔
1648
        }
1649
        self
1✔
1650
    }
1651

1652
    /// Allows custom ordering of subcommands within the help message. Subcommands with a lower
1653
    /// value will be displayed first in the help message. This is helpful when one would like to
1654
    /// emphasize frequently used subcommands, or prioritize those towards the top of the list.
1655
    /// Duplicate values **are** allowed. Subcommands with duplicate display orders will be
1656
    /// displayed in alphabetical order.
1657
    ///
1658
    /// **NOTE:** The default is 999 for all subcommands.
1659
    ///
1660
    /// # Examples
1661
    ///
1662
    /// ```rust
1663
    /// # use clap::{App, };
1664
    /// let m = App::new("cust-ord")
1665
    ///     .subcommand(App::new("alpha") // typically subcommands are grouped
1666
    ///                                                // alphabetically by name. Subcommands
1667
    ///                                                // without a display_order have a value of
1668
    ///                                                // 999 and are displayed alphabetically with
1669
    ///                                                // all other 999 subcommands
1670
    ///         .about("Some help and text"))
1671
    ///     .subcommand(App::new("beta")
1672
    ///         .display_order(1)   // In order to force this subcommand to appear *first*
1673
    ///                             // all we have to do is give it a value lower than 999.
1674
    ///                             // Any other subcommands with a value of 1 will be displayed
1675
    ///                             // alphabetically with this one...then 2 values, then 3, etc.
1676
    ///         .about("I should be first!"))
1677
    ///     .get_matches_from(vec![
1678
    ///         "cust-ord", "--help"
1679
    ///     ]);
1680
    /// ```
1681
    ///
1682
    /// The above example displays the following help message
1683
    ///
1684
    /// ```text
1685
    /// cust-ord
1686
    ///
1687
    /// USAGE:
1688
    ///     cust-ord [FLAGS] [OPTIONS]
1689
    ///
1690
    /// FLAGS:
1691
    ///     -h, --help       Prints help information
1692
    ///     -V, --version    Prints version information
1693
    ///
1694
    /// SUBCOMMANDS:
1695
    ///     beta    I should be first!
1696
    ///     alpha   Some help and text
1697
    /// ```
1698
    #[inline]
1699
    pub fn display_order(mut self, ord: usize) -> Self {
×
1700
        self.disp_ord = ord;
×
1701
        self
×
1702
    }
1703

1704
    /// Allows one to mutate an [`Arg`] after it's been added to an [`App`].
1705
    ///
1706
    /// # Examples
1707
    ///
1708
    /// ```rust
1709
    /// # use clap::{App, Arg};
1710
    ///
1711
    /// let mut app = App::new("foo")
1712
    ///     .arg(Arg::new("bar")
1713
    ///         .short('b'))
1714
    ///     .mut_arg("bar", |a| a.short('B'));
1715
    ///
1716
    /// let res = app.try_get_matches_from_mut(vec!["foo", "-b"]);
1717
    ///
1718
    /// // Since we changed `bar`'s short to "B" this should err as there
1719
    /// // is no `-b` anymore, only `-B`
1720
    ///
1721
    /// assert!(res.is_err());
1722
    ///
1723
    /// let res = app.try_get_matches_from_mut(vec!["foo", "-B"]);
1724
    /// assert!(res.is_ok());
1725
    /// ```
1726
    pub fn mut_arg<T, F>(mut self, arg_id: T, f: F) -> Self
22✔
1727
    where
1728
        F: FnOnce(Arg<'help>) -> Arg<'help>,
1729
        T: Key + Into<&'help str>,
1730
    {
1731
        let arg_id: &str = arg_id.into();
22✔
1732
        let id = Id::from(arg_id);
22✔
1733

1734
        let mut a = self.args.remove_by_name(&id).unwrap_or_else(|| Arg {
22✔
1735
            id,
×
1736
            name: arg_id,
×
1737
            ..Arg::default()
×
1738
        });
1739

1740
        if a.provider == ArgProvider::Generated {
22✔
1741
            a.provider = ArgProvider::GeneratedMutated;
22✔
1742
        }
1743

1744
        self.args.push(f(a));
22✔
1745
        self
22✔
1746
    }
1747

1748
    /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same
1749
    /// method as if someone ran `-h` to request the help message.
1750
    ///
1751
    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1752
    /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1753
    ///
1754
    /// # Examples
1755
    ///
1756
    /// ```rust
1757
    /// # use clap::App;
1758
    /// let mut app = App::new("myprog");
1759
    /// app.print_help();
1760
    /// ```
1761
    /// [`io::stdout()`]: std::io::stdout()
1762
    /// [`BufWriter`]: std::io::BufWriter
1763
    /// [`-h` (short)]: Arg::about()
1764
    /// [`--help` (long)]: Arg::long_about()
1765
    pub fn print_help(&mut self) -> io::Result<()> {
×
1766
        self._build();
×
1767

1768
        let p = Parser::new(self);
×
1769
        let mut c = Colorizer::new(false, p.color_help());
×
1770
        Help::new(HelpWriter::Buffer(&mut c), &p, false).write_help()?;
×
1771
        c.print()
×
1772
    }
1773

1774
    /// Prints the full help message to [`io::stdout()`] using a [`BufWriter`] using the same
1775
    /// method as if someone ran `--help` to request the help message.
1776
    ///
1777
    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1778
    /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1779
    ///
1780
    /// # Examples
1781
    ///
1782
    /// ```rust
1783
    /// # use clap::App;
1784
    /// let mut app = App::new("myprog");
1785
    /// app.print_long_help();
1786
    /// ```
1787
    /// [`io::stdout()`]: std::io::stdout()
1788
    /// [`BufWriter`]: std::io::BufWriter
1789
    /// [`-h` (short)]: Arg::about()
1790
    /// [`--help` (long)]: Arg::long_about()
1791
    pub fn print_long_help(&mut self) -> io::Result<()> {
×
1792
        self._build();
×
1793

1794
        let p = Parser::new(self);
×
1795
        let mut c = Colorizer::new(false, p.color_help());
×
1796
        Help::new(HelpWriter::Buffer(&mut c), &p, true).write_help()?;
×
1797
        c.print()
×
1798
    }
1799

1800
    /// Writes the full help message to the user to a [`io::Write`] object in the same method as if
1801
    /// the user ran `-h`.
1802
    ///
1803
    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1804
    /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1805
    ///
1806
    /// # Examples
1807
    ///
1808
    /// ```rust
1809
    /// # use clap::App;
1810
    /// use std::io;
1811
    /// let mut app = App::new("myprog");
1812
    /// let mut out = io::stdout();
1813
    /// app.write_help(&mut out).expect("failed to write to stdout");
1814
    /// ```
1815
    /// [`io::Write`]: std::io::Write
1816
    /// [`-h` (short)]: Arg::about()
1817
    /// [`--help` (long)]: Arg::long_about()
1818
    pub fn write_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
8✔
1819
        self._build();
9✔
1820

1821
        let p = Parser::new(self);
9✔
1822
        Help::new(HelpWriter::Normal(w), &p, false).write_help()?;
9✔
1823
        w.flush()
9✔
1824
    }
1825

1826
    /// Writes the full help message to the user to a [`io::Write`] object in the same method as if
1827
    /// the user ran `--help`.
1828
    ///
1829
    /// **NOTE:** clap has the ability to distinguish between "short" and "long" help messages
1830
    /// depending on if the user ran [`-h` (short)] or [`--help` (long)].
1831
    ///
1832
    /// # Examples
1833
    ///
1834
    /// ```rust
1835
    /// # use clap::App;
1836
    /// use std::io;
1837
    /// let mut app = App::new("myprog");
1838
    /// let mut out = io::stdout();
1839
    /// app.write_long_help(&mut out).expect("failed to write to stdout");
1840
    /// ```
1841
    /// [`io::Write`]: std::io::Write
1842
    /// [`-h` (short)]: Arg::about()
1843
    /// [`--help` (long)]: Arg::long_about()
1844
    pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
7✔
1845
        self._build();
7✔
1846

1847
        let p = Parser::new(self);
10✔
1848
        Help::new(HelpWriter::Normal(w), &p, true).write_help()?;
10✔
1849
        w.flush()
10✔
1850
    }
1851

1852
    /// Returns the version message rendered as if the user ran `-V`.
1853
    ///
1854
    /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages
1855
    /// depending on if the user ran [`-V` (short)] or [`--version` (long)].
1856
    ///
1857
    /// ### Coloring
1858
    ///
1859
    /// This function does not try to color the message nor it inserts any [ANSI escape codes].
1860
    ///
1861
    /// ### Examples
1862
    ///
1863
    /// ```rust
1864
    /// # use clap::App;
1865
    /// use std::io;
1866
    /// let app = App::new("myprog");
1867
    /// println!("{}", app.render_version());
1868
    /// ```
1869
    /// [`io::Write`]: std::io::Write
1870
    /// [`-V` (short)]: App::version()
1871
    /// [`--version` (long)]: App::long_version()
1872
    /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
1873
    pub fn render_version(&self) -> String {
3✔
1874
        self._render_version(false)
3✔
1875
    }
1876

1877
    /// Returns the version message rendered as if the user ran `--version`.
1878
    ///
1879
    /// **NOTE:** clap has the ability to distinguish between "short" and "long" version messages
1880
    /// depending on if the user ran [`-V` (short)] or [`--version` (long)].
1881
    ///
1882
    /// ### Coloring
1883
    ///
1884
    /// This function does not try to color the message nor it inserts any [ANSI escape codes].
1885
    ///
1886
    /// ### Examples
1887
    ///
1888
    /// ```rust
1889
    /// # use clap::App;
1890
    /// use std::io;
1891
    /// let app = App::new("myprog");
1892
    /// println!("{}", app.render_long_version());
1893
    /// ```
1894
    /// [`io::Write`]: std::io::Write
1895
    /// [`-V` (short)]: App::version()
1896
    /// [`--version` (long)]: App::long_version()
1897
    /// [ANSI escape codes]: https://en.wikipedia.org/wiki/ANSI_escape_code
1898
    pub fn render_long_version(&self) -> String {
2✔
1899
        self._render_version(true)
2✔
1900
    }
1901

1902
    /// @TODO-v3-alpha @docs @p2: write docs
1903
    pub fn generate_usage(&mut self) -> String {
3✔
1904
        // If there are global arguments, or settings we need to propagate them down to subcommands
1905
        // before parsing incase we run into a subcommand
1906
        self._build();
3✔
1907

1908
        let mut parser = Parser::new(self);
3✔
1909
        parser._build();
3✔
1910
        Usage::new(&parser).create_usage_with_title(&[])
3✔
1911
    }
1912

1913
    /// Starts the parsing process, upon a failed parse an error will be displayed to the user and
1914
    /// the process will exit with the appropriate error code. By default this method gets all user
1915
    /// provided arguments from [`env::args_os`] in order to allow for invalid UTF-8 code points,
1916
    /// which are legal on many platforms.
1917
    ///
1918
    /// # Examples
1919
    ///
1920
    /// ```no_run
1921
    /// # use clap::{App, Arg};
1922
    /// let matches = App::new("myprog")
1923
    ///     // Args and options go here...
1924
    ///     .get_matches();
1925
    /// ```
1926
    /// [`env::args_os`]: std::env::args_os()
1927
    #[inline]
1928
    pub fn get_matches(self) -> ArgMatches {
×
1929
        self.get_matches_from(&mut env::args_os())
×
1930
    }
1931

1932
    /// Starts the parsing process, just like [`App::get_matches`] but doesn't consume the `App`.
1933
    ///
1934
    /// # Examples
1935
    ///
1936
    /// ```no_run
1937
    /// # use clap::{App, Arg};
1938
    /// let mut app = App::new("myprog")
1939
    ///     // Args and options go here...
1940
    ///     ;
1941
    /// let matches = app.get_matches_mut();
1942
    /// ```
1943
    /// [`env::args_os`]: std::env::args_os()
1944
    /// [`App::get_matches`]: App::get_matches()
1945
    pub fn get_matches_mut(&mut self) -> ArgMatches {
×
1946
        self.try_get_matches_from_mut(&mut env::args_os())
×
1947
            .unwrap_or_else(|e| {
×
1948
                // Otherwise, write to stderr and exit
1949
                if e.use_stderr() {
×
1950
                    e.message.print().expect("Error writing Error to stderr");
×
1951

1952
                    if self.settings.is_set(AppSettings::WaitOnError) {
×
1953
                        wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
×
1954
                        let mut s = String::new();
×
1955
                        let i = io::stdin();
×
1956
                        i.lock().read_line(&mut s).unwrap();
×
1957
                    }
1958

1959
                    drop(e);
×
1960
                    safe_exit(2);
×
1961
                }
1962

1963
                e.exit()
×
1964
            })
1965
    }
1966

1967
    /// Starts the parsing process. This method will return a [`clap::Result`] type instead of exiting
1968
    /// the process on failed parse. By default this method gets matches from [`env::args_os`].
1969
    ///
1970
    /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
1971
    /// used. It will return a [`clap::Error`], where the [`kind`] is a
1972
    /// [`ErrorKind::DisplayHelp`] or [`ErrorKind::DisplayVersion`] respectively. You must call
1973
    /// [`Error::exit`] or perform a [`std::process::exit`].
1974
    ///
1975
    /// # Examples
1976
    ///
1977
    /// ```no_run
1978
    /// # use clap::{App, Arg};
1979
    /// let matches = App::new("myprog")
1980
    ///     // Args and options go here...
1981
    ///     .try_get_matches()
1982
    ///     .unwrap_or_else(|e| e.exit());
1983
    /// ```
1984
    /// [`env::args_os`]: std::env::args_os()
1985
    /// [`Error::exit`]: Error::exit()
1986
    /// [`std::process::exit`]: std::process::exit()
1987
    /// [`clap::Result`]: Result
1988
    /// [`clap::Error`]: Error
1989
    /// [`kind`]: Error
1990
    #[inline]
1991
    pub fn try_get_matches(self) -> ClapResult<ArgMatches> {
4✔
1992
        // Start the parsing
1993
        self.try_get_matches_from(&mut env::args_os())
4✔
1994
    }
1995

1996
    /// Starts the parsing process. Like [`App::get_matches`] this method does not return a [`clap::Result`]
1997
    /// and will automatically exit with an error message. This method, however, lets you specify
1998
    /// what iterator to use when performing matches, such as a [`Vec`] of your making.
1999
    ///
2000
    /// **NOTE:** The first argument will be parsed as the binary name unless
2001
    /// [`AppSettings::NoBinaryName`] is used.
2002
    ///
2003
    /// # Examples
2004
    ///
2005
    /// ```no_run
2006
    /// # use clap::{App, Arg};
2007
    /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2008
    ///
2009
    /// let matches = App::new("myprog")
2010
    ///     // Args and options go here...
2011
    ///     .get_matches_from(arg_vec);
2012
    /// ```
2013
    /// [`App::get_matches`]: App::get_matches()
2014
    /// [`clap::Result`]: Result
2015
    /// [`Vec`]: std::vec::Vec
2016
    pub fn get_matches_from<I, T>(mut self, itr: I) -> ArgMatches
89✔
2017
    where
2018
        I: IntoIterator<Item = T>,
2019
        T: Into<OsString> + Clone,
2020
    {
2021
        self.try_get_matches_from_mut(itr).unwrap_or_else(|e| {
90✔
2022
            // Otherwise, write to stderr and exit
2023
            if e.use_stderr() {
×
2024
                e.message.print().expect("Error writing Error to stderr");
×
2025

2026
                if self.settings.is_set(AppSettings::WaitOnError) {
×
2027
                    wlnerr!("\nPress [ENTER] / [RETURN] to continue...");
×
2028
                    let mut s = String::new();
×
2029
                    let i = io::stdin();
×
2030
                    i.lock().read_line(&mut s).unwrap();
×
2031
                }
2032

2033
                drop(self);
×
2034
                drop(e);
×
2035
                safe_exit(2);
×
2036
            }
2037

2038
            drop(self);
×
2039
            e.exit()
×
2040
        })
2041
    }
2042

2043
    /// Starts the parsing process. A combination of [`App::get_matches_from`], and
2044
    /// [`App::try_get_matches`].
2045
    ///
2046
    /// **NOTE:** This method WILL NOT exit when `--help` or `--version` (or short versions) are
2047
    /// used. It will return a [`clap::Error`], where the [`kind`] is a [`ErrorKind::DisplayHelp`]
2048
    /// or [`ErrorKind::DisplayVersion`] respectively. You must call [`Error::exit`] or
2049
    /// perform a [`std::process::exit`] yourself.
2050
    ///
2051
    /// **NOTE:** The first argument will be parsed as the binary name unless
2052
    /// [`AppSettings::NoBinaryName`] is used.
2053
    ///
2054
    /// # Examples
2055
    ///
2056
    /// ```no_run
2057
    /// # use clap::{App, Arg};
2058
    /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2059
    ///
2060
    /// let matches = App::new("myprog")
2061
    ///     // Args and options go here...
2062
    ///     .try_get_matches_from(arg_vec)
2063
    ///     .unwrap_or_else(|e| e.exit());
2064
    /// ```
2065
    /// [`App::get_matches_from`]: App::get_matches_from()
2066
    /// [`App::try_get_matches`]: App::try_get_matches()
2067
    /// [`Error::exit`]: Error::exit()
2068
    /// [`std::process::exit`]: std::process::exit()
2069
    /// [`clap::Error`]: Error
2070
    /// [`Error::exit`]: Error::exit()
2071
    /// [`kind`]: Error
2072
    pub fn try_get_matches_from<I, T>(mut self, itr: I) -> ClapResult<ArgMatches>
84✔
2073
    where
2074
        I: IntoIterator<Item = T>,
2075
        T: Into<OsString> + Clone,
2076
    {
2077
        self.try_get_matches_from_mut(itr)
80✔
2078
    }
2079

2080
    /// Starts the parsing process without consuming the [`App`] struct `self`. This is normally not
2081
    /// the desired functionality, instead prefer [`App::try_get_matches_from`] which *does*
2082
    /// consume `self`.
2083
    ///
2084
    /// **NOTE:** The first argument will be parsed as the binary name unless
2085
    /// [`AppSettings::NoBinaryName`] is used.
2086
    ///
2087
    /// # Examples
2088
    ///
2089
    /// ```no_run
2090
    /// # use clap::{App, Arg};
2091
    /// let arg_vec = vec!["my_prog", "some", "args", "to", "parse"];
2092
    ///
2093
    /// let mut app = App::new("myprog");
2094
    ///     // Args and options go here...
2095
    /// let matches = app.try_get_matches_from_mut(arg_vec)
2096
    ///     .unwrap_or_else(|e| e.exit());
2097
    /// ```
2098
    /// [`App::try_get_matches_from`]: App::try_get_matches_from()
2099
    pub fn try_get_matches_from_mut<I, T>(&mut self, itr: I) -> ClapResult<ArgMatches>
144✔
2100
    where
2101
        I: IntoIterator<Item = T>,
2102
        T: Into<OsString> + Clone,
2103
    {
2104
        let mut it = Input::from(itr.into_iter());
143✔
2105
        // Get the name of the program (argument 1 of env::args()) and determine the
2106
        // actual file
2107
        // that was used to execute the program. This is because a program called
2108
        // ./target/release/my_prog -a
2109
        // will have two arguments, './target/release/my_prog', '-a' but we don't want
2110
        // to display
2111
        // the full path when displaying help messages and such
2112
        if !self.settings.is_set(AppSettings::NoBinaryName) {
146✔
2113
            if let Some((name, _)) = it.next() {
152✔
2114
                let p = Path::new(name);
147✔
2115

2116
                if let Some(f) = p.file_name() {
148✔
2117
                    if let Some(s) = f.to_str() {
128✔
2118
                        if self.bin_name.is_none() {
133✔
2119
                            self.bin_name = Some(s.to_owned());
135✔
2120
                        }
2121
                    }
2122
                }
2123
            }
2124
        }
2125

2126
        self._do_parse(&mut it)
153✔
2127
    }
2128

2129
    /// Sets the placeholder text used for subcommands when printing usage and help.
2130
    /// By default, this is "SUBCOMMAND" with a header of "SUBCOMMANDS".
2131
    ///
2132
    /// # Examples
2133
    ///
2134
    /// ```no_run
2135
    /// # use clap::{App, Arg};
2136
    /// App::new("myprog")
2137
    ///     .subcommand(App::new("sub1"))
2138
    ///     .print_help()
2139
    /// # ;
2140
    /// ```
2141
    ///
2142
    /// will produce
2143
    ///
2144
    /// ```text
2145
    /// myprog
2146
    ///
2147
    /// USAGE:
2148
    ///     myprog [SUBCOMMAND]
2149
    ///
2150
    /// FLAGS:
2151
    ///     -h, --help       Prints help information
2152
    ///     -V, --version    Prints version information
2153
    ///
2154
    /// SUBCOMMANDS:
2155
    ///     help    Prints this message or the help of the given subcommand(s)
2156
    ///     sub1
2157
    /// ```
2158
    ///
2159
    /// but usage of `subcommand_placeholder`
2160
    ///
2161
    /// ```no_run
2162
    /// # use clap::{App, Arg};
2163
    /// App::new("myprog")
2164
    ///     .subcommand(App::new("sub1"))
2165
    ///     .subcommand_placeholder("THING", "THINGS")
2166
    ///     .print_help()
2167
    /// # ;
2168
    /// ```
2169
    ///
2170
    /// will produce
2171
    ///
2172
    /// ```text
2173
    /// myprog
2174
    ///
2175
    /// USAGE:
2176
    ///     myprog [THING]
2177
    ///
2178
    /// FLAGS:
2179
    ///     -h, --help       Prints help information
2180
    ///     -V, --version    Prints version information
2181
    ///
2182
    /// THINGS:
2183
    ///     help    Prints this message or the help of the given subcommand(s)
2184
    ///     sub1
2185
    /// ```
2186
    pub fn subcommand_placeholder<S, T>(mut self, placeholder: S, header: T) -> Self
1✔
2187
    where
2188
        S: Into<&'help str>,
2189
        T: Into<&'help str>,
2190
    {
2191
        self.subcommand_placeholder = Some(placeholder.into());
1✔
2192
        self.subcommand_header = Some(header.into());
1✔
2193
        self
1✔
2194
    }
2195
}
2196

2197
// Internally used only
2198
impl<'help> App<'help> {
2199
    fn get_used_global_args(&self, matcher: &ArgMatcher) -> Vec<Id> {
76✔
2200
        let global_args: Vec<_> = self
76✔
2201
            .args
×
2202
            .args()
2203
            .filter(|a| a.global)
154✔
2204
            .map(|ga| ga.id.clone())
154✔
2205
            .collect();
2206
        if let Some(used_subcommand) = matcher.0.subcommand.as_ref() {
103✔
2207
            if let Some(used_subcommand) = self
76✔
2208
                .subcommands
×
2209
                .iter()
2210
                .find(|subcommand| subcommand.id == used_subcommand.id)
74✔
2211
            {
2212
                return [global_args, used_subcommand.get_used_global_args(matcher)].concat();
24✔
2213
            }
2214
        }
2215
        global_args
76✔
2216
    }
2217

2218
    fn _do_parse(&mut self, it: &mut Input) -> ClapResult<ArgMatches> {
99✔
2219
        debug!("App::_do_parse");
×
2220
        let mut matcher = ArgMatcher::default();
87✔
2221

2222
        // If there are global arguments, or settings we need to propagate them down to subcommands
2223
        // before parsing in case we run into a subcommand
2224
        self._build();
87✔
2225

2226
        // do the real parsing
2227
        let mut parser = Parser::new(self);
90✔
2228
        if let Err(error) = parser.get_matches_with(&mut matcher, it) {
90✔
2229
            if self.is_set(AppSettings::IgnoreErrors) {
53✔
2230
                debug!("App::_do_parse: ignoring error: {}", error);
×
2231
            } else {
2232
                return Err(error);
52✔
2233
            }
2234
        }
2235

2236
        let global_arg_vec: Vec<Id> = self.get_used_global_args(&matcher);
76✔
2237

2238
        matcher.propagate_globals(&global_arg_vec);
76✔
2239

2240
        Ok(matcher.into_inner())
76✔
2241
    }
2242

2243
    // used in clap_generate (https://github.com/clap-rs/clap_generate)
2244
    #[doc(hidden)]
2245
    pub fn _build(&mut self) {
99✔
2246
        debug!("App::_build");
×
2247
        if !self.settings.is_set(AppSettings::Built) {
206✔
2248
            // Make sure all the globally set flags apply to us as well
2249
            self.settings = self.settings | self.g_settings;
205✔
2250

2251
            self._propagate();
103✔
2252
            self._check_help_and_version();
99✔
2253
            self._propagate_global_args();
100✔
2254
            self._derive_display_order();
101✔
2255

2256
            let mut pos_counter = 1;
101✔
2257
            for a in self.args.args_mut() {
205✔
2258
                // Fill in the groups
2259
                for g in &a.groups {
106✔
2260
                    if let Some(ag) = self.groups.iter_mut().find(|grp| grp.id == *g) {
15✔
2261
                        ag.args.push(a.id.clone());
3✔
2262
                    } else {
2263
                        let mut ag = ArgGroup::with_id(g.clone());
2✔
2264
                        ag.args.push(a.id.clone());
1✔
2265
                        self.groups.push(ag);
1✔
2266
                    }
2267
                }
2268

2269
                // Figure out implied settings
2270
                if a.is_set(ArgSettings::Last) {
304✔
2271
                    // if an arg has `Last` set, we need to imply DontCollapseArgsInUsage so that args
2272
                    // in the usage string don't get confused or left out.
2273
                    self.settings.set(AppSettings::DontCollapseArgsInUsage);
5✔
2274
                }
2275
                a._build();
102✔
2276
                if a.short.is_none() && a.long.is_none() && a.index.is_none() {
205✔
2277
                    a.index = Some(pos_counter);
46✔
2278
                    pos_counter += 1;
92✔
2279
                }
2280
            }
2281

2282
            self.args._build();
101✔
2283

2284
            #[cfg(debug_assertions)]
2285
            self::debug_asserts::assert_app(self);
98✔
2286
            self.settings.set(AppSettings::Built);
100✔
2287
        } else {
2288
            debug!("App::_build: already built");
×
2289
        }
2290
    }
2291

2292
    fn _panic_on_missing_help(&self, help_required_globally: bool) {
104✔
2293
        if self.is_set(AppSettings::HelpRequired) || help_required_globally {
205✔
2294
            let args_missing_help: Vec<String> = self
2✔
2295
                .args
×
2296
                .args()
2297
                .filter(|arg| arg.about.is_none() && arg.long_about.is_none())
2✔
2298
                .map(|arg| String::from(arg.name))
2✔
2299
                .collect();
2300

2301
            if !args_missing_help.is_empty() {
1✔
2302
                panic!(
2✔
2303
                    "AppSettings::HelpRequired is enabled for the App {}, but at least one of its arguments does not have either `help` or `long_help` set. List of such arguments: {}",
2304
                    self.name,
1✔
2305
                    args_missing_help.join(", ")
2✔
2306
                );
2307
            }
2308
        }
2309

2310
        for sub_app in &self.subcommands {
146✔
2311
            sub_app._panic_on_missing_help(help_required_globally);
42✔
2312
        }
2313
    }
2314

2315
    #[cfg(debug_assertions)]
2316
    fn two_args_of<F>(&self, condition: F) -> Option<(&Arg<'help>, &Arg<'help>)>
375✔
2317
    where
2318
        F: Fn(&Arg) -> bool,
2319
    {
2320
        two_elements_of(self.args.args().filter(|a: &&Arg| condition(a)))
1,127✔
2321
    }
2322

2323
    // just in case
2324
    #[allow(unused)]
2325
    fn two_groups_of<F>(&self, condition: F) -> Option<(&ArgGroup, &ArgGroup)>
2326
    where
2327
        F: Fn(&ArgGroup) -> bool,
2328
    {
2329
        two_elements_of(self.groups.iter().filter(|a| condition(a)))
×
2330
    }
2331

2332
    /// Propagate global args
2333
    pub(crate) fn _propagate_global_args(&mut self) {
100✔
2334
        debug!("App::_propagate_global_args:{}", self.name);
×
2335

2336
        for sc in &mut self.subcommands {
141✔
2337
            for a in self.args.args().filter(|a| a.global) {
164✔
2338
                let mut propagate = false;
40✔
2339
                let is_generated = matches!(
17✔
2340
                    a.provider,
×
2341
                    ArgProvider::Generated | ArgProvider::GeneratedMutated
42✔
2342
                );
2343

2344
                // Remove generated help and version args in the subcommand
2345
                //
2346
                // Don't remove if those args are futher mutated
2347
                if is_generated {
59✔
2348
                    let generated_pos = sc
83✔
2349
                        .args
×
2350
                        .args()
2351
                        .position(|x| x.id == a.id && x.provider == ArgProvider::Generated);
125✔
2352

2353
                    if let Some(index) = generated_pos {
42✔
2354
                        sc.args.remove(index);
42✔
2355
                        propagate = true;
41✔
2356
                    }
2357
                }
2358

2359
                if propagate || sc.find(&a.id).is_none() {
84✔
2360
                    sc.args.push(a.clone());
83✔
2361
                }
2362
            }
2363
        }
2364
    }
2365

2366
    /// Propagate settings
2367
    pub(crate) fn _propagate(&mut self) {
103✔
2368
        macro_rules! propagate_subcmd {
×
2369
            ($_self:expr, $sc:expr) => {{
×
2370
                // We have to create a new scope in order to tell rustc the borrow of `sc` is
2371
                // done and to recursively call this method
2372
                {
2373
                    let vsc = $_self
×
2374
                        .settings
×
2375
                        .is_set(AppSettings::DisableVersionForSubcommands);
×
2376
                    let gv = $_self.settings.is_set(AppSettings::GlobalVersion);
×
2377

2378
                    if vsc {
×
2379
                        $sc.set(AppSettings::DisableVersionFlag);
×
2380
                    }
2381
                    if gv && $sc.version.is_none() && $_self.version.is_some() {
×
2382
                        $sc.set(AppSettings::GlobalVersion);
×
2383
                        $sc.version = Some($_self.version.unwrap());
×
2384
                    }
2385
                    if $_self.settings.is_set(AppSettings::IgnoreErrors) {
×
2386
                        $sc.set(AppSettings::IgnoreErrors);
×
2387
                    }
2388
                    $sc.settings = $sc.settings | $_self.g_settings;
×
2389
                    $sc.g_settings = $sc.g_settings | $_self.g_settings;
×
2390
                    $sc.term_w = $_self.term_w;
×
2391
                    $sc.max_w = $_self.max_w;
×
2392
                }
2393
            }};
2394
        }
2395

2396
        debug!("App::_propagate:{}", self.name);
×
2397

2398
        for sc in &mut self.subcommands {
144✔
2399
            propagate_subcmd!(self, sc);
42✔
2400
        }
2401
    }
2402

2403
    #[allow(clippy::blocks_in_if_conditions)]
2404
    pub(crate) fn _check_help_and_version(&mut self) {
99✔
2405
        debug!("App::_check_help_and_version");
×
2406

2407
        if self.is_set(AppSettings::DisableHelpFlag)
495✔
2408
            || self.args.args().any(|x| {
308✔
2409
                x.provider == ArgProvider::User
291✔
2410
                    && (x.long == Some("help") || x.id == Id::help_hash())
175✔
2411
            })
2412
            || self
197✔
2413
                .subcommands
×
2414
                .iter()
×
2415
                .any(|sc| sc.long_flag == Some("help"))
78✔
2416
        {
2417
            debug!("App::_check_help_and_version: Removing generated help");
×
2418

2419
            let generated_help_pos = self
10✔
2420
                .args
×
2421
                .args()
2422
                .position(|x| x.id == Id::help_hash() && x.provider == ArgProvider::Generated);
10✔
2423

2424
            if let Some(index) = generated_help_pos {
10✔
2425
                self.args.remove(index);
5✔
2426
            }
2427
        } else {
2428
            let other_arg_has_short = self.args.args().any(|x| x.short == Some('h'));
405✔
2429
            let help = self
103✔
2430
                .args
×
2431
                .args_mut()
2432
                .find(|x| x.id == Id::help_hash())
206✔
2433
                .expect(INTERNAL_ERROR_MSG);
×
2434

2435
            if !(help.short.is_some()
400✔
2436
                || other_arg_has_short
×
2437
                || self.subcommands.iter().any(|sc| sc.short_flag == Some('h')))
281✔
2438
            {
2439
                help.short = Some('h');
103✔
2440
            }
2441
        }
2442

2443
        if self.is_set(AppSettings::DisableVersionFlag)
504✔
2444
            || self.args.args().any(|x| {
307✔
2445
                x.provider == ArgProvider::User
296✔
2446
                    && (x.long == Some("version") || x.id == Id::version_hash())
177✔
2447
            })
2448
            || self
200✔
2449
                .subcommands
×
2450
                .iter()
×
2451
                .any(|sc| sc.long_flag == Some("version"))
78✔
2452
        {
2453
            debug!("App::_check_help_and_version: Removing generated version");
×
2454

2455
            let generated_version_pos = self
11✔
2456
                .args
×
2457
                .args()
2458
                .position(|x| x.id == Id::version_hash() && x.provider == ArgProvider::Generated);
12✔
2459

2460
            if let Some(index) = generated_version_pos {
12✔
2461
                self.args.remove(index);
6✔
2462
            }
2463
        } else {
2464
            let other_arg_has_short = self.args.args().any(|x| x.short == Some('V'));
416✔
2465
            let version = self
104✔
2466
                .args
×
2467
                .args_mut()
2468
                .find(|x| x.id == Id::version_hash())
208✔
2469
                .expect(INTERNAL_ERROR_MSG);
×
2470

2471
            if !(version.short.is_some()
406✔
2472
                || other_arg_has_short
×
2473
                || self.subcommands.iter().any(|sc| sc.short_flag == Some('V')))
284✔
2474
            {
2475
                version.short = Some('V');
104✔
2476
            }
2477
        }
2478

2479
        if !self.is_set(AppSettings::DisableHelpSubcommand)
484✔
2480
            && self.has_subcommands()
105✔
2481
            && !self.subcommands.iter().any(|s| s.id == Id::help_hash())
166✔
2482
        {
2483
            debug!("App::_check_help_and_version: Building help subcommand");
×
2484
            self.subcommands.push(
81✔
2485
                App::new("help")
81✔
2486
                    .about("Prints this message or the help of the given subcommand(s)"),
×
2487
            );
2488
        }
2489
    }
2490

2491
    pub(crate) fn _derive_display_order(&mut self) {
101✔
2492
        debug!("App::_derive_display_order:{}", self.name);
×
2493

2494
        if self.settings.is_set(AppSettings::DeriveDisplayOrder) {
203✔
2495
            for (i, a) in self
6✔
2496
                .args
×
2497
                .args_mut()
×
2498
                .filter(|a| a.has_switch())
4✔
2499
                .filter(|a| a.disp_ord == 999)
4✔
2500
                .enumerate()
×
2501
            {
2502
                a.disp_ord = i;
2✔
2503
            }
2504
            for (i, mut sc) in &mut self
6✔
2505
                .subcommands
×
2506
                .iter_mut()
×
2507
                .enumerate()
×
2508
                .filter(|&(_, ref sc)| sc.disp_ord == 999)
4✔
2509
            {
2510
                sc.disp_ord = i;
2✔
2511
            }
2512
        }
2513
        for sc in &mut self.subcommands {
144✔
2514
            sc._derive_display_order();
42✔
2515
        }
2516
    }
2517

2518
    // used in clap_generate (https://github.com/clap-rs/clap_generate)
2519
    #[doc(hidden)]
2520
    pub fn _build_bin_names(&mut self) {
5✔
2521
        debug!("App::_build_bin_names");
×
2522

2523
        if !self.is_set(AppSettings::BinNameBuilt) {
10✔
2524
            for mut sc in &mut self.subcommands {
14✔
2525
                debug!("App::_build_bin_names:iter: bin_name set...");
×
2526

2527
                if sc.bin_name.is_none() {
8✔
2528
                    debug!("No");
×
2529
                    let bin_name = format!(
4✔
2530
                        "{}{}{}",
2531
                        self.bin_name.as_ref().unwrap_or(&self.name.clone()),
8✔
2532
                        if self.bin_name.is_some() { " " } else { "" },
4✔
2533
                        &*sc.name
4✔
2534
                    );
2535
                    debug!(
×
2536
                        "App::_build_bin_names:iter: Setting bin_name of {} to {}",
2537
                        self.name, bin_name
×
2538
                    );
2539
                    sc.bin_name = Some(bin_name);
4✔
2540
                } else {
2541
                    debug!("yes ({:?})", sc.bin_name);
×
2542
                }
2543
                debug!(
×
2544
                    "App::_build_bin_names:iter: Calling build_bin_names from...{}",
2545
                    sc.name
×
2546
                );
2547
                sc._build_bin_names();
4✔
2548
            }
2549
            self.set(AppSettings::BinNameBuilt);
4✔
2550
        } else {
2551
            debug!("App::_build_bin_names: already built");
×
2552
        }
2553
    }
2554

2555
    pub(crate) fn _render_version(&self, use_long: bool) -> String {
5✔
2556
        debug!("App::_render_version");
×
2557

2558
        let ver = if use_long {
5✔
2559
            self.long_version
10✔
2560
                .unwrap_or_else(|| self.version.unwrap_or(""))
15✔
2561
        } else {
2562
            self.version
6✔
2563
                .unwrap_or_else(|| self.long_version.unwrap_or(""))
7✔
2564
        };
2565
        if let Some(bn) = self.bin_name.as_ref() {
8✔
2566
            if bn.contains(' ') {
6✔
2567
                // In case we're dealing with subcommands i.e. git mv is translated to git-mv
2568
                format!("{} {}\n", bn.replace(" ", "-"), ver)
×
2569
            } else {
2570
                format!("{} {}\n", &self.name[..], ver)
6✔
2571
            }
2572
        } else {
2573
            format!("{} {}\n", &self.name[..], ver)
6✔
2574
        }
2575
    }
2576

2577
    pub(crate) fn format_group(&self, g: &Id) -> String {
8✔
2578
        let g_string = self
16✔
2579
            .unroll_args_in_group(g)
×
2580
            .iter()
2581
            .filter_map(|x| self.find(x))
24✔
2582
            .map(|x| {
8✔
2583
                if x.index.is_some() {
8✔
2584
                    // Print val_name for positional arguments. e.g. <file_name>
2585
                    x.name_no_brackets().to_string()
6✔
2586
                } else {
2587
                    // Print useage string for flags arguments, e.g. <--help>
2588
                    x.to_string()
7✔
2589
                }
2590
            })
2591
            .collect::<Vec<_>>()
2592
            .join("|");
2593
        format!("<{}>", &*g_string)
7✔
2594
    }
2595
}
2596

2597
// Internal Query Methods
2598
impl<'help> App<'help> {
2599
    pub(crate) fn find(&self, arg_id: &Id) -> Option<&Arg<'help>> {
78✔
2600
        self.args.args().find(|a| a.id == *arg_id)
240✔
2601
    }
2602

2603
    #[inline]
2604
    // Should we color the output?
2605
    pub(crate) fn color(&self) -> ColorChoice {
41✔
2606
        debug!("App::color: Color setting...");
×
2607

2608
        if self.is_set(AppSettings::ColorNever) {
41✔
2609
            debug!("Never");
×
2610
            ColorChoice::Never
×
2611
        } else if self.is_set(AppSettings::ColorAlways) {
41✔
2612
            debug!("Always");
×
2613
            ColorChoice::Always
×
2614
        } else {
2615
            debug!("Auto");
×
2616
            ColorChoice::Auto
41✔
2617
        }
2618
    }
2619

2620
    #[inline]
2621
    pub(crate) fn contains_short(&self, s: char) -> bool {
1✔
2622
        if !self.is_set(AppSettings::Built) {
1✔
2623
            panic!("If App::_build hasn't been called, manually search through Arg shorts");
×
2624
        }
2625

2626
        self.args.contains(s)
1✔
2627
    }
2628

2629
    #[inline]
2630
    pub(crate) fn set(&mut self, s: AppSettings) {
14✔
2631
        self.settings.set(s)
14✔
2632
    }
2633

2634
    #[inline]
2635
    pub(crate) fn has_args(&self) -> bool {
12✔
2636
        !self.args.is_empty()
12✔
2637
    }
2638

2639
    pub(crate) fn has_positionals(&self) -> bool {
2✔
2640
        self.args.keys().any(|x| x.is_position())
6✔
2641
    }
2642

2643
    pub(crate) fn has_visible_subcommands(&self) -> bool {
60✔
2644
        self.subcommands
60✔
2645
            .iter()
2646
            .any(|sc| sc.name != "help" && !sc.is_set(AppSettings::Hidden))
28✔
2647
    }
2648

2649
    /// Check if this subcommand can be referred to as `name`. In other words,
2650
    /// check if `name` is the name of this subcommand or is one of its aliases.
2651
    #[inline]
2652
    pub(crate) fn aliases_to<T>(&self, name: &T) -> bool
67✔
2653
    where
2654
        T: PartialEq<str> + ?Sized,
2655
    {
2656
        *name == *self.get_name() || self.get_all_aliases().any(|alias| *name == *alias)
143✔
2657
    }
2658

2659
    /// Check if this subcommand can be referred to as `name`. In other words,
2660
    /// check if `name` is the name of this short flag subcommand or is one of its short flag aliases.
2661
    #[inline]
2662
    pub(crate) fn short_flag_aliases_to(&self, flag: char) -> bool {
1✔
2663
        Some(flag) == self.short_flag
3✔
2664
            || self.get_all_short_flag_aliases().any(|alias| flag == alias)
4✔
2665
    }
2666

2667
    /// Check if this subcommand can be referred to as `name`. In other words,
2668
    /// check if `name` is the name of this long flag subcommand or is one of its long flag aliases.
2669
    #[inline]
2670
    pub(crate) fn long_flag_aliases_to<T>(&self, flag: &T) -> bool
6✔
2671
    where
2672
        T: PartialEq<str> + ?Sized,
2673
    {
2674
        match self.long_flag {
×
2675
            Some(long_flag) => {
8✔
2676
                flag == long_flag || self.get_all_long_flag_aliases().any(|alias| flag == alias)
4✔
2677
            }
2678
            None => self.get_all_long_flag_aliases().any(|alias| flag == alias),
8✔
2679
        }
2680
    }
2681

2682
    #[cfg(debug_assertions)]
2683
    pub(crate) fn id_exists(&self, id: &Id) -> bool {
17✔
2684
        self.args.args().any(|x| x.id == *id) || self.groups.iter().any(|x| x.id == *id)
73✔
2685
    }
2686

2687
    /// Iterate through the groups this arg is member of.
2688
    pub(crate) fn groups_for_arg<'a>(&'a self, arg: &Id) -> impl Iterator<Item = Id> + 'a {
74✔
2689
        debug!("App::groups_for_arg: id={:?}", arg);
×
2690
        let arg = arg.clone();
75✔
2691
        self.groups
150✔
2692
            .iter()
2693
            .filter(move |grp| grp.args.iter().any(|a| a == &arg))
115✔
2694
            .map(|grp| grp.id.clone())
16✔
2695
    }
2696

2697
    /// Iterate through all the names of all subcommands (not recursively), including aliases.
2698
    /// Used for suggestions.
2699
    pub(crate) fn all_subcommand_names<'a>(&'a self) -> impl Iterator<Item = &'a str>
15✔
2700
    where
2701
        'help: 'a,
2702
    {
2703
        let a: Vec<_> = self
15✔
2704
            .get_subcommands()
2705
            .flat_map(|sc| {
6✔
2706
                let name = sc.get_name();
6✔
2707
                let aliases = sc.get_all_aliases();
6✔
2708
                std::iter::once(name).chain(aliases)
6✔
2709
            })
2710
            .collect();
2711

2712
        // Strictly speaking, we don't need this trip through the Vec.
2713
        // We should have been able to return FlatMap iter above directly.
2714
        //
2715
        // Unfortunately, that would trigger
2716
        // https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
2717
        //
2718
        // I think this "collect to vec" solution is better than the linked one
2719
        // because it's simpler and it doesn't really matter performance-wise.
2720
        a.into_iter()
15✔
2721
    }
2722

2723
    pub(crate) fn unroll_args_in_group(&self, group: &Id) -> Vec<Id> {
7✔
2724
        debug!("App::unroll_args_in_group: group={:?}", group);
×
2725
        let mut g_vec = vec![group];
7✔
2726
        let mut args = vec![];
14✔
2727

2728
        while let Some(g) = g_vec.pop() {
20✔
2729
            for n in self
21✔
2730
                .groups
×
2731
                .iter()
×
2732
                .find(|grp| grp.id == *g)
21✔
2733
                .expect(INTERNAL_ERROR_MSG)
×
2734
                .args
×
2735
                .iter()
×
2736
            {
2737
                debug!("App::unroll_args_in_group:iter: entity={:?}", n);
×
2738
                if !args.contains(n) {
8✔
2739
                    if self.find(n).is_some() {
14✔
2740
                        debug!("App::unroll_args_in_group:iter: this is an arg");
×
2741
                        args.push(n.clone())
21✔
2742
                    } else {
2743
                        debug!("App::unroll_args_in_group:iter: this is a group");
×
2744
                        g_vec.push(n);
×
2745
                    }
2746
                }
2747
            }
2748
        }
2749

2750
        args
×
2751
    }
2752

2753
    pub(crate) fn unroll_requirements_for_arg(&self, arg: &Id, matcher: &ArgMatcher) -> Vec<Id> {
70✔
2754
        let requires_if_or_not = |(val, req_arg): &(Option<&str>, Id)| -> Option<Id> {
81✔
2755
            if let Some(v) = val {
8✔
2756
                if matcher
14✔
2757
                    .get(arg)
3✔
2758
                    .map(|ma| ma.contains_val(v))
9✔
2759
                    .unwrap_or(false)
2760
                {
2761
                    Some(req_arg.clone())
4✔
2762
                } else {
2763
                    None
3✔
2764
                }
2765
            } else {
2766
                Some(req_arg.clone())
8✔
2767
            }
2768
        };
2769

2770
        let mut processed = vec![];
71✔
2771
        let mut r_vec = vec![arg];
71✔
2772
        let mut args = vec![];
144✔
2773

2774
        while let Some(a) = r_vec.pop() {
144✔
2775
            if processed.contains(&a) {
72✔
2776
                continue;
×
2777
            }
2778

2779
            processed.push(a);
72✔
2780

2781
            if let Some(arg) = self.find(a) {
145✔
2782
                for r in arg.requires.iter().filter_map(requires_if_or_not) {
78✔
2783
                    if let Some(req) = self.find(&r) {
5✔
2784
                        if !req.requires.is_empty() {
10✔
2785
                            r_vec.push(&req.id)
2✔
2786
                        }
2787
                    }
2788
                    args.push(r);
5✔
2789
                }
2790
            }
2791
        }
2792

2793
        args
×
2794
    }
2795

2796
    /// Find a flag subcommand name by short flag or an alias
2797
    pub(crate) fn find_short_subcmd(&self, c: char) -> Option<&str> {
3✔
2798
        self.get_subcommands()
6✔
2799
            .find(|sc| sc.short_flag_aliases_to(c))
5✔
2800
            .map(|sc| sc.get_name())
2✔
2801
    }
2802

2803
    /// Find a flag subcommand name by long flag or an alias
2804
    pub(crate) fn find_long_subcmd(&self, long: &ArgStr) -> Option<&str> {
10✔
2805
        self.get_subcommands()
20✔
2806
            .find(|sc| sc.long_flag_aliases_to(long))
22✔
2807
            .map(|sc| sc.get_name())
4✔
2808
    }
2809
}
2810

2811
impl<'help> Index<&'_ Id> for App<'help> {
2812
    type Output = Arg<'help>;
2813

2814
    fn index(&self, key: &Id) -> &Self::Output {
38✔
2815
        self.find(key).expect(INTERNAL_ERROR_MSG)
38✔
2816
    }
2817
}
2818

2819
#[cfg(feature = "yaml")]
2820
impl<'help> From<&'help Yaml> for App<'help> {
2821
    #[allow(clippy::cognitive_complexity)]
2822
    fn from(y: &'help Yaml) -> Self {
3✔
2823
        // We WANT this to panic on error...so expect() is good.
2824
        let (mut a, yaml, err) = if let Some(name) = y["name"].as_str() {
8✔
2825
            (App::new(name), y, "app".into())
2✔
2826
        } else {
2827
            let yaml_hash = y.as_hash().unwrap();
4✔
2828
            let name_yaml = yaml_hash.keys().next().unwrap();
2✔
2829
            let name_str = name_yaml.as_str().unwrap();
2✔
2830

2831
            (
2832
                App::new(name_str),
2✔
2833
                yaml_hash.get(name_yaml).unwrap(),
2✔
2834
                format!("subcommand '{}'", name_str),
2✔
2835
            )
2836
        };
2837

2838
        let mut has_metadata = false;
2✔
2839

2840
        for (k, v) in yaml.as_hash().unwrap().iter() {
4✔
2841
            a = match k.as_str().unwrap() {
17✔
2842
                "_has_metadata" => {
2✔
2843
                    has_metadata = true;
1✔
2844
                    a
1✔
2845
                }
2846
                "bin_name" => yaml_to_str!(a, v, bin_name),
2✔
2847
                "version" => yaml_to_str!(a, v, version),
4✔
2848
                "long_version" => yaml_to_str!(a, v, long_version),
2✔
2849
                "author" => yaml_to_str!(a, v, author),
3✔
2850
                "about" => yaml_to_str!(a, v, about),
4✔
2851
                "before_help" => yaml_to_str!(a, v, before_help),
2✔
2852
                "before_long_help" => yaml_to_str!(a, v, before_long_help),
2✔
2853
                "after_help" => yaml_to_str!(a, v, after_help),
2✔
2854
                "after_long_help" => yaml_to_str!(a, v, after_long_help),
2✔
2855
                "help_heading" => yaml_to_str!(a, v, help_heading),
2✔
2856
                "help_template" => yaml_to_str!(a, v, help_template),
2✔
2857
                "override_help" => yaml_to_str!(a, v, override_help),
2✔
2858
                "override_usage" => yaml_to_str!(a, v, override_usage),
2✔
2859
                "alias" => yaml_to_str!(a, v, alias),
2✔
2860
                "aliases" => yaml_vec_or_str!(a, v, alias),
2✔
2861
                "visible_alias" => yaml_to_str!(a, v, visible_alias),
2✔
2862
                "visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
2✔
2863
                "display_order" => yaml_to_usize!(a, v, display_order),
2✔
2864
                "term_width" => yaml_to_usize!(a, v, term_width),
2✔
2865
                "max_term_width" => yaml_to_usize!(a, v, max_term_width),
2✔
2866
                "args" => {
2✔
2867
                    if let Some(vec) = v.as_vec() {
2✔
2868
                        for arg_yaml in vec {
2✔
2869
                            a = a.arg(Arg::from(arg_yaml));
2✔
2870
                        }
2871
                    } else {
2872
                        panic!("Failed to convert YAML value {:?} to a vec", v);
×
2873
                    }
2874
                    a
2✔
2875
                }
2876
                "subcommands" => {
2✔
2877
                    if let Some(vec) = v.as_vec() {
4✔
2878
                        for sc_yaml in vec {
4✔
2879
                            a = a.subcommand(App::from(sc_yaml));
3✔
2880
                        }
2881
                    } else {
2882
                        panic!("Failed to convert YAML value {:?} to a vec", v);
×
2883
                    }
2884
                    a
2✔
2885
                }
2886
                "groups" => {
2✔
2887
                    if let Some(vec) = v.as_vec() {
4✔
2888
                        for ag_yaml in vec {
4✔
2889
                            a = a.group(ArgGroup::from(ag_yaml));
2✔
2890
                        }
2891
                    } else {
2892
                        panic!("Failed to convert YAML value {:?} to a vec", v);
×
2893
                    }
2894
                    a
2✔
2895
                }
2896
                "setting" | "settings" => yaml_to_setting!(a, v, setting, "AppSetting", err),
3✔
2897
                "global_setting" | "global_settings" => {
2✔
2898
                    yaml_to_setting!(a, v, global_setting, "AppSetting", err)
×
2899
                }
2900
                "name" => continue,
2✔
2901
                s => {
1✔
2902
                    if !has_metadata {
1✔
2903
                        panic!("Unknown setting '{}' in YAML file for {}", s, err)
2✔
2904
                    }
2905
                    continue;
×
2906
                }
2907
            }
2908
        }
2909

2910
        a
2✔
2911
    }
2912
}
2913

2914
impl fmt::Display for App<'_> {
2915
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
×
2916
        write!(f, "{}", self.name)
×
2917
    }
2918
}
2919

2920
fn two_elements_of<I, T>(mut iter: I) -> Option<(T, T)>
376✔
2921
where
2922
    I: Iterator<Item = T>,
2923
{
2924
    let first = iter.next();
376✔
2925
    let second = iter.next();
376✔
2926

2927
    match (first, second) {
747✔
2928
        (Some(first), Some(second)) => Some((first, second)),
750✔
2929
        _ => None,
374✔
2930
    }
2931
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2024 Coveralls, Inc