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

clap-rs / clap / 650304720

pending completion
650304720

Pull #2415

github

GitHub
Merge 88a92042f into dd352be19
Pull Request #2415: Ignore extra fields in Arg yaml definitions

11038 of 12861 relevant lines covered (85.83%)

12.1 hits per line

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

82.53
/src/build/arg/mod.rs
1
#[cfg(debug_assertions)]
2
pub mod debug_asserts;
3
mod settings;
4
#[cfg(test)]
5
mod tests;
6
mod value_hint;
7

8
pub use self::settings::ArgSettings;
9
pub use self::value_hint::ValueHint;
10

11
// Std
12
use std::{
13
    borrow::Cow,
14
    cmp::{Ord, Ordering},
15
    env,
16
    error::Error,
17
    ffi::{OsStr, OsString},
18
    fmt::{self, Display, Formatter},
19
    str,
20
    sync::{Arc, Mutex},
21
};
22

23
// Third Party
24
#[cfg(feature = "regex")]
25
use ::regex::Regex;
26

27
#[cfg(feature = "regex")]
28
mod regex;
29

30
#[cfg(feature = "regex")]
31
pub use self::regex::RegexRef;
32

33
// Internal
34
use crate::{
35
    build::{arg::settings::ArgFlags, usage_parser::UsageParser},
36
    util::VecMap,
37
    util::{Id, Key},
38
    INTERNAL_ERROR_MSG,
39
};
40

41
#[cfg(feature = "yaml")]
42
use yaml_rust::Yaml;
43

44
type Validator<'a> = dyn FnMut(&str) -> Result<(), Box<dyn Error + Send + Sync>> + Send + 'a;
45
type ValidatorOs<'a> = dyn FnMut(&OsStr) -> Result<(), Box<dyn Error + Send + Sync>> + Send + 'a;
46

47
#[derive(Debug, Clone, Eq, PartialEq)]
48
pub(crate) enum ArgProvider {
49
    Generated,
50
    GeneratedMutated,
51
    User,
52
}
53

54
impl Default for ArgProvider {
55
    fn default() -> Self {
109✔
56
        ArgProvider::User
109✔
57
    }
58
}
59

60
/// The abstract representation of a command line argument. Used to set all the options and
61
/// relationships that define a valid argument for the program.
62
///
63
/// There are two methods for constructing [`Arg`]s, using the builder pattern and setting options
64
/// manually, or using a usage string which is far less verbose but has fewer options. You can also
65
/// use a combination of the two methods to achieve the best of both worlds.
66
///
67
/// # Examples
68
///
69
/// ```rust
70
/// # use clap::Arg;
71
/// // Using the traditional builder pattern and setting each option manually
72
/// let cfg = Arg::new("config")
73
///       .short('c')
74
///       .long("config")
75
///       .takes_value(true)
76
///       .value_name("FILE")
77
///       .about("Provides a config file to myprog");
78
/// // Using a usage string (setting a similar argument to the one above)
79
/// let input = Arg::from("-i, --input=[FILE] 'Provides an input file to the program'");
80
/// ```
81
#[allow(missing_debug_implementations)]
82
#[derive(Default, Clone)]
83
pub struct Arg<'help> {
84
    pub(crate) id: Id,
85
    pub(crate) provider: ArgProvider,
86
    pub(crate) name: &'help str,
87
    pub(crate) about: Option<&'help str>,
88
    pub(crate) long_about: Option<&'help str>,
89
    pub(crate) blacklist: Vec<Id>,
90
    pub(crate) settings: ArgFlags,
91
    pub(crate) overrides: Vec<Id>,
92
    pub(crate) groups: Vec<Id>,
93
    pub(crate) requires: Vec<(Option<&'help str>, Id)>,
94
    pub(crate) r_ifs: Vec<(Id, &'help str)>,
95
    pub(crate) r_ifs_all: Vec<(Id, &'help str)>,
96
    pub(crate) r_unless: Vec<Id>,
97
    pub(crate) short: Option<char>,
98
    pub(crate) long: Option<&'help str>,
99
    pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible)
100
    pub(crate) short_aliases: Vec<(char, bool)>, // (name, visible)
101
    pub(crate) disp_ord: usize,
102
    pub(crate) unified_ord: usize,
103
    pub(crate) possible_vals: Vec<&'help str>,
104
    pub(crate) val_names: VecMap<&'help str>,
105
    pub(crate) num_vals: Option<usize>,
106
    pub(crate) max_vals: Option<usize>,
107
    pub(crate) min_vals: Option<usize>,
108
    pub(crate) validator: Option<Arc<Mutex<Validator<'help>>>>,
109
    pub(crate) validator_os: Option<Arc<Mutex<ValidatorOs<'help>>>>,
110
    pub(crate) val_delim: Option<char>,
111
    pub(crate) default_vals: Vec<&'help OsStr>,
112
    pub(crate) default_vals_ifs: VecMap<(Id, Option<&'help OsStr>, Option<&'help OsStr>)>,
113
    pub(crate) default_missing_vals: Vec<&'help OsStr>,
114
    pub(crate) env: Option<(&'help OsStr, Option<OsString>)>,
115
    pub(crate) terminator: Option<&'help str>,
116
    pub(crate) index: Option<usize>,
117
    pub(crate) help_heading: Option<&'help str>,
118
    pub(crate) global: bool,
119
    pub(crate) exclusive: bool,
120
    pub(crate) value_hint: ValueHint,
121
}
122

123
/// Getters
124
impl<'help> Arg<'help> {
125
    /// Get the name of the argument
126
    #[inline]
127
    pub fn get_name(&self) -> &str {
2✔
128
        &self.name
2✔
129
    }
130

131
    /// Get the help specified for this argument, if any
132
    #[inline]
133
    pub fn get_about(&self) -> Option<&str> {
10✔
134
        self.about
10✔
135
    }
136

137
    /// Get the long help specified for this argument, if any
138
    ///
139
    /// # Examples
140
    ///
141
    /// ```rust
142
    /// # use clap::Arg;
143
    /// let arg = Arg::new("foo").long_about("long about");
144
    /// assert_eq!(Some("long about"), arg.get_long_about());
145
    /// ```
146
    ///
147
    #[inline]
148
    pub fn get_long_about(&self) -> Option<&str> {
×
149
        self.long_about
×
150
    }
151

152
    /// Get the help heading specified for this argument, if any
153
    #[inline]
154
    pub fn get_help_heading(&self) -> Option<&str> {
52✔
155
        self.help_heading
52✔
156
    }
157

158
    /// Get the short option name for this argument, if any
159
    #[inline]
160
    pub fn get_short(&self) -> Option<char> {
4✔
161
        self.short
4✔
162
    }
163

164
    /// Get visible short aliases for this argument, if any
165
    #[inline]
166
    pub fn get_visible_short_aliases(&self) -> Option<Vec<char>> {
3✔
167
        if self.short_aliases.is_empty() {
7✔
168
            None
4✔
169
        } else {
170
            Some(
171
                self.short_aliases
3✔
172
                    .iter()
×
173
                    .filter_map(|(c, v)| if *v { Some(c) } else { None })
4✔
174
                    .copied()
×
175
                    .collect(),
×
176
            )
177
        }
178
    }
179

180
    /// Get the short option name and its visible aliases, if any
181
    #[inline]
182
    pub fn get_short_and_visible_aliases(&self) -> Option<Vec<char>> {
2✔
183
        let mut shorts = match self.short {
2✔
184
            Some(short) => vec![short],
4✔
185
            None => return None,
1✔
186
        };
187
        if let Some(aliases) = self.get_visible_short_aliases() {
2✔
188
            shorts.extend(aliases);
1✔
189
        }
190
        Some(shorts)
2✔
191
    }
192

193
    /// Get the long option name for this argument, if any
194
    #[inline]
195
    pub fn get_long(&self) -> Option<&str> {
4✔
196
        self.long
4✔
197
    }
198

199
    /// Get visible aliases for this argument, if any
200
    #[inline]
201
    pub fn get_visible_aliases(&self) -> Option<Vec<&str>> {
4✔
202
        if self.aliases.is_empty() {
7✔
203
            None
4✔
204
        } else {
205
            Some(
206
                self.aliases
3✔
207
                    .iter()
×
208
                    .filter_map(|(s, v)| if *v { Some(s) } else { None })
4✔
209
                    .copied()
×
210
                    .collect(),
×
211
            )
212
        }
213
    }
214

215
    /// Get the long option name and its visible aliases, if any
216
    #[inline]
217
    pub fn get_long_and_visible_aliases(&self) -> Option<Vec<&str>> {
2✔
218
        let mut longs = match self.long {
2✔
219
            Some(long) => vec![long],
4✔
220
            None => return None,
1✔
221
        };
222
        if let Some(aliases) = self.get_visible_aliases() {
2✔
223
            longs.extend(aliases);
1✔
224
        }
225
        Some(longs)
2✔
226
    }
227

228
    /// Get the list of the possible values for this argument, if any
229
    #[inline]
230
    pub fn get_possible_values(&self) -> Option<&[&str]> {
1✔
231
        if self.possible_vals.is_empty() {
2✔
232
            None
1✔
233
        } else {
234
            Some(&self.possible_vals)
4✔
235
        }
236
    }
237

238
    /// Get the index of this argument, if any
239
    #[inline]
240
    pub fn get_index(&self) -> Option<usize> {
89✔
241
        self.index
89✔
242
    }
243

244
    /// Get the value hint of this argument
245
    pub fn get_value_hint(&self) -> ValueHint {
2✔
246
        self.value_hint
2✔
247
    }
248

249
    /// Get information on if this argument is global or not
250
    pub fn get_global(&self) -> bool {
3✔
251
        self.global
3✔
252
    }
253

254
    /// Get the environment variable name specified for this argument, if any
255
    ///
256
    /// # Examples
257
    ///
258
    /// ```rust
259
    /// # use std::ffi::OsStr;
260
    /// # use clap::Arg;
261
    /// let arg = Arg::new("foo").env("ENVIRONMENT");
262
    /// assert_eq!(Some(OsStr::new("ENVIRONMENT")), arg.get_env());
263
    /// ```
264
    pub fn get_env(&self) -> Option<&OsStr> {
×
265
        self.env.as_ref().map(|x| x.0)
×
266
    }
267

268
    /// Get the default values specified for this argument, if any
269
    ///
270
    /// # Examples
271
    ///
272
    /// ```rust
273
    /// # use clap::Arg;
274
    /// let arg = Arg::new("foo").default_value("default value");
275
    /// assert_eq!(&["default value"], arg.get_default_values());
276
    /// ```
277
    pub fn get_default_values(&self) -> &[&OsStr] {
×
278
        &self.default_vals
×
279
    }
280
}
281

282
impl<'help> Arg<'help> {
283
    /// Creates a new instance of [`Arg`] using a unique string name. The name will be used to get
284
    /// information about whether or not the argument was used at runtime, get values, set
285
    /// relationships with other args, etc..
286
    ///
287
    /// **NOTE:** In the case of arguments that take values (i.e. [`Arg::takes_value(true)`])
288
    /// and positional arguments (i.e. those without a preceding `-` or `--`) the name will also
289
    /// be displayed when the user prints the usage/help information of the program.
290
    ///
291
    /// # Examples
292
    ///
293
    /// ```rust
294
    /// # use clap::{App, Arg};
295
    /// Arg::new("config")
296
    /// # ;
297
    /// ```
298
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
299
    pub fn new<S: Into<&'help str>>(n: S) -> Self {
110✔
300
        let name = n.into();
110✔
301
        Arg {
302
            id: Id::from(&*name),
110✔
303
            name,
304
            disp_ord: 999,
305
            unified_ord: 999,
306
            ..Default::default()
307
        }
308
    }
309

310
    pub(crate) fn generated(mut self) -> Self {
110✔
311
        self.provider = ArgProvider::Generated;
110✔
312
        self
110✔
313
    }
314

315
    /// Sets the short version of the argument without the preceding `-`.
316
    ///
317
    /// By default `clap` automatically assigns `V` and `h` to the auto-generated `version` and
318
    /// `help` arguments respectively. You may use the uppercase `V` or lowercase `h` for your own
319
    /// arguments, in which case `clap` simply will not assign those to the auto-generated
320
    /// `version` or `help` arguments.
321
    ///
322
    /// # Examples
323
    ///
324
    /// To set [`short`] use a single valid UTF-8 character. If you supply a leading `-` such as
325
    /// `-c`, the `-` will be stripped.
326
    ///
327
    /// ```rust
328
    /// # use clap::{App, Arg};
329
    /// Arg::new("config")
330
    ///     .short('c')
331
    /// # ;
332
    /// ```
333
    ///
334
    /// Setting [`short`] allows using the argument via a single hyphen (`-`) such as `-c`
335
    ///
336
    /// ```rust
337
    /// # use clap::{App, Arg};
338
    /// let m = App::new("prog")
339
    ///     .arg(Arg::new("config")
340
    ///         .short('c'))
341
    ///     .get_matches_from(vec![
342
    ///         "prog", "-c"
343
    ///     ]);
344
    ///
345
    /// assert!(m.is_present("config"));
346
    /// ```
347
    /// [`short`]: Arg::short()
348
    #[inline]
349
    pub fn short(mut self, s: char) -> Self {
47✔
350
        if s == '-' {
47✔
351
            panic!("short option name cannot be `-`");
×
352
        }
353

354
        self.short = Some(s);
47✔
355
        self
47✔
356
    }
357

358
    /// Sets the long version of the argument without the preceding `--`.
359
    ///
360
    /// By default `clap` automatically assigns `version` and `help` to the auto-generated
361
    /// `version` and `help` arguments respectively. You may use the word `version` or `help` for
362
    /// the long form of your own arguments, in which case `clap` simply will not assign those to
363
    /// the auto-generated `version` or `help` arguments.
364
    ///
365
    /// **NOTE:** Any leading `-` characters will be stripped
366
    ///
367
    /// # Examples
368
    ///
369
    /// To set `long` use a word containing valid UTF-8 codepoints. If you supply a double leading
370
    /// `--` such as `--config` they will be stripped. Hyphens in the middle of the word, however,
371
    /// will *not* be stripped (i.e. `config-file` is allowed)
372
    ///
373
    /// ```rust
374
    /// # use clap::{App, Arg};
375
    /// Arg::new("cfg")
376
    ///     .long("config")
377
    /// # ;
378
    /// ```
379
    ///
380
    /// Setting `long` allows using the argument via a double hyphen (`--`) such as `--config`
381
    ///
382
    /// ```rust
383
    /// # use clap::{App, Arg};
384
    /// let m = App::new("prog")
385
    ///     .arg(Arg::new("cfg")
386
    ///         .long("config"))
387
    ///     .get_matches_from(vec![
388
    ///         "prog", "--config"
389
    ///     ]);
390
    ///
391
    /// assert!(m.is_present("cfg"));
392
    /// ```
393
    #[inline]
394
    pub fn long(mut self, l: &'help str) -> Self {
159✔
395
        self.long = Some(l.trim_start_matches(|c| c == '-'));
380✔
396
        self
161✔
397
    }
398

399
    /// Allows adding a [`Arg`] alias, which function as "hidden" arguments that
400
    /// automatically dispatch as if this argument was used. This is more efficient, and easier
401
    /// than creating multiple hidden arguments as one only needs to check for the existence of
402
    /// this command, and not all variants.
403
    ///
404
    /// # Examples
405
    ///
406
    /// ```rust
407
    /// # use clap::{App, Arg};
408
    /// let m = App::new("prog")
409
    ///             .arg(Arg::new("test")
410
    ///             .long("test")
411
    ///             .alias("alias")
412
    ///             .takes_value(true))
413
    ///        .get_matches_from(vec![
414
    ///             "prog", "--alias", "cool"
415
    ///         ]);
416
    /// assert!(m.is_present("test"));
417
    /// assert_eq!(m.value_of("test"), Some("cool"));
418
    /// ```
419
    pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
5✔
420
        self.aliases.push((name.into(), false));
5✔
421
        self
5✔
422
    }
423

424
    /// Allows adding a [`Arg`] alias, which function as "hidden" arguments that
425
    /// automatically dispatch as if this argument was used. This is more efficient, and easier
426
    /// than creating multiple hidden arguments as one only needs to check for the existence of
427
    /// this command, and not all variants.
428
    ///
429
    /// # Examples
430
    ///
431
    /// ```rust
432
    /// # use clap::{App, Arg};
433
    /// let m = App::new("prog")
434
    ///             .arg(Arg::new("test")
435
    ///             .short('t')
436
    ///             .short_alias('e')
437
    ///             .takes_value(true))
438
    ///        .get_matches_from(vec![
439
    ///             "prog", "-e", "cool"
440
    ///         ]);
441
    /// assert!(m.is_present("test"));
442
    /// assert_eq!(m.value_of("test"), Some("cool"));
443
    /// ```
444
    pub fn short_alias(mut self, name: char) -> Self {
4✔
445
        if name == '-' {
4✔
446
            panic!("short alias name cannot be `-`");
×
447
        }
448

449
        self.short_aliases.push((name, false));
4✔
450
        self
4✔
451
    }
452

453
    /// Allows adding [`Arg`] aliases, which function as "hidden" arguments that
454
    /// automatically dispatch as if this argument was used. This is more efficient, and easier
455
    /// than creating multiple hidden subcommands as one only needs to check for the existence of
456
    /// this command, and not all variants.
457
    ///
458
    /// # Examples
459
    ///
460
    /// ```rust
461
    /// # use clap::{App, Arg};
462
    /// let m = App::new("prog")
463
    ///             .arg(Arg::new("test")
464
    ///                     .long("test")
465
    ///                     .aliases(&["do-stuff", "do-tests", "tests"])
466
    ///                     .about("the file to add")
467
    ///                     .required(false))
468
    ///             .get_matches_from(vec![
469
    ///                 "prog", "--do-tests"
470
    ///             ]);
471
    /// assert!(m.is_present("test"));
472
    /// ```
473
    pub fn aliases(mut self, names: &[&'help str]) -> Self {
3✔
474
        self.aliases.extend(names.iter().map(|&x| (x, false)));
9✔
475
        self
3✔
476
    }
477

478
    /// Allows adding [`Arg`] aliases, which function as "hidden" arguments that
479
    /// automatically dispatch as if this argument was used. This is more efficient, and easier
480
    /// than creating multiple hidden subcommands as one only needs to check for the existence of
481
    /// this command, and not all variants.
482
    ///
483
    /// # Examples
484
    ///
485
    /// ```rust
486
    /// # use clap::{App, Arg};
487
    /// let m = App::new("prog")
488
    ///             .arg(Arg::new("test")
489
    ///                     .short('t')
490
    ///                     .short_aliases(&['e', 's'])
491
    ///                     .about("the file to add")
492
    ///                     .required(false))
493
    ///             .get_matches_from(vec![
494
    ///                 "prog", "-s"
495
    ///             ]);
496
    /// assert!(m.is_present("test"));
497
    /// ```
498
    pub fn short_aliases(mut self, names: &[char]) -> Self {
3✔
499
        for s in names {
6✔
500
            if s == &'-' {
3✔
501
                panic!("short alias name cannot be `-`");
×
502
            }
503
            self.short_aliases.push((*s, false));
3✔
504
        }
505
        self
3✔
506
    }
507

508
    /// Allows adding a [`Arg`] alias that functions exactly like those defined with
509
    /// [`Arg::alias`], except that they are visible inside the help message.
510
    ///
511
    /// # Examples
512
    ///
513
    /// ```rust
514
    /// # use clap::{App, Arg};
515
    /// let m = App::new("prog")
516
    ///             .arg(Arg::new("test")
517
    ///                 .visible_alias("something-awesome")
518
    ///                 .long("test")
519
    ///                 .takes_value(true))
520
    ///        .get_matches_from(vec![
521
    ///             "prog", "--something-awesome", "coffee"
522
    ///         ]);
523
    /// assert!(m.is_present("test"));
524
    /// assert_eq!(m.value_of("test"), Some("coffee"));
525
    /// ```
526
    /// [`App::alias`]: Arg::alias()
527
    pub fn visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self {
7✔
528
        self.aliases.push((name.into(), true));
7✔
529
        self
7✔
530
    }
531

532
    /// Allows adding a [`Arg`] alias that functions exactly like those defined with
533
    /// [`Arg::alias`], except that they are visible inside the help message.
534
    ///
535
    /// # Examples
536
    ///
537
    /// ```rust
538
    /// # use clap::{App, Arg};
539
    /// let m = App::new("prog")
540
    ///             .arg(Arg::new("test")
541
    ///                 .long("test")
542
    ///                 .visible_short_alias('t')
543
    ///                 .takes_value(true))
544
    ///        .get_matches_from(vec![
545
    ///             "prog", "-t", "coffee"
546
    ///         ]);
547
    /// assert!(m.is_present("test"));
548
    /// assert_eq!(m.value_of("test"), Some("coffee"));
549
    /// ```
550
    /// [`App::alias`]: Arg::short_alias()
551
    pub fn visible_short_alias(mut self, name: char) -> Self {
6✔
552
        if name == '-' {
6✔
553
            panic!("short alias name cannot be `-`");
×
554
        }
555

556
        self.short_aliases.push((name, true));
6✔
557
        self
6✔
558
    }
559

560
    /// Allows adding multiple [`Arg`] aliases that functions exactly like those defined
561
    /// with [`Arg::aliases`], except that they are visible inside the help message.
562
    ///
563
    /// # Examples
564
    ///
565
    /// ```rust
566
    /// # use clap::{App, Arg};
567
    /// let m = App::new("prog")
568
    ///             .arg(Arg::new("test")
569
    ///                 .long("test")
570
    ///                 .visible_aliases(&["something", "awesome", "cool"]))
571
    ///        .get_matches_from(vec![
572
    ///             "prog", "--awesome"
573
    ///         ]);
574
    /// assert!(m.is_present("test"));
575
    /// ```
576
    /// [`App::aliases`]: Arg::aliases()
577
    pub fn visible_aliases(mut self, names: &[&'help str]) -> Self {
2✔
578
        self.aliases.extend(names.iter().map(|n| (*n, true)));
6✔
579
        self
2✔
580
    }
581

582
    /// Allows adding multiple [`Arg`] aliases that functions exactly like those defined
583
    /// with [`Arg::aliases`], except that they are visible inside the help message.
584
    ///
585
    /// # Examples
586
    ///
587
    /// ```rust
588
    /// # use clap::{App, Arg};
589
    /// let m = App::new("prog")
590
    ///             .arg(Arg::new("test")
591
    ///                 .long("test")
592
    ///                 .visible_short_aliases(&['t', 'e']))
593
    ///        .get_matches_from(vec![
594
    ///             "prog", "-t"
595
    ///         ]);
596
    /// assert!(m.is_present("test"));
597
    /// ```
598
    /// [`App::aliases`]: Arg::short_aliases()
599
    pub fn visible_short_aliases(mut self, names: &[char]) -> Self {
4✔
600
        for n in names {
7✔
601
            if n == &'-' {
4✔
602
                panic!("short alias name cannot be `-`");
×
603
            }
604
            self.short_aliases.push((*n, true));
4✔
605
        }
606
        self
4✔
607
    }
608

609
    /// Sets the short help text of the argument that will be displayed to the user when they print
610
    /// the help information with `-h`. Typically, this is a short (one line) description of the
611
    /// arg.
612
    ///
613
    /// **NOTE:** If only `Arg::about` is provided, and not [`Arg::long_about`] but the user requests
614
    /// `--help` clap will still display the contents of `help` appropriately
615
    ///
616
    /// **NOTE:** Only `Arg::about` is used in completion script generation in order to be concise
617
    ///
618
    /// # Examples
619
    ///
620
    /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
621
    /// include a newline in the help text and have the following text be properly aligned with all
622
    /// the other help text.
623
    ///
624
    /// ```rust
625
    /// # use clap::{App, Arg};
626
    /// Arg::new("config")
627
    ///     .about("The config file used by the myprog")
628
    /// # ;
629
    /// ```
630
    ///
631
    /// Setting `about` displays a short message to the side of the argument when the user passes
632
    /// `-h` or `--help` (by default).
633
    ///
634
    /// ```rust
635
    /// # use clap::{App, Arg};
636
    /// let m = App::new("prog")
637
    ///     .arg(Arg::new("cfg")
638
    ///         .long("config")
639
    ///         .about("Some help text describing the --config arg"))
640
    ///     .get_matches_from(vec![
641
    ///         "prog", "--help"
642
    ///     ]);
643
    /// ```
644
    ///
645
    /// The above example displays
646
    ///
647
    /// ```notrust
648
    /// helptest
649
    ///
650
    /// USAGE:
651
    ///    helptest [FLAGS]
652
    ///
653
    /// FLAGS:
654
    ///     --config     Some help text describing the --config arg
655
    /// -h, --help       Prints help information
656
    /// -V, --version    Prints version information
657
    /// ```
658
    /// [`Arg::long_about`]: Arg::long_about()
659
    #[inline]
660
    pub fn about(mut self, h: &'help str) -> Self {
132✔
661
        self.about = Some(h);
132✔
662
        self
132✔
663
    }
664

665
    /// Sets the long help text of the argument that will be displayed to the user when they print
666
    /// the help information with `--help`. Typically this a more detailed (multi-line) message
667
    /// that describes the arg.
668
    ///
669
    /// **NOTE:** If only `long_about` is provided, and not [`Arg::about`] but the user requests `-h`
670
    /// clap will still display the contents of `long_about` appropriately
671
    ///
672
    /// **NOTE:** Only [`Arg::about`] is used in completion script generation in order to be concise
673
    ///
674
    /// # Examples
675
    ///
676
    /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
677
    /// include a newline in the help text and have the following text be properly aligned with all
678
    /// the other help text.
679
    ///
680
    /// ```rust
681
    /// # use clap::{App, Arg};
682
    /// Arg::new("config")
683
    ///     .long_about(
684
    /// "The config file used by the myprog must be in JSON format
685
    /// with only valid keys and may not contain other nonsense
686
    /// that cannot be read by this program. Obviously I'm going on
687
    /// and on, so I'll stop now.")
688
    /// # ;
689
    /// ```
690
    ///
691
    /// Setting `help` displays a short message to the side of the argument when the user passes
692
    /// `-h` or `--help` (by default).
693
    ///
694
    /// ```rust
695
    /// # use clap::{App, Arg};
696
    /// let m = App::new("prog")
697
    ///     .arg(Arg::new("cfg")
698
    ///         .long("config")
699
    ///         .long_about(
700
    /// "The config file used by the myprog must be in JSON format
701
    /// with only valid keys and may not contain other nonsense
702
    /// that cannot be read by this program. Obviously I'm going on
703
    /// and on, so I'll stop now."))
704
    ///     .get_matches_from(vec![
705
    ///         "prog", "--help"
706
    ///     ]);
707
    /// ```
708
    ///
709
    /// The above example displays
710
    ///
711
    /// ```text
712
    /// prog
713
    ///
714
    /// USAGE:
715
    ///     prog [FLAGS]
716
    ///
717
    /// FLAGS:
718
    ///         --config
719
    ///             The config file used by the myprog must be in JSON format
720
    ///             with only valid keys and may not contain other nonsense
721
    ///             that cannot be read by this program. Obviously I'm going on
722
    ///             and on, so I'll stop now.
723
    ///
724
    ///     -h, --help
725
    ///             Prints help information
726
    ///
727
    ///     -V, --version
728
    ///             Prints version information
729
    /// ```
730
    /// [`Arg::about`]: Arg::about()
731
    #[inline]
732
    pub fn long_about(mut self, h: &'help str) -> Self {
2✔
733
        self.long_about = Some(h);
2✔
734
        self
2✔
735
    }
736

737
    /// Set this arg as [required] as long as the specified argument is not present at runtime.
738
    ///
739
    /// **Pro Tip:** Using `Arg::required_unless_present` implies [`Arg::required`] and is therefore not
740
    /// mandatory to also set.
741
    ///
742
    /// # Examples
743
    ///
744
    /// ```rust
745
    /// # use clap::Arg;
746
    /// Arg::new("config")
747
    ///     .required_unless_present("debug")
748
    /// # ;
749
    /// ```
750
    ///
751
    /// In the following example, the required argument is *not* provided,
752
    /// but it's not an error because the `unless` arg has been supplied.
753
    ///
754
    /// ```rust
755
    /// # use clap::{App, Arg};
756
    /// let res = App::new("prog")
757
    ///     .arg(Arg::new("cfg")
758
    ///         .required_unless_present("dbg")
759
    ///         .takes_value(true)
760
    ///         .long("config"))
761
    ///     .arg(Arg::new("dbg")
762
    ///         .long("debug"))
763
    ///     .try_get_matches_from(vec![
764
    ///         "prog", "--debug"
765
    ///     ]);
766
    ///
767
    /// assert!(res.is_ok());
768
    /// ```
769
    ///
770
    /// Setting `Arg::required_unless_present(name)` and *not* supplying `name` or this arg is an error.
771
    ///
772
    /// ```rust
773
    /// # use clap::{App, Arg, ErrorKind};
774
    /// let res = App::new("prog")
775
    ///     .arg(Arg::new("cfg")
776
    ///         .required_unless_present("dbg")
777
    ///         .takes_value(true)
778
    ///         .long("config"))
779
    ///     .arg(Arg::new("dbg")
780
    ///         .long("debug"))
781
    ///     .try_get_matches_from(vec![
782
    ///         "prog"
783
    ///     ]);
784
    ///
785
    /// assert!(res.is_err());
786
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
787
    /// ```
788
    /// [required]: Arg::required()
789
    pub fn required_unless_present<T: Key>(mut self, arg_id: T) -> Self {
2✔
790
        self.r_unless.push(arg_id.into());
2✔
791
        self
2✔
792
    }
793

794
    /// Sets this arg as [required] unless *all* of the specified arguments are present at runtime.
795
    ///
796
    /// In other words, parsing will succeed only if user either
797
    /// * supplies the `self` arg.
798
    /// * supplies *all* of the `names` arguments.
799
    ///
800
    /// **NOTE:** If you wish for this argument to only be required unless *any of* these args are
801
    /// present see [`Arg::required_unless_present_any`]
802
    ///
803
    /// # Examples
804
    ///
805
    /// ```rust
806
    /// # use clap::Arg;
807
    /// Arg::new("config")
808
    ///     .required_unless_present_all(&["cfg", "dbg"])
809
    /// # ;
810
    /// ```
811
    ///
812
    /// In the following example, the required argument is *not* provided, but it's not an error
813
    /// because *all* of the `names` args have been supplied.
814
    ///
815
    /// ```rust
816
    /// # use clap::{App, Arg};
817
    /// let res = App::new("prog")
818
    ///     .arg(Arg::new("cfg")
819
    ///         .required_unless_present_all(&["dbg", "infile"])
820
    ///         .takes_value(true)
821
    ///         .long("config"))
822
    ///     .arg(Arg::new("dbg")
823
    ///         .long("debug"))
824
    ///     .arg(Arg::new("infile")
825
    ///         .short('i')
826
    ///         .takes_value(true))
827
    ///     .try_get_matches_from(vec![
828
    ///         "prog", "--debug", "-i", "file"
829
    ///     ]);
830
    ///
831
    /// assert!(res.is_ok());
832
    /// ```
833
    ///
834
    /// Setting [`Arg::required_unless_present_all(names)`] and *not* supplying
835
    /// either *all* of `unless` args or the `self` arg is an error.
836
    ///
837
    /// ```rust
838
    /// # use clap::{App, Arg, ErrorKind};
839
    /// let res = App::new("prog")
840
    ///     .arg(Arg::new("cfg")
841
    ///         .required_unless_present_all(&["dbg", "infile"])
842
    ///         .takes_value(true)
843
    ///         .long("config"))
844
    ///     .arg(Arg::new("dbg")
845
    ///         .long("debug"))
846
    ///     .arg(Arg::new("infile")
847
    ///         .short('i')
848
    ///         .takes_value(true))
849
    ///     .try_get_matches_from(vec![
850
    ///         "prog"
851
    ///     ]);
852
    ///
853
    /// assert!(res.is_err());
854
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
855
    /// ```
856
    /// [required]: Arg::required()
857
    /// [`Arg::required_unless_present_any`]: Arg::required_unless_present_any()
858
    /// [`Arg::required_unless_present_all(names)`]: Arg::required_unless_present_all()
859
    pub fn required_unless_present_all<T, I>(mut self, names: I) -> Self
1✔
860
    where
861
        I: IntoIterator<Item = T>,
862
        T: Key,
863
    {
864
        self.r_unless.extend(names.into_iter().map(Id::from));
1✔
865
        self.setting(ArgSettings::RequiredUnlessAll)
1✔
866
    }
867

868
    /// Sets this arg as [required] unless *any* of the specified arguments are present at runtime.
869
    ///
870
    /// In other words, parsing will succeed only if user either
871
    /// * supplies the `self` arg.
872
    /// * supplies *one or more* of the `unless` arguments.
873
    ///
874
    /// **NOTE:** If you wish for this argument to be required unless *all of* these args are
875
    /// present see [`Arg::required_unless_present_all`]
876
    ///
877
    /// # Examples
878
    ///
879
    /// ```rust
880
    /// # use clap::Arg;
881
    /// Arg::new("config")
882
    ///     .required_unless_present_any(&["cfg", "dbg"])
883
    /// # ;
884
    /// ```
885
    ///
886
    /// Setting [`Arg::required_unless_present_any(names)`] requires that the argument be used at runtime
887
    /// *unless* *at least one of* the args in `names` are present. In the following example, the
888
    /// required argument is *not* provided, but it's not an error because one the `unless` args
889
    /// have been supplied.
890
    ///
891
    /// ```rust
892
    /// # use clap::{App, Arg};
893
    /// let res = App::new("prog")
894
    ///     .arg(Arg::new("cfg")
895
    ///         .required_unless_present_any(&["dbg", "infile"])
896
    ///         .takes_value(true)
897
    ///         .long("config"))
898
    ///     .arg(Arg::new("dbg")
899
    ///         .long("debug"))
900
    ///     .arg(Arg::new("infile")
901
    ///         .short('i')
902
    ///         .takes_value(true))
903
    ///     .try_get_matches_from(vec![
904
    ///         "prog", "--debug"
905
    ///     ]);
906
    ///
907
    /// assert!(res.is_ok());
908
    /// ```
909
    ///
910
    /// Setting [`Arg::required_unless_present_any(names)`] and *not* supplying *at least one of* `names`
911
    /// or this arg is an error.
912
    ///
913
    /// ```rust
914
    /// # use clap::{App, Arg, ErrorKind};
915
    /// let res = App::new("prog")
916
    ///     .arg(Arg::new("cfg")
917
    ///         .required_unless_present_any(&["dbg", "infile"])
918
    ///         .takes_value(true)
919
    ///         .long("config"))
920
    ///     .arg(Arg::new("dbg")
921
    ///         .long("debug"))
922
    ///     .arg(Arg::new("infile")
923
    ///         .short('i')
924
    ///         .takes_value(true))
925
    ///     .try_get_matches_from(vec![
926
    ///         "prog"
927
    ///     ]);
928
    ///
929
    /// assert!(res.is_err());
930
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
931
    /// ```
932
    /// [required]: Arg::required()
933
    /// [`Arg::required_unless_present_any(names)`]: Arg::required_unless_present_any()
934
    /// [`Arg::required_unless_present_all`]: Arg::required_unless_present_all()
935
    pub fn required_unless_present_any<T, I>(mut self, names: I) -> Self
1✔
936
    where
937
        I: IntoIterator<Item = T>,
938
        T: Key,
939
    {
940
        self.r_unless.extend(names.into_iter().map(Id::from));
1✔
941
        self
1✔
942
    }
943

944
    /// Sets a conflicting argument by name. I.e. when using this argument,
945
    /// the following argument can't be present and vice versa.
946
    ///
947
    /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules
948
    /// only need to be set for one of the two arguments, they do not need to be set for each.
949
    ///
950
    /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
951
    /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not
952
    /// need to also do B.conflicts_with(A))
953
    ///
954
    /// **NOTE:** [`Arg::conflicts_with_all(names)`] allows specifying an argument which conflicts with more than one argument.
955
    ///
956
    /// **NOTE** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
957
    ///
958
    /// # Examples
959
    ///
960
    /// ```rust
961
    /// # use clap::Arg;
962
    /// Arg::new("config")
963
    ///     .conflicts_with("debug")
964
    /// # ;
965
    /// ```
966
    ///
967
    /// Setting conflicting argument, and having both arguments present at runtime is an error.
968
    ///
969
    /// ```rust
970
    /// # use clap::{App, Arg, ErrorKind};
971
    /// let res = App::new("prog")
972
    ///     .arg(Arg::new("cfg")
973
    ///         .takes_value(true)
974
    ///         .conflicts_with("debug")
975
    ///         .long("config"))
976
    ///     .arg(Arg::new("debug")
977
    ///         .long("debug"))
978
    ///     .try_get_matches_from(vec![
979
    ///         "prog", "--debug", "--config", "file.conf"
980
    ///     ]);
981
    ///
982
    /// assert!(res.is_err());
983
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::ArgumentConflict);
984
    /// ```
985
    ///
986
    /// [`Arg::conflicts_with_all(names)`]: Arg::conflicts_with_all()
987
    /// [`Arg::exclusive(true)`]: Arg::exclusive()
988
    pub fn conflicts_with<T: Key>(mut self, arg_id: T) -> Self {
16✔
989
        self.blacklist.push(arg_id.into());
16✔
990
        self
16✔
991
    }
992

993
    /// The same as [`Arg::conflicts_with`] but allows specifying multiple two-way conflicts per
994
    /// argument.
995
    ///
996
    /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules
997
    /// only need to be set for one of the two arguments, they do not need to be set for each.
998
    ///
999
    /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
1000
    /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not need
1001
    /// need to also do B.conflicts_with(A))
1002
    ///
1003
    /// **NOTE:** This option does not exist when using a YAML configuration file. Using [`Arg::conflicts_with`]
1004
    /// followed by an array of strings will achieve the equivalent effect.
1005
    ///
1006
    /// **NOTE:** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
1007
    ///
1008
    /// # Examples
1009
    ///
1010
    /// ```rust
1011
    /// # use clap::Arg;
1012
    /// Arg::new("config")
1013
    ///     .conflicts_with_all(&["debug", "input"])
1014
    /// # ;
1015
    /// ```
1016
    ///
1017
    /// Setting conflicting argument, and having any of the arguments present at runtime with a
1018
    /// conflicting argument is an error.
1019
    ///
1020
    /// ```rust
1021
    /// # use clap::{App, Arg, ErrorKind};
1022
    /// let res = App::new("prog")
1023
    ///     .arg(Arg::new("cfg")
1024
    ///         .takes_value(true)
1025
    ///         .conflicts_with_all(&["debug", "input"])
1026
    ///         .long("config"))
1027
    ///     .arg(Arg::new("debug")
1028
    ///         .long("debug"))
1029
    ///     .arg(Arg::new("input")
1030
    ///         .index(1))
1031
    ///     .try_get_matches_from(vec![
1032
    ///         "prog", "--config", "file.conf", "file.txt"
1033
    ///     ]);
1034
    ///
1035
    /// assert!(res.is_err());
1036
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::ArgumentConflict);
1037
    /// ```
1038
    /// [`Arg::conflicts_with`]: Arg::conflicts_with()
1039
    /// [`Arg::exclusive(true)`]: Arg::exclusive()
1040
    pub fn conflicts_with_all(mut self, names: &[&str]) -> Self {
1✔
1041
        self.blacklist.extend(names.iter().map(Id::from));
1✔
1042
        self
1✔
1043
    }
1044

1045
    /// Set an exclusive argument by name. An exclusive argument conflict with every other flag
1046
    /// and must be always passed alone.
1047
    ///
1048
    /// # Examples
1049
    ///
1050
    /// ```rust
1051
    /// # use clap::Arg;
1052
    /// Arg::new("config")
1053
    ///     .exclusive(true)
1054
    /// # ;
1055
    /// ```
1056
    /// **NOTE:** If using YAML the above example should be laid out as follows
1057
    ///
1058
    /// ```yaml
1059
    /// - config
1060
    ///     exclusive: true
1061
    /// ```
1062
    ///
1063
    /// Setting an exclusive argument and having any other arguments present at runtime
1064
    /// is an error.
1065
    ///
1066
    /// ```rust
1067
    /// # use clap::{App, Arg, ErrorKind};
1068
    /// let res = App::new("prog")
1069
    ///     .arg(Arg::new("exclusive")
1070
    ///         .takes_value(true)
1071
    ///         .exclusive(true)
1072
    ///         .long("exclusive"))
1073
    ///     .arg(Arg::new("debug")
1074
    ///         .long("debug"))
1075
    ///     .arg(Arg::new("input")
1076
    ///         .index(1))
1077
    ///     .try_get_matches_from(vec![
1078
    ///         "prog", "--exclusive", "file.conf", "file.txt"
1079
    ///     ]);
1080
    ///
1081
    /// assert!(res.is_err());
1082
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::ArgumentConflict);
1083
    /// ```
1084
    #[inline]
1085
    pub fn exclusive(mut self, exclusive: bool) -> Self {
3✔
1086
        // FIXME: This should be an ArgSetting, not bool
1087
        self.exclusive = exclusive;
3✔
1088
        self
3✔
1089
    }
1090

1091
    /// Sets an overridable argument by name. I.e. this argument and the following argument
1092
    /// will override each other in POSIX style (whichever argument was specified at runtime
1093
    /// **last** "wins")
1094
    ///
1095
    /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any
1096
    /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed
1097
    ///
1098
    /// **WARNING:** Positional arguments and options which accept [`Multiple*`] cannot override
1099
    /// themselves (or we would never be able to advance to the next positional). If a positional
1100
    /// argument or option with one of the [`Multiple*`] settings lists itself as an override, it is
1101
    /// simply ignored.
1102
    ///
1103
    /// # Examples
1104
    ///
1105
    /// ```rust # use clap::{App, Arg};
1106
    /// # use clap::{App, Arg};
1107
    /// let m = App::new("prog")
1108
    ///     .arg(Arg::from("-f, --flag 'some flag'")
1109
    ///         .conflicts_with("debug"))
1110
    ///     .arg(Arg::from("-d, --debug 'other flag'"))
1111
    ///     .arg(Arg::from("-c, --color 'third flag'")
1112
    ///         .overrides_with("flag"))
1113
    ///     .get_matches_from(vec![
1114
    ///         "prog", "-f", "-d", "-c"]);
1115
    ///             //    ^~~~~~~~~~~~^~~~~ flag is overridden by color
1116
    ///
1117
    /// assert!(m.is_present("color"));
1118
    /// assert!(m.is_present("debug")); // even though flag conflicts with debug, it's as if flag
1119
    ///                                 // was never used because it was overridden with color
1120
    /// assert!(!m.is_present("flag"));
1121
    /// ```
1122
    /// Care must be taken when using this setting, and having an arg override with itself. This
1123
    /// is common practice when supporting things like shell aliases, config files, etc.
1124
    /// However, when combined with multiple values, it can get dicy.
1125
    /// Here is how clap handles such situations:
1126
    ///
1127
    /// When a flag overrides itself, it's as if the flag was only ever used once (essentially
1128
    /// preventing a "Unexpected multiple usage" error):
1129
    ///
1130
    /// ```rust
1131
    /// # use clap::{App, Arg};
1132
    /// let m = App::new("posix")
1133
    ///             .arg(Arg::from("--flag  'some flag'").overrides_with("flag"))
1134
    ///             .get_matches_from(vec!["posix", "--flag", "--flag"]);
1135
    /// assert!(m.is_present("flag"));
1136
    /// assert_eq!(m.occurrences_of("flag"), 1);
1137
    /// ```
1138
    /// Making an arg [`Multiple*``] and override itself is essentially meaningless. Therefore
1139
    /// clap ignores an override of self if it's a flag and it already accepts multiple occurrences.
1140
    ///
1141
    /// ```
1142
    /// # use clap::{App, Arg};
1143
    /// let m = App::new("posix")
1144
    ///             .arg(Arg::from("--flag...  'some flag'").overrides_with("flag"))
1145
    ///             .get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
1146
    /// assert!(m.is_present("flag"));
1147
    /// assert_eq!(m.occurrences_of("flag"), 4);
1148
    /// ```
1149
    /// Now notice with options (which *do not* set one of the [`Multiple*`]), it's as if only the
1150
    /// last occurrence happened.
1151
    ///
1152
    /// ```
1153
    /// # use clap::{App, Arg};
1154
    /// let m = App::new("posix")
1155
    ///             .arg(Arg::from("--opt [val] 'some option'").overrides_with("opt"))
1156
    ///             .get_matches_from(vec!["", "--opt=some", "--opt=other"]);
1157
    /// assert!(m.is_present("opt"));
1158
    /// assert_eq!(m.occurrences_of("opt"), 1);
1159
    /// assert_eq!(m.value_of("opt"), Some("other"));
1160
    /// ```
1161
    ///
1162
    /// Just like flags, options with one of the [`Multiple*``] set, will ignore the "override self"
1163
    /// setting.
1164
    ///
1165
    /// ```
1166
    /// # use clap::{App, Arg};
1167
    /// let m = App::new("posix")
1168
    ///             .arg(Arg::from("--opt [val]... 'some option'")
1169
    ///                 .overrides_with("opt"))
1170
    ///             .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]);
1171
    /// assert!(m.is_present("opt"));
1172
    /// assert_eq!(m.occurrences_of("opt"), 2);
1173
    /// assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["first", "over", "other", "val"]);
1174
    /// ```
1175
    ///
1176
    /// A safe thing to do if you'd like to support an option which supports multiple values, but
1177
    /// also is "overridable" by itself, is to not use [`UseValueDelimiter`] and *not* use
1178
    /// `MultipleValues` while telling users to separate values with a comma (i.e. `val1,val2`)
1179
    ///
1180
    /// ```
1181
    /// # use clap::{App, Arg};
1182
    /// let m = App::new("posix")
1183
    ///             .arg(Arg::from("--opt [val] 'some option'")
1184
    ///                 .overrides_with("opt"))
1185
    ///             .get_matches_from(vec!["", "--opt=some,other", "--opt=one,two"]);
1186
    /// assert!(m.is_present("opt"));
1187
    /// assert_eq!(m.occurrences_of("opt"), 1);
1188
    /// assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["one,two"]);
1189
    /// ```
1190
    /// [`Multiple*`]: ArgSettings::MultipleValues
1191
    /// [`UseValueDelimiter`]: ArgSettings::UseValueDelimiter
1192
    pub fn overrides_with<T: Key>(mut self, arg_id: T) -> Self {
4✔
1193
        self.overrides.push(arg_id.into());
4✔
1194
        self
4✔
1195
    }
1196

1197
    /// Sets multiple mutually overridable arguments by name. I.e. this argument and the following
1198
    /// argument will override each other in POSIX style (whichever argument was specified at
1199
    /// runtime **last** "wins")
1200
    ///
1201
    /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any
1202
    /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed
1203
    ///
1204
    /// # Examples
1205
    ///
1206
    /// ```rust
1207
    /// # use clap::{App, Arg};
1208
    /// let m = App::new("prog")
1209
    ///     .arg(Arg::from("-f, --flag 'some flag'")
1210
    ///         .conflicts_with("color"))
1211
    ///     .arg(Arg::from("-d, --debug 'other flag'"))
1212
    ///     .arg(Arg::from("-c, --color 'third flag'")
1213
    ///         .overrides_with_all(&["flag", "debug"]))
1214
    ///     .get_matches_from(vec![
1215
    ///         "prog", "-f", "-d", "-c"]);
1216
    ///             //    ^~~~~~^~~~~~~~~ flag and debug are overridden by color
1217
    ///
1218
    /// assert!(m.is_present("color")); // even though flag conflicts with color, it's as if flag
1219
    ///                                 // and debug were never used because they were overridden
1220
    ///                                 // with color
1221
    /// assert!(!m.is_present("debug"));
1222
    /// assert!(!m.is_present("flag"));
1223
    /// ```
1224
    pub fn overrides_with_all<T: Key>(mut self, names: &[T]) -> Self {
×
1225
        self.overrides.extend(names.iter().map(Id::from));
×
1226
        self
×
1227
    }
1228

1229
    /// Sets an argument by name that is required when this one is present I.e. when
1230
    /// using this argument, the following argument *must* be present.
1231
    ///
1232
    /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required
1233
    ///
1234
    /// # Examples
1235
    ///
1236
    /// ```rust
1237
    /// # use clap::Arg;
1238
    /// Arg::new("config")
1239
    ///     .requires("input")
1240
    /// # ;
1241
    /// ```
1242
    ///
1243
    /// Setting [`Arg::requires(name)`] requires that the argument be used at runtime if the
1244
    /// defining argument is used. If the defining argument isn't used, the other argument isn't
1245
    /// required
1246
    ///
1247
    /// ```rust
1248
    /// # use clap::{App, Arg};
1249
    /// let res = App::new("prog")
1250
    ///     .arg(Arg::new("cfg")
1251
    ///         .takes_value(true)
1252
    ///         .requires("input")
1253
    ///         .long("config"))
1254
    ///     .arg(Arg::new("input")
1255
    ///         .index(1))
1256
    ///     .try_get_matches_from(vec![
1257
    ///         "prog"
1258
    ///     ]);
1259
    ///
1260
    /// assert!(res.is_ok()); // We didn't use cfg, so input wasn't required
1261
    /// ```
1262
    ///
1263
    /// Setting [`Arg::requires(name)`] and *not* supplying that argument is an error.
1264
    ///
1265
    /// ```rust
1266
    /// # use clap::{App, Arg, ErrorKind};
1267
    /// let res = App::new("prog")
1268
    ///     .arg(Arg::new("cfg")
1269
    ///         .takes_value(true)
1270
    ///         .requires("input")
1271
    ///         .long("config"))
1272
    ///     .arg(Arg::new("input")
1273
    ///         .index(1))
1274
    ///     .try_get_matches_from(vec![
1275
    ///         "prog", "--config", "file.conf"
1276
    ///     ]);
1277
    ///
1278
    /// assert!(res.is_err());
1279
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1280
    /// ```
1281
    /// [`Arg::requires(name)`]: Arg::requires()
1282
    /// [Conflicting]: Arg::conflicts_with()
1283
    /// [override]: Arg::overrides_with()
1284
    pub fn requires<T: Key>(mut self, arg_id: T) -> Self {
12✔
1285
        self.requires.push((None, arg_id.into()));
12✔
1286
        self
12✔
1287
    }
1288

1289
    /// Require another argument if this arg was present on runtime, and its value equals to `val`.
1290
    ///
1291
    /// This method takes `value, another_arg` pair. At runtime, clap will check
1292
    /// if this arg (`self`) is present and its value equals to `val`.
1293
    /// If it does, `another_arg` will be marked as required.
1294
    ///
1295
    /// **NOTE:** If using YAML the values should be laid out as follows
1296
    ///
1297
    /// ```yaml
1298
    /// requires_if:
1299
    ///     - [val, arg]
1300
    /// ```
1301
    ///
1302
    /// # Examples
1303
    ///
1304
    /// ```rust
1305
    /// # use clap::Arg;
1306
    /// Arg::new("config")
1307
    ///     .requires_if("val", "arg")
1308
    /// # ;
1309
    /// ```
1310
    ///
1311
    /// Setting `Arg::requires_if(val, arg)` requires that the `arg` be used at runtime if the
1312
    /// defining argument's value is equal to `val`. If the defining argument is anything other than
1313
    /// `val`, the other argument isn't required.
1314
    ///
1315
    /// ```rust
1316
    /// # use clap::{App, Arg};
1317
    /// let res = App::new("prog")
1318
    ///     .arg(Arg::new("cfg")
1319
    ///         .takes_value(true)
1320
    ///         .requires_if("my.cfg", "other")
1321
    ///         .long("config"))
1322
    ///     .arg(Arg::new("other"))
1323
    ///     .try_get_matches_from(vec![
1324
    ///         "prog", "--config", "some.cfg"
1325
    ///     ]);
1326
    ///
1327
    /// assert!(res.is_ok()); // We didn't use --config=my.cfg, so other wasn't required
1328
    /// ```
1329
    ///
1330
    /// Setting `Arg::requires_if(val, arg)` and setting the value to `val` but *not* supplying
1331
    /// `arg` is an error.
1332
    ///
1333
    /// ```rust
1334
    /// # use clap::{App, Arg, ErrorKind};
1335
    /// let res = App::new("prog")
1336
    ///     .arg(Arg::new("cfg")
1337
    ///         .takes_value(true)
1338
    ///         .requires_if("my.cfg", "input")
1339
    ///         .long("config"))
1340
    ///     .arg(Arg::new("input"))
1341
    ///     .try_get_matches_from(vec![
1342
    ///         "prog", "--config", "my.cfg"
1343
    ///     ]);
1344
    ///
1345
    /// assert!(res.is_err());
1346
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1347
    /// ```
1348
    /// [`Arg::requires(name)`]: Arg::requires()
1349
    /// [Conflicting]: Arg::conflicts_with()
1350
    /// [override]: Arg::overrides_with()
1351
    pub fn requires_if<T: Key>(mut self, val: &'help str, arg_id: T) -> Self {
5✔
1352
        self.requires.push((Some(val), arg_id.into()));
5✔
1353
        self
5✔
1354
    }
1355

1356
    /// Allows multiple conditional requirements. The requirement will only become valid if this arg's value
1357
    /// equals `val`.
1358
    ///
1359
    /// **NOTE:** If using YAML the values should be laid out as follows
1360
    ///
1361
    /// ```yaml
1362
    /// requires_if:
1363
    ///     - [val, arg]
1364
    ///     - [val2, arg2]
1365
    /// ```
1366
    ///
1367
    /// # Examples
1368
    ///
1369
    /// ```rust
1370
    /// # use clap::Arg;
1371
    /// Arg::new("config")
1372
    ///     .requires_ifs(&[
1373
    ///         ("val", "arg"),
1374
    ///         ("other_val", "arg2"),
1375
    ///     ])
1376
    /// # ;
1377
    /// ```
1378
    ///
1379
    /// Setting `Arg::requires_ifs(&["val", "arg"])` requires that the `arg` be used at runtime if the
1380
    /// defining argument's value is equal to `val`. If the defining argument's value is anything other
1381
    /// than `val`, `arg` isn't required.
1382
    ///
1383
    /// ```rust
1384
    /// # use clap::{App, Arg, ErrorKind};
1385
    /// let res = App::new("prog")
1386
    ///     .arg(Arg::new("cfg")
1387
    ///         .takes_value(true)
1388
    ///         .requires_ifs(&[
1389
    ///             ("special.conf", "opt"),
1390
    ///             ("other.conf", "other"),
1391
    ///         ])
1392
    ///         .long("config"))
1393
    ///     .arg(Arg::new("opt")
1394
    ///         .long("option")
1395
    ///         .takes_value(true))
1396
    ///     .arg(Arg::new("other"))
1397
    ///     .try_get_matches_from(vec![
1398
    ///         "prog", "--config", "special.conf"
1399
    ///     ]);
1400
    ///
1401
    /// assert!(res.is_err()); // We  used --config=special.conf so --option <val> is required
1402
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1403
    /// ```
1404
    /// [`Arg::requires(name)`]: Arg::requires()
1405
    /// [Conflicting]: Arg::conflicts_with()
1406
    /// [override]: Arg::overrides_with()
1407
    pub fn requires_ifs<T: Key>(mut self, ifs: &[(&'help str, T)]) -> Self {
2✔
1408
        self.requires
2✔
1409
            .extend(ifs.iter().map(|(val, arg)| (Some(*val), Id::from(arg))));
6✔
1410
        self
2✔
1411
    }
1412

1413
    /// Allows specifying that this argument is [required] only if the specified
1414
    /// `arg` is present at runtime and its value equals `val`.
1415
    ///
1416
    /// **NOTE:** If using YAML the values should be laid out as follows
1417
    ///
1418
    /// ```yaml
1419
    /// required_if_eq:
1420
    ///     - [arg, val]
1421
    /// ```
1422
    ///
1423
    /// # Examples
1424
    ///
1425
    /// ```rust
1426
    /// # use clap::Arg;
1427
    /// Arg::new("config")
1428
    ///     .required_if_eq("other_arg", "value")
1429
    /// # ;
1430
    /// ```
1431
    ///
1432
    /// ```rust
1433
    /// # use clap::{App, Arg, ErrorKind};
1434
    /// let res = App::new("prog")
1435
    ///     .arg(Arg::new("cfg")
1436
    ///         .takes_value(true)
1437
    ///         .required_if_eq("other", "special")
1438
    ///         .long("config"))
1439
    ///     .arg(Arg::new("other")
1440
    ///         .long("other")
1441
    ///         .takes_value(true))
1442
    ///     .try_get_matches_from(vec![
1443
    ///         "prog", "--other", "not-special"
1444
    ///     ]);
1445
    ///
1446
    /// assert!(res.is_ok()); // We didn't use --other=special, so "cfg" wasn't required
1447
    ///
1448
    /// let res = App::new("prog")
1449
    ///     .arg(Arg::new("cfg")
1450
    ///         .takes_value(true)
1451
    ///         .required_if_eq("other", "special")
1452
    ///         .long("config"))
1453
    ///     .arg(Arg::new("other")
1454
    ///         .long("other")
1455
    ///         .takes_value(true))
1456
    ///     .try_get_matches_from(vec![
1457
    ///         "prog", "--other", "special"
1458
    ///     ]);
1459
    ///
1460
    /// // We did use --other=special so "cfg" had become required but was missing.
1461
    /// assert!(res.is_err());
1462
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1463
    /// ```
1464
    /// [`Arg::requires(name)`]: Arg::requires()
1465
    /// [Conflicting]: Arg::conflicts_with()
1466
    /// [required]: Arg::required()
1467
    pub fn required_if_eq<T: Key>(mut self, arg_id: T, val: &'help str) -> Self {
5✔
1468
        self.r_ifs.push((arg_id.into(), val));
5✔
1469
        self
5✔
1470
    }
1471

1472
    /// Allows specifying that this argument is [required] based on multiple conditions. The
1473
    /// conditions are set up in a `(arg, val)` style tuple. The requirement will only become valid
1474
    /// if one of the specified `arg`'s value equals its corresponding `val`.
1475
    ///
1476
    /// **NOTE:** If using YAML the values should be laid out as follows
1477
    ///
1478
    /// ```yaml
1479
    /// required_if_eq:
1480
    ///     - [arg, val]
1481
    ///     - [arg2, val2]
1482
    /// ```
1483
    ///
1484
    /// # Examples
1485
    ///
1486
    /// ```rust
1487
    /// # use clap::Arg;
1488
    /// Arg::new("config")
1489
    ///     .required_if_eq_any(&[
1490
    ///         ("extra", "val"),
1491
    ///         ("option", "spec")
1492
    ///     ])
1493
    /// # ;
1494
    /// ```
1495
    ///
1496
    /// Setting `Arg::required_if_eq_any(&[(arg, val)])` makes this arg required if any of the `arg`s
1497
    /// are used at runtime and it's corresponding value is equal to `val`. If the `arg`'s value is
1498
    /// anything other than `val`, this argument isn't required.
1499
    ///
1500
    /// ```rust
1501
    /// # use clap::{App, Arg};
1502
    /// let res = App::new("prog")
1503
    ///     .arg(Arg::new("cfg")
1504
    ///         .required_if_eq_any(&[
1505
    ///             ("extra", "val"),
1506
    ///             ("option", "spec")
1507
    ///         ])
1508
    ///         .takes_value(true)
1509
    ///         .long("config"))
1510
    ///     .arg(Arg::new("extra")
1511
    ///         .takes_value(true)
1512
    ///         .long("extra"))
1513
    ///     .arg(Arg::new("option")
1514
    ///         .takes_value(true)
1515
    ///         .long("option"))
1516
    ///     .try_get_matches_from(vec![
1517
    ///         "prog", "--option", "other"
1518
    ///     ]);
1519
    ///
1520
    /// assert!(res.is_ok()); // We didn't use --option=spec, or --extra=val so "cfg" isn't required
1521
    /// ```
1522
    ///
1523
    /// Setting `Arg::required_if_eq_any(&[(arg, val)])` and having any of the `arg`s used with its
1524
    /// value of `val` but *not* using this arg is an error.
1525
    ///
1526
    /// ```rust
1527
    /// # use clap::{App, Arg, ErrorKind};
1528
    /// let res = App::new("prog")
1529
    ///     .arg(Arg::new("cfg")
1530
    ///         .required_if_eq_any(&[
1531
    ///             ("extra", "val"),
1532
    ///             ("option", "spec")
1533
    ///         ])
1534
    ///         .takes_value(true)
1535
    ///         .long("config"))
1536
    ///     .arg(Arg::new("extra")
1537
    ///         .takes_value(true)
1538
    ///         .long("extra"))
1539
    ///     .arg(Arg::new("option")
1540
    ///         .takes_value(true)
1541
    ///         .long("option"))
1542
    ///     .try_get_matches_from(vec![
1543
    ///         "prog", "--option", "spec"
1544
    ///     ]);
1545
    ///
1546
    /// assert!(res.is_err());
1547
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1548
    /// ```
1549
    /// [`Arg::requires(name)`]: Arg::requires()
1550
    /// [Conflicting]: Arg::conflicts_with()
1551
    /// [required]: Arg::required()
1552
    pub fn required_if_eq_any<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
2✔
1553
        self.r_ifs
4✔
1554
            .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val)));
6✔
1555
        self
2✔
1556
    }
1557

1558
    /// Allows specifying that this argument is [required] based on multiple conditions. The
1559
    /// conditions are set up in a `(arg, val)` style tuple. The requirement will only become valid
1560
    /// if every one of the specified `arg`'s value equals its corresponding `val`.
1561
    ///
1562
    /// **NOTE:** If using YAML the values should be laid out as follows
1563
    ///
1564
    /// ```yaml
1565
    /// required_if_eq_all:
1566
    ///     - [arg, val]
1567
    ///     - [arg2, val2]
1568
    /// ```
1569
    ///
1570
    /// # Examples
1571
    ///
1572
    /// ```rust
1573
    /// # use clap::Arg;
1574
    /// Arg::new("config")
1575
    ///     .required_if_eq_all(&[
1576
    ///         ("extra", "val"),
1577
    ///         ("option", "spec")
1578
    ///     ])
1579
    /// # ;
1580
    /// ```
1581
    ///
1582
    /// Setting `Arg::required_if_eq_all(&[(arg, val)])` makes this arg required if all of the `arg`s
1583
    /// are used at runtime and every value is equal to its corresponding `val`. If the `arg`'s value is
1584
    /// anything other than `val`, this argument isn't required.
1585
    ///
1586
    /// ```rust
1587
    /// # use clap::{App, Arg};
1588
    /// let res = App::new("prog")
1589
    ///     .arg(Arg::new("cfg")
1590
    ///         .required_if_eq_all(&[
1591
    ///             ("extra", "val"),
1592
    ///             ("option", "spec")
1593
    ///         ])
1594
    ///         .takes_value(true)
1595
    ///         .long("config"))
1596
    ///     .arg(Arg::new("extra")
1597
    ///         .takes_value(true)
1598
    ///         .long("extra"))
1599
    ///     .arg(Arg::new("option")
1600
    ///         .takes_value(true)
1601
    ///         .long("option"))
1602
    ///     .try_get_matches_from(vec![
1603
    ///         "prog", "--option", "spec"
1604
    ///     ]);
1605
    ///
1606
    /// assert!(res.is_ok()); // We didn't use --option=spec --extra=val so "cfg" isn't required
1607
    /// ```
1608
    ///
1609
    /// Setting `Arg::required_if_eq_all(&[(arg, val)])` and having all of the `arg`s used with its
1610
    /// value of `val` but *not* using this arg is an error.
1611
    ///
1612
    /// ```rust
1613
    /// # use clap::{App, Arg, ErrorKind};
1614
    /// let res = App::new("prog")
1615
    ///     .arg(Arg::new("cfg")
1616
    ///         .required_if_eq_all(&[
1617
    ///             ("extra", "val"),
1618
    ///             ("option", "spec")
1619
    ///         ])
1620
    ///         .takes_value(true)
1621
    ///         .long("config"))
1622
    ///     .arg(Arg::new("extra")
1623
    ///         .takes_value(true)
1624
    ///         .long("extra"))
1625
    ///     .arg(Arg::new("option")
1626
    ///         .takes_value(true)
1627
    ///         .long("option"))
1628
    ///     .try_get_matches_from(vec![
1629
    ///         "prog", "--extra", "val", "--option", "spec"
1630
    ///     ]);
1631
    ///
1632
    /// assert!(res.is_err());
1633
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1634
    /// ```
1635
    /// [required]: Arg::required()
1636
    pub fn required_if_eq_all<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
2✔
1637
        self.r_ifs_all
4✔
1638
            .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val)));
6✔
1639
        self
2✔
1640
    }
1641

1642
    /// Sets multiple arguments by names that are required when this one is present I.e. when
1643
    /// using this argument, the following arguments *must* be present.
1644
    ///
1645
    /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required
1646
    /// by default.
1647
    ///
1648
    /// # Examples
1649
    ///
1650
    /// ```rust
1651
    /// # use clap::Arg;
1652
    /// Arg::new("config")
1653
    ///     .requires_all(&["input", "output"])
1654
    /// # ;
1655
    /// ```
1656
    ///
1657
    /// Setting `Arg::requires_all(&[arg, arg2])` requires that all the arguments be used at
1658
    /// runtime if the defining argument is used. If the defining argument isn't used, the other
1659
    /// argument isn't required
1660
    ///
1661
    /// ```rust
1662
    /// # use clap::{App, Arg};
1663
    /// let res = App::new("prog")
1664
    ///     .arg(Arg::new("cfg")
1665
    ///         .takes_value(true)
1666
    ///         .requires("input")
1667
    ///         .long("config"))
1668
    ///     .arg(Arg::new("input")
1669
    ///         .index(1))
1670
    ///     .arg(Arg::new("output")
1671
    ///         .index(2))
1672
    ///     .try_get_matches_from(vec![
1673
    ///         "prog"
1674
    ///     ]);
1675
    ///
1676
    /// assert!(res.is_ok()); // We didn't use cfg, so input and output weren't required
1677
    /// ```
1678
    ///
1679
    /// Setting `Arg::requires_all(&[arg, arg2])` and *not* supplying all the arguments is an
1680
    /// error.
1681
    ///
1682
    /// ```rust
1683
    /// # use clap::{App, Arg, ErrorKind};
1684
    /// let res = App::new("prog")
1685
    ///     .arg(Arg::new("cfg")
1686
    ///         .takes_value(true)
1687
    ///         .requires_all(&["input", "output"])
1688
    ///         .long("config"))
1689
    ///     .arg(Arg::new("input")
1690
    ///         .index(1))
1691
    ///     .arg(Arg::new("output")
1692
    ///         .index(2))
1693
    ///     .try_get_matches_from(vec![
1694
    ///         "prog", "--config", "file.conf", "in.txt"
1695
    ///     ]);
1696
    ///
1697
    /// assert!(res.is_err());
1698
    /// // We didn't use output
1699
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
1700
    /// ```
1701
    /// [Conflicting]: Arg::conflicts_with()
1702
    /// [override]: Arg::overrides_with()
1703
    pub fn requires_all<T: Key>(mut self, names: &[T]) -> Self {
2✔
1704
        self.requires.extend(names.iter().map(|s| (None, s.into())));
6✔
1705
        self
2✔
1706
    }
1707

1708
    /// Specifies the index of a positional argument **starting at** 1.
1709
    ///
1710
    /// **NOTE:** The index refers to position according to **other positional argument**. It does
1711
    /// not define position in the argument list as a whole.
1712
    ///
1713
    /// **NOTE:** This is only meant to be used for positional arguments and shouldn't to be used
1714
    /// with [`Arg::short`] or [`Arg::long`]. If they are defined, they will be ignored.
1715
    ///
1716
    /// **NOTE:** You can optionally leave off the `index` method, and the index will be
1717
    /// assigned in order of evaluation. Utilizing the `index` method allows for setting
1718
    /// indexes out of order
1719
    ///
1720
    /// **NOTE:** When utilized with [`Arg::multiple(true)`], only the **last** positional argument
1721
    /// may be defined as multiple (i.e. with the highest index)
1722
    ///
1723
    /// # Panics
1724
    ///
1725
    /// Although not in this method directly, [`App`] will [`panic!`] if indexes are skipped (such
1726
    /// as defining `index(1)` and `index(3)` but not `index(2)`, or a positional argument is
1727
    /// defined as multiple and is not the highest index
1728
    ///
1729
    /// # Examples
1730
    ///
1731
    /// ```rust
1732
    /// # use clap::{App, Arg};
1733
    /// Arg::new("config")
1734
    ///     .index(1)
1735
    /// # ;
1736
    /// ```
1737
    ///
1738
    /// ```rust
1739
    /// # use clap::{App, Arg};
1740
    /// let m = App::new("prog")
1741
    ///     .arg(Arg::new("mode")
1742
    ///         .index(1))
1743
    ///     .arg(Arg::new("debug")
1744
    ///         .long("debug"))
1745
    ///     .get_matches_from(vec![
1746
    ///         "prog", "--debug", "fast"
1747
    ///     ]);
1748
    ///
1749
    /// assert!(m.is_present("mode"));
1750
    /// assert_eq!(m.value_of("mode"), Some("fast")); // notice index(1) means "first positional"
1751
    ///                                               // *not* first argument
1752
    /// ```
1753
    /// [`Arg::short`]: Arg::short()
1754
    /// [`Arg::long`]: Arg::long()
1755
    /// [`Arg::multiple(true)`]: Arg::multiple()
1756
    /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html
1757
    #[inline]
1758
    pub fn index(mut self, idx: usize) -> Self {
11✔
1759
        self.index = Some(idx);
11✔
1760
        self
11✔
1761
    }
1762

1763
    /// Specifies a value that *stops* parsing multiple values of a give argument. By default when
1764
    /// one sets [`multiple(true)`] on an argument, clap will continue parsing values for that
1765
    /// argument until it reaches another valid argument, or one of the other more specific settings
1766
    /// for multiple values is used (such as [`min_values`], [`max_values`] or
1767
    /// [`number_of_values`]).
1768
    ///
1769
    /// **NOTE:** This setting only applies to [options] and [positional arguments]
1770
    ///
1771
    /// **NOTE:** When the terminator is passed in on the command line, it is **not** stored as one
1772
    /// of the values
1773
    ///
1774
    /// # Examples
1775
    ///
1776
    /// ```rust
1777
    /// # use clap::{App, Arg};
1778
    /// Arg::new("vals")
1779
    ///     .takes_value(true)
1780
    ///     .multiple(true)
1781
    ///     .value_terminator(";")
1782
    /// # ;
1783
    /// ```
1784
    /// The following example uses two arguments, a sequence of commands, and the location in which
1785
    /// to perform them
1786
    ///
1787
    /// ```rust
1788
    /// # use clap::{App, Arg};
1789
    /// let m = App::new("prog")
1790
    ///     .arg(Arg::new("cmds")
1791
    ///         .takes_value(true)
1792
    ///         .multiple(true)
1793
    ///         .allow_hyphen_values(true)
1794
    ///         .value_terminator(";"))
1795
    ///     .arg(Arg::new("location"))
1796
    ///     .get_matches_from(vec![
1797
    ///         "prog", "find", "-type", "f", "-name", "special", ";", "/home/clap"
1798
    ///     ]);
1799
    /// let cmds: Vec<_> = m.values_of("cmds").unwrap().collect();
1800
    /// assert_eq!(&cmds, &["find", "-type", "f", "-name", "special"]);
1801
    /// assert_eq!(m.value_of("location"), Some("/home/clap"));
1802
    /// ```
1803
    /// [options]: Arg::takes_value()
1804
    /// [positional arguments]: Arg::index()
1805
    /// [`multiple(true)`]: Arg::multiple()
1806
    /// [`min_values`]: Arg::min_values()
1807
    /// [`number_of_values`]: Arg::number_of_values()
1808
    /// [`max_values`]: Arg::max_values()
1809
    #[inline]
1810
    pub fn value_terminator(mut self, term: &'help str) -> Self {
1✔
1811
        self.terminator = Some(term);
2✔
1812
        self.takes_value(true)
2✔
1813
    }
1814

1815
    /// Specifies a list of possible values for this argument. At runtime, `clap` verifies that
1816
    /// only one of the specified values was used, or fails with an error message.
1817
    ///
1818
    /// **NOTE:** This setting only applies to [options] and [positional arguments]
1819
    ///
1820
    /// # Examples
1821
    ///
1822
    /// ```rust
1823
    /// # use clap::{App, Arg};
1824
    /// Arg::new("mode")
1825
    ///     .takes_value(true)
1826
    ///     .possible_values(&["fast", "slow", "medium"])
1827
    /// # ;
1828
    /// ```
1829
    ///
1830
    /// ```rust
1831
    /// # use clap::{App, Arg};
1832
    /// let m = App::new("prog")
1833
    ///     .arg(Arg::new("mode")
1834
    ///         .long("mode")
1835
    ///         .takes_value(true)
1836
    ///         .possible_values(&["fast", "slow", "medium"]))
1837
    ///     .get_matches_from(vec![
1838
    ///         "prog", "--mode", "fast"
1839
    ///     ]);
1840
    /// assert!(m.is_present("mode"));
1841
    /// assert_eq!(m.value_of("mode"), Some("fast"));
1842
    /// ```
1843
    ///
1844
    /// The next example shows a failed parse from using a value which wasn't defined as one of the
1845
    /// possible values.
1846
    ///
1847
    /// ```rust
1848
    /// # use clap::{App, Arg, ErrorKind};
1849
    /// let res = App::new("prog")
1850
    ///     .arg(Arg::new("mode")
1851
    ///         .long("mode")
1852
    ///         .takes_value(true)
1853
    ///         .possible_values(&["fast", "slow", "medium"]))
1854
    ///     .try_get_matches_from(vec![
1855
    ///         "prog", "--mode", "wrong"
1856
    ///     ]);
1857
    /// assert!(res.is_err());
1858
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::InvalidValue);
1859
    /// ```
1860
    /// [options]: Arg::takes_value()
1861
    /// [positional arguments]: Arg::index()
1862
    pub fn possible_values(mut self, names: &[&'help str]) -> Self {
15✔
1863
        self.possible_vals.extend(names);
15✔
1864
        self.takes_value(true)
15✔
1865
    }
1866

1867
    /// Specifies a possible value for this argument, one at a time. At runtime, `clap` verifies
1868
    /// that only one of the specified values was used, or fails with error message.
1869
    ///
1870
    /// **NOTE:** This setting only applies to [options] and [positional arguments]
1871
    ///
1872
    /// # Examples
1873
    ///
1874
    /// ```rust
1875
    /// # use clap::{App, Arg};
1876
    /// Arg::new("mode")
1877
    ///     .takes_value(true)
1878
    ///     .possible_value("fast")
1879
    ///     .possible_value("slow")
1880
    ///     .possible_value("medium")
1881
    /// # ;
1882
    /// ```
1883
    ///
1884
    /// ```rust
1885
    /// # use clap::{App, Arg};
1886
    /// let m = App::new("prog")
1887
    ///     .arg(Arg::new("mode")
1888
    ///         .long("mode")
1889
    ///         .takes_value(true)
1890
    ///         .possible_value("fast")
1891
    ///         .possible_value("slow")
1892
    ///         .possible_value("medium"))
1893
    ///     .get_matches_from(vec![
1894
    ///         "prog", "--mode", "fast"
1895
    ///     ]);
1896
    /// assert!(m.is_present("mode"));
1897
    /// assert_eq!(m.value_of("mode"), Some("fast"));
1898
    /// ```
1899
    ///
1900
    /// The next example shows a failed parse from using a value which wasn't defined as one of the
1901
    /// possible values.
1902
    ///
1903
    /// ```rust
1904
    /// # use clap::{App, Arg, ErrorKind};
1905
    /// let res = App::new("prog")
1906
    ///     .arg(Arg::new("mode")
1907
    ///         .long("mode")
1908
    ///         .takes_value(true)
1909
    ///         .possible_value("fast")
1910
    ///         .possible_value("slow")
1911
    ///         .possible_value("medium"))
1912
    ///     .try_get_matches_from(vec![
1913
    ///         "prog", "--mode", "wrong"
1914
    ///     ]);
1915
    /// assert!(res.is_err());
1916
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::InvalidValue);
1917
    /// ```
1918
    /// [options]: Arg::takes_value()
1919
    /// [positional arguments]: Arg::index()
1920
    pub fn possible_value(mut self, name: &'help str) -> Self {
6✔
1921
        self.possible_vals.push(name);
6✔
1922
        self.takes_value(true)
6✔
1923
    }
1924

1925
    /// Specifies the name of the [`ArgGroup`] the argument belongs to.
1926
    ///
1927
    /// # Examples
1928
    ///
1929
    /// ```rust
1930
    /// # use clap::{App, Arg};
1931
    /// Arg::new("debug")
1932
    ///     .long("debug")
1933
    ///     .group("mode")
1934
    /// # ;
1935
    /// ```
1936
    ///
1937
    /// Multiple arguments can be a member of a single group and then the group checked as if it
1938
    /// was one of said arguments.
1939
    ///
1940
    /// ```rust
1941
    /// # use clap::{App, Arg};
1942
    /// let m = App::new("prog")
1943
    ///     .arg(Arg::new("debug")
1944
    ///         .long("debug")
1945
    ///         .group("mode"))
1946
    ///     .arg(Arg::new("verbose")
1947
    ///         .long("verbose")
1948
    ///         .group("mode"))
1949
    ///     .get_matches_from(vec![
1950
    ///         "prog", "--debug"
1951
    ///     ]);
1952
    /// assert!(m.is_present("mode"));
1953
    /// ```
1954
    pub fn group<T: Key>(mut self, group_id: T) -> Self {
3✔
1955
        self.groups.push(group_id.into());
3✔
1956
        self
3✔
1957
    }
1958

1959
    /// Specifies the names of multiple [`ArgGroup`]'s the argument belongs to.
1960
    ///
1961
    /// # Examples
1962
    ///
1963
    /// ```rust
1964
    /// # use clap::{App, Arg};
1965
    /// Arg::new("debug")
1966
    ///     .long("debug")
1967
    ///     .groups(&["mode", "verbosity"])
1968
    /// # ;
1969
    /// ```
1970
    ///
1971
    /// Arguments can be members of multiple groups and then the group checked as if it
1972
    /// was one of said arguments.
1973
    ///
1974
    /// ```rust
1975
    /// # use clap::{App, Arg};
1976
    /// let m = App::new("prog")
1977
    ///     .arg(Arg::new("debug")
1978
    ///         .long("debug")
1979
    ///         .groups(&["mode", "verbosity"]))
1980
    ///     .arg(Arg::new("verbose")
1981
    ///         .long("verbose")
1982
    ///         .groups(&["mode", "verbosity"]))
1983
    ///     .get_matches_from(vec![
1984
    ///         "prog", "--debug"
1985
    ///     ]);
1986
    /// assert!(m.is_present("mode"));
1987
    /// assert!(m.is_present("verbosity"));
1988
    /// ```
1989
    pub fn groups<T: Key>(mut self, group_ids: &[T]) -> Self {
×
1990
        self.groups.extend(group_ids.iter().map(Id::from));
×
1991
        self
×
1992
    }
1993

1994
    /// Specifies how many values are required to satisfy this argument. For example, if you had a
1995
    /// `-f <file>` argument where you wanted exactly 3 'files' you would set
1996
    /// `.number_of_values(3)`, and this argument wouldn't be satisfied unless the user provided
1997
    /// 3 and only 3 values.
1998
    ///
1999
    /// **NOTE:** Does *not* require [`Arg::multiple(true)`] to be set. Setting
2000
    /// [`Arg::multiple(true)`] would allow `-f <file> <file> <file> -f <file> <file> <file>` where
2001
    /// as *not* setting [`Arg::multiple(true)`] would only allow one occurrence of this argument.
2002
    ///
2003
    /// # Examples
2004
    ///
2005
    /// ```rust
2006
    /// # use clap::{App, Arg};
2007
    /// Arg::new("file")
2008
    ///     .short('f')
2009
    ///     .number_of_values(3)
2010
    /// # ;
2011
    /// ```
2012
    ///
2013
    /// Not supplying the correct number of values is an error
2014
    ///
2015
    /// ```rust
2016
    /// # use clap::{App, Arg, ErrorKind};
2017
    /// let res = App::new("prog")
2018
    ///     .arg(Arg::new("file")
2019
    ///         .takes_value(true)
2020
    ///         .number_of_values(2)
2021
    ///         .short('F'))
2022
    ///     .try_get_matches_from(vec![
2023
    ///         "prog", "-F", "file1"
2024
    ///     ]);
2025
    ///
2026
    /// assert!(res.is_err());
2027
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::WrongNumberOfValues);
2028
    /// ```
2029
    /// [`Arg::multiple(true)`]: Arg::multiple()
2030
    #[inline]
2031
    pub fn number_of_values(mut self, qty: usize) -> Self {
6✔
2032
        self.num_vals = Some(qty);
6✔
2033
        self.takes_value(true).multiple_values(true)
6✔
2034
    }
2035

2036
    /// Allows one to perform a custom validation on the argument value. You provide a closure
2037
    /// which accepts a [`String`] value, and return a [`Result`] where the [`Err(String)`] is a
2038
    /// message displayed to the user.
2039
    ///
2040
    /// **NOTE:** The error message does *not* need to contain the `error:` portion, only the
2041
    /// message as all errors will appear as
2042
    /// `error: Invalid value for '<arg>': <YOUR MESSAGE>` where `<arg>` is replaced by the actual
2043
    /// arg, and `<YOUR MESSAGE>` is the `String` you return as the error.
2044
    ///
2045
    /// **NOTE:** There is a small performance hit for using validators, as they are implemented
2046
    /// with [`Arc`] pointers. And the value to be checked will be allocated an extra time in order
2047
    /// to be passed to the closure. This performance hit is extremely minimal in the grand
2048
    /// scheme of things.
2049
    ///
2050
    /// # Examples
2051
    ///
2052
    /// ```rust
2053
    /// # use clap::{App, Arg};
2054
    /// fn has_at(v: &str) -> Result<(), String> {
2055
    ///     if v.contains("@") { return Ok(()); }
2056
    ///     Err(String::from("The value did not contain the required @ sigil"))
2057
    /// }
2058
    /// let res = App::new("prog")
2059
    ///     .arg(Arg::new("file")
2060
    ///         .index(1)
2061
    ///         .validator(has_at))
2062
    ///     .try_get_matches_from(vec![
2063
    ///         "prog", "some@file"
2064
    ///     ]);
2065
    /// assert!(res.is_ok());
2066
    /// assert_eq!(res.unwrap().value_of("file"), Some("some@file"));
2067
    /// ```
2068
    /// [`String`]: std::string::String
2069
    /// [`Result`]: std::result::Result
2070
    /// [`Err(String)`]: std::result::Result::Err
2071
    /// [`Arc`]: std::sync::Arc
2072
    pub fn validator<F, O, E>(mut self, mut f: F) -> Self
88✔
2073
    where
2074
        F: FnMut(&str) -> Result<O, E> + Send + 'help,
2075
        E: Into<Box<dyn Error + Send + Sync + 'static>>,
2076
    {
2077
        self.validator = Some(Arc::new(Mutex::new(move |s: &str| {
164✔
2078
            f(s).map(|_| ()).map_err(|e| e.into())
94✔
2079
        })));
2080
        self
88✔
2081
    }
2082

2083
    /// Works identically to Validator but is intended to be used with values that could
2084
    /// contain non UTF-8 formatted strings.
2085
    ///
2086
    /// # Examples
2087
    ///
2088
    #[cfg_attr(not(unix), doc = " ```ignore")]
2089
    #[cfg_attr(unix, doc = " ```rust")]
2090
    /// # use clap::{App, Arg};
2091
    /// # use std::ffi::{OsStr, OsString};
2092
    /// # use std::os::unix::ffi::OsStrExt;
2093
    /// fn has_ampersand(v: &OsStr) -> Result<(), String> {
2094
    ///     if v.as_bytes().iter().any(|b| *b == b'&') { return Ok(()); }
2095
    ///     Err(String::from("The value did not contain the required & sigil"))
2096
    /// }
2097
    /// let res = App::new("prog")
2098
    ///     .arg(Arg::new("file")
2099
    ///         .index(1)
2100
    ///         .validator_os(has_ampersand))
2101
    ///     .try_get_matches_from(vec![
2102
    ///         "prog", "Fish & chips"
2103
    ///     ]);
2104
    /// assert!(res.is_ok());
2105
    /// assert_eq!(res.unwrap().value_of("file"), Some("Fish & chips"));
2106
    /// ```
2107
    /// [`String`]: std::string::String
2108
    /// [`OsStr`]: std::ffi::OsStr
2109
    /// [`OsString`]: std::ffi::OsString
2110
    /// [`Result`]: std::result::Result
2111
    /// [`Err(String)`]: std::result::Result::Err
2112
    /// [`Rc`]: std::rc::Rc
2113
    pub fn validator_os<F, O, E>(mut self, mut f: F) -> Self
3✔
2114
    where
2115
        F: FnMut(&OsStr) -> Result<O, E> + Send + 'help,
2116
        E: Into<Box<dyn Error + Send + Sync + 'static>>,
2117
    {
2118
        self.validator_os = Some(Arc::new(Mutex::new(move |s: &OsStr| {
5✔
2119
            f(s).map(|_| ()).map_err(|e| e.into())
2✔
2120
        })));
2121
        self
3✔
2122
    }
2123

2124
    /// Validates the argument via the given regular expression.
2125
    ///
2126
    /// As regular expressions are not very user friendly, the additional `err_message` should
2127
    /// describe the expected format in clear words. All notes for [`Arg::validator()`] regarding the
2128
    /// error message and performance also hold for `validator_regex`.
2129
    ///
2130
    /// The regular expression can either be borrowed or moved into `validator_regex`. This happens
2131
    /// automatically via [`RegexRef`]'s `Into` implementation.
2132
    ///
2133
    /// **NOTE:** If using YAML then a single vector with two entries should be provided:
2134
    /// ```yaml
2135
    /// validator_regex: [remove-all-files, needs the exact phrase 'remove-all-files' to continue]
2136
    /// ```
2137
    ///
2138
    /// # Performance
2139
    /// Regular expressions are expensive to compile. You should prefer sharing your regular expression.
2140
    /// We use a [`Cow`]-like internal structure to enable both sharing as well as taking ownership of a
2141
    /// provided regular expression.
2142
    ///
2143
    /// # Examples
2144
    /// You can use the classical `"\d+"` regular expression to match digits only:
2145
    /// ```rust
2146
    /// # use clap::{App, Arg};
2147
    /// use regex::Regex;
2148
    ///
2149
    /// let digits = Regex::new(r"\d+").unwrap();
2150
    ///
2151
    /// let res = App::new("prog")
2152
    ///     .arg(Arg::new("digits")
2153
    ///         .index(1)
2154
    ///         .validator_regex(&digits, "only digits are allowed"))
2155
    ///     .try_get_matches_from(vec![
2156
    ///         "prog", "12345"
2157
    ///     ]);
2158
    /// assert!(res.is_ok());
2159
    /// assert_eq!(res.unwrap().value_of("digits"), Some("12345"));
2160
    /// ```
2161
    /// However, any valid `Regex` can be used:
2162
    /// ```rust
2163
    /// # use clap::{App, Arg, ErrorKind};
2164
    /// use regex::Regex;
2165
    ///
2166
    /// let priority = Regex::new(r"[A-C]").unwrap();
2167
    ///
2168
    /// let res = App::new("prog")
2169
    ///     .arg(Arg::new("priority")
2170
    ///         .index(1)
2171
    ///         .validator_regex(priority, "only priorities A, B or C are allowed"))
2172
    ///     .try_get_matches_from(vec![
2173
    ///         "prog", "12345"
2174
    ///     ]);
2175
    /// assert!(res.is_err());
2176
    /// assert_eq!(res.err().unwrap().kind, ErrorKind::ValueValidation)
2177
    /// ```
2178
    #[cfg(feature = "regex")]
2179
    pub fn validator_regex(
1✔
2180
        self,
2181
        regex: impl Into<RegexRef<'help>>,
2182
        err_message: &'help str,
2183
    ) -> Self {
2184
        let regex = regex.into();
1✔
2185
        self.validator(move |s: &str| {
2✔
2186
            if regex.is_match(s) {
2✔
2187
                Ok(())
1✔
2188
            } else {
2189
                Err(err_message)
1✔
2190
            }
2191
        })
2192
    }
2193

2194
    /// Specifies the *maximum* number of values are for this argument. For example, if you had a
2195
    /// `-f <file>` argument where you wanted up to 3 'files' you would set `.max_values(3)`, and
2196
    /// this argument would be satisfied if the user provided, 1, 2, or 3 values.
2197
    ///
2198
    /// **NOTE:** This does *not* implicitly set [`Arg::multiple(true)`]. This is because
2199
    /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single
2200
    /// occurrence with multiple values. For positional arguments this **does** set
2201
    /// [`Arg::multiple(true)`] because there is no way to determine the difference between multiple
2202
    /// occurrences and multiple values.
2203
    ///
2204
    /// # Examples
2205
    ///
2206
    /// ```rust
2207
    /// # use clap::{App, Arg};
2208
    /// Arg::new("file")
2209
    ///     .short('f')
2210
    ///     .max_values(3)
2211
    /// # ;
2212
    /// ```
2213
    ///
2214
    /// Supplying less than the maximum number of values is allowed
2215
    ///
2216
    /// ```rust
2217
    /// # use clap::{App, Arg};
2218
    /// let res = App::new("prog")
2219
    ///     .arg(Arg::new("file")
2220
    ///         .takes_value(true)
2221
    ///         .max_values(3)
2222
    ///         .short('F'))
2223
    ///     .try_get_matches_from(vec![
2224
    ///         "prog", "-F", "file1", "file2"
2225
    ///     ]);
2226
    ///
2227
    /// assert!(res.is_ok());
2228
    /// let m = res.unwrap();
2229
    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
2230
    /// assert_eq!(files, ["file1", "file2"]);
2231
    /// ```
2232
    ///
2233
    /// Supplying more than the maximum number of values is an error
2234
    ///
2235
    /// ```rust
2236
    /// # use clap::{App, Arg, ErrorKind};
2237
    /// let res = App::new("prog")
2238
    ///     .arg(Arg::new("file")
2239
    ///         .takes_value(true)
2240
    ///         .max_values(2)
2241
    ///         .short('F'))
2242
    ///     .try_get_matches_from(vec![
2243
    ///         "prog", "-F", "file1", "file2", "file3"
2244
    ///     ]);
2245
    ///
2246
    /// assert!(res.is_err());
2247
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
2248
    /// ```
2249
    /// [`Arg::multiple(true)`]: Arg::multiple()
2250
    #[inline]
2251
    pub fn max_values(mut self, qty: usize) -> Self {
13✔
2252
        self.max_vals = Some(qty);
13✔
2253
        self.takes_value(true).multiple_values(true)
13✔
2254
    }
2255

2256
    /// Specifies the *minimum* number of values for this argument. For example, if you had a
2257
    /// `-f <file>` argument where you wanted at least 2 'files' you would set
2258
    /// `.min_values(2)`, and this argument would be satisfied if the user provided, 2 or more
2259
    /// values.
2260
    ///
2261
    /// **NOTE:** This does not implicitly set [`Arg::multiple(true)`]. This is because
2262
    /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single
2263
    /// occurrence with multiple values. For positional arguments this **does** set
2264
    /// [`Arg::multiple(true)`] because there is no way to determine the difference between multiple
2265
    /// occurrences and multiple values.
2266
    ///
2267
    /// # Examples
2268
    ///
2269
    /// ```rust
2270
    /// # use clap::{App, Arg};
2271
    /// Arg::new("file")
2272
    ///     .short('f')
2273
    ///     .min_values(3)
2274
    /// # ;
2275
    /// ```
2276
    ///
2277
    /// Supplying more than the minimum number of values is allowed
2278
    ///
2279
    /// ```rust
2280
    /// # use clap::{App, Arg};
2281
    /// let res = App::new("prog")
2282
    ///     .arg(Arg::new("file")
2283
    ///         .takes_value(true)
2284
    ///         .min_values(2)
2285
    ///         .short('F'))
2286
    ///     .try_get_matches_from(vec![
2287
    ///         "prog", "-F", "file1", "file2", "file3"
2288
    ///     ]);
2289
    ///
2290
    /// assert!(res.is_ok());
2291
    /// let m = res.unwrap();
2292
    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
2293
    /// assert_eq!(files, ["file1", "file2", "file3"]);
2294
    /// ```
2295
    ///
2296
    /// Supplying less than the minimum number of values is an error
2297
    ///
2298
    /// ```rust
2299
    /// # use clap::{App, Arg, ErrorKind};
2300
    /// let res = App::new("prog")
2301
    ///     .arg(Arg::new("file")
2302
    ///         .takes_value(true)
2303
    ///         .min_values(2)
2304
    ///         .short('F'))
2305
    ///     .try_get_matches_from(vec![
2306
    ///         "prog", "-F", "file1"
2307
    ///     ]);
2308
    ///
2309
    /// assert!(res.is_err());
2310
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::TooFewValues);
2311
    /// ```
2312
    /// [`Arg::multiple(true)`]: Arg::multiple()
2313
    #[inline]
2314
    pub fn min_values(mut self, qty: usize) -> Self {
16✔
2315
        self.min_vals = Some(qty);
16✔
2316
        self.takes_value(true).multiple_values(true)
16✔
2317
    }
2318

2319
    /// Specifies the separator to use when values are clumped together, defaults to `,` (comma).
2320
    ///
2321
    /// **NOTE:** implicitly sets [`Arg::use_delimiter(true)`]
2322
    ///
2323
    /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]
2324
    ///
2325
    /// # Examples
2326
    ///
2327
    /// ```rust
2328
    /// # use clap::{App, Arg};
2329
    /// let m = App::new("prog")
2330
    ///     .arg(Arg::new("config")
2331
    ///         .short('c')
2332
    ///         .long("config")
2333
    ///         .value_delimiter(";"))
2334
    ///     .get_matches_from(vec![
2335
    ///         "prog", "--config=val1;val2;val3"
2336
    ///     ]);
2337
    ///
2338
    /// assert_eq!(m.values_of("config").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"])
2339
    /// ```
2340
    /// [`Arg::use_delimiter(true)`]: Arg::use_delimiter()
2341
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2342
    #[inline]
2343
    pub fn value_delimiter(mut self, d: &str) -> Self {
2✔
2344
        self.val_delim = Some(
2✔
2345
            d.chars()
2✔
2346
                .next()
×
2347
                .expect("Failed to get value_delimiter from arg"),
×
2348
        );
2349
        self.takes_value(true).use_delimiter(true)
2✔
2350
    }
2351

2352
    /// Specify multiple names for values of option arguments. These names are cosmetic only, used
2353
    /// for help and usage strings only. The names are **not** used to access arguments. The values
2354
    /// of the arguments are accessed in numeric order (i.e. if you specify two names `one` and
2355
    /// `two` `one` will be the first matched value, `two` will be the second).
2356
    ///
2357
    /// This setting can be very helpful when describing the type of input the user should be
2358
    /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to
2359
    /// use all capital letters for the value name.
2360
    ///
2361
    /// **Pro Tip:** It may help to use [`Arg::next_line_help(true)`] if there are long, or
2362
    /// multiple value names in order to not throw off the help text alignment of all options.
2363
    ///
2364
    /// **NOTE:** This implicitly sets [`Arg::number_of_values`] if the number of value names is
2365
    /// greater than one. I.e. be aware that the number of "names" you set for the values, will be
2366
    /// the *exact* number of values required to satisfy this argument
2367
    ///
2368
    /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]
2369
    ///
2370
    /// **NOTE:** Does *not* require or imply [`Arg::multiple(true)`].
2371
    ///
2372
    /// # Examples
2373
    ///
2374
    /// ```rust
2375
    /// # use clap::{App, Arg};
2376
    /// Arg::new("speed")
2377
    ///     .short('s')
2378
    ///     .value_names(&["fast", "slow"])
2379
    /// # ;
2380
    /// ```
2381
    ///
2382
    /// ```rust
2383
    /// # use clap::{App, Arg};
2384
    /// let m = App::new("prog")
2385
    ///     .arg(Arg::new("io")
2386
    ///         .long("io-files")
2387
    ///         .value_names(&["INFILE", "OUTFILE"]))
2388
    ///     .get_matches_from(vec![
2389
    ///         "prog", "--help"
2390
    ///     ]);
2391
    /// ```
2392
    /// Running the above program produces the following output
2393
    ///
2394
    /// ```text
2395
    /// valnames
2396
    ///
2397
    /// USAGE:
2398
    ///    valnames [FLAGS] [OPTIONS]
2399
    ///
2400
    /// FLAGS:
2401
    ///     -h, --help       Prints help information
2402
    ///     -V, --version    Prints version information
2403
    ///
2404
    /// OPTIONS:
2405
    ///     --io-files <INFILE> <OUTFILE>    Some help text
2406
    /// ```
2407
    /// [`Arg::next_line_help(true)`]: Arg::next_line_help()
2408
    /// [`Arg::number_of_values`]: Arg::number_of_values()
2409
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2410
    /// [`Arg::multiple(true)`]: Arg::multiple()
2411
    pub fn value_names(mut self, names: &[&'help str]) -> Self {
1✔
2412
        let mut i = self.val_names.len();
1✔
2413
        for s in names {
2✔
2414
            self.val_names.insert(i, s);
1✔
2415
            i += 1;
1✔
2416
        }
2417

2418
        self.takes_value(true)
1✔
2419
    }
2420

2421
    /// Specifies the name for value of [option] or [positional] arguments inside of help
2422
    /// documentation. This name is cosmetic only, the name is **not** used to access arguments.
2423
    /// This setting can be very helpful when describing the type of input the user should be
2424
    /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to
2425
    /// use all capital letters for the value name.
2426
    ///
2427
    /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]
2428
    ///
2429
    /// # Examples
2430
    ///
2431
    /// ```rust
2432
    /// # use clap::{App, Arg};
2433
    /// Arg::new("cfg")
2434
    ///     .long("config")
2435
    ///     .value_name("FILE")
2436
    /// # ;
2437
    /// ```
2438
    ///
2439
    /// ```rust
2440
    /// # use clap::{App, Arg};
2441
    /// let m = App::new("prog")
2442
    ///     .arg(Arg::new("config")
2443
    ///         .long("config")
2444
    ///         .value_name("FILE")
2445
    ///         .about("Some help text"))
2446
    ///     .get_matches_from(vec![
2447
    ///         "prog", "--help"
2448
    ///     ]);
2449
    /// ```
2450
    /// Running the above program produces the following output
2451
    ///
2452
    /// ```text
2453
    /// valnames
2454
    ///
2455
    /// USAGE:
2456
    ///    valnames [FLAGS] [OPTIONS]
2457
    ///
2458
    /// FLAGS:
2459
    ///     -h, --help       Prints help information
2460
    ///     -V, --version    Prints version information
2461
    ///
2462
    /// OPTIONS:
2463
    ///     --config <FILE>     Some help text
2464
    /// ```
2465
    /// [option]: Arg::takes_value()
2466
    /// [positional]: Arg::index()
2467
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2468
    pub fn value_name(mut self, name: &'help str) -> Self {
7✔
2469
        let l = self.val_names.len();
7✔
2470
        self.val_names.insert(l, name);
7✔
2471
        self.takes_value(true)
7✔
2472
    }
2473

2474
    /// Specifies the value of the argument when *not* specified at runtime.
2475
    ///
2476
    /// **NOTE:** If the user *does not* use this argument at runtime, [`ArgMatches::occurrences_of`]
2477
    /// will return `0` even though the [`ArgMatches::value_of`] will return the default specified.
2478
    ///
2479
    /// **NOTE:** If the user *does not* use this argument at runtime [`ArgMatches::is_present`] will
2480
    /// still return `true`. If you wish to determine whether the argument was used at runtime or
2481
    /// not, consider [`ArgMatches::occurrences_of`] which will return `0` if the argument was *not*
2482
    /// used at runtime.
2483
    ///
2484
    /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value_if`] but slightly
2485
    /// different. `Arg::default_value` *only* takes affect when the user has not provided this arg
2486
    /// at runtime. `Arg::default_value_if` however only takes effect when the user has not provided
2487
    /// a value at runtime **and** these other conditions are met as well. If you have set
2488
    /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide this arg
2489
    /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value`
2490
    /// will be applied.
2491
    ///
2492
    /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
2493
    ///
2494
    /// **NOTE:** This setting effectively disables `AppSettings::ArgRequiredElseHelp` if used in
2495
    /// conjunction as it ensures that some argument will always be present.
2496
    ///
2497
    /// # Examples
2498
    ///
2499
    /// First we use the default value without providing any value at runtime.
2500
    ///
2501
    /// ```rust
2502
    /// # use clap::{App, Arg};
2503
    /// let m = App::new("prog")
2504
    ///     .arg(Arg::new("opt")
2505
    ///         .long("myopt")
2506
    ///         .default_value("myval"))
2507
    ///     .get_matches_from(vec![
2508
    ///         "prog"
2509
    ///     ]);
2510
    ///
2511
    /// assert_eq!(m.value_of("opt"), Some("myval"));
2512
    /// assert!(m.is_present("opt"));
2513
    /// assert_eq!(m.occurrences_of("opt"), 0);
2514
    /// ```
2515
    ///
2516
    /// Next we provide a value at runtime to override the default.
2517
    ///
2518
    /// ```rust
2519
    /// # use clap::{App, Arg};
2520
    /// let m = App::new("prog")
2521
    ///     .arg(Arg::new("opt")
2522
    ///         .long("myopt")
2523
    ///         .default_value("myval"))
2524
    ///     .get_matches_from(vec![
2525
    ///         "prog", "--myopt=non_default"
2526
    ///     ]);
2527
    ///
2528
    /// assert_eq!(m.value_of("opt"), Some("non_default"));
2529
    /// assert!(m.is_present("opt"));
2530
    /// assert_eq!(m.occurrences_of("opt"), 1);
2531
    /// ```
2532
    /// [`ArgMatches::occurrences_of`]: ArgMatches::occurrences_of()
2533
    /// [`ArgMatches::value_of`]: ArgMatches::value_of()
2534
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2535
    /// [`ArgMatches::is_present`]: ArgMatches::is_present()
2536
    /// [`Arg::default_value_if`]: Arg::default_value_if()
2537
    #[inline]
2538
    pub fn default_value(self, val: &'help str) -> Self {
20✔
2539
        self.default_values_os(&[OsStr::new(val)])
20✔
2540
    }
2541

2542
    /// Provides a default value in the exact same manner as [`Arg::default_value`]
2543
    /// only using [`OsStr`]s instead.
2544
    ///
2545
    /// [`Arg::default_value`]: Arg::default_value()
2546
    /// [`OsStr`]: std::ffi::OsStr
2547
    #[inline]
2548
    pub fn default_value_os(self, val: &'help OsStr) -> Self {
1✔
2549
        self.default_values_os(&[val])
1✔
2550
    }
2551

2552
    /// Like [`Arg::default_value`] but for args taking multiple values
2553
    ///
2554
    /// [`Arg::default_value`]: Arg::default_value()
2555
    #[inline]
2556
    pub fn default_values(self, vals: &[&'help str]) -> Self {
2✔
2557
        let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect();
6✔
2558
        self.default_values_os(&vals_vec[..])
2✔
2559
    }
2560

2561
    /// Provides default values in the exact same manner as [`Arg::default_values`]
2562
    /// only using [`OsStr`]s instead.
2563
    ///
2564
    /// [`Arg::default_values`]: Arg::default_values()
2565
    /// [`OsStr`]: std::ffi::OsStr
2566
    #[inline]
2567
    pub fn default_values_os(mut self, vals: &[&'help OsStr]) -> Self {
20✔
2568
        self.default_vals = vals.to_vec();
20✔
2569
        self.takes_value(true)
20✔
2570
    }
2571

2572
    /// Specifies a value for the argument when the argument is supplied and a value is required
2573
    /// but the value is *not* specified at runtime.
2574
    ///
2575
    /// This configuration option is often used to give the user a shortcut and allow them to
2576
    /// efficiently specify an option argument without requiring an explicitly value. The `--color`
2577
    /// argument is a common example. By, supplying an default, such as `default_missing_value("always")`,
2578
    /// the user can quickly just add `--color` to the command line to produce the desired color output.
2579
    ///
2580
    /// **NOTE:** using this configuration option requires the use of the `.min_values(0)` and the
2581
    /// `.require_equals(true)` configuration option. These are required in order to unambiguously
2582
    /// determine what, if any, value was supplied for the argument.
2583
    ///
2584
    /// # Examples
2585
    ///
2586
    /// Here is an implementation of the common POSIX style `--color` argument.
2587
    ///
2588
    /// ```rust
2589
    /// # use clap::{App, Arg};
2590
    ///
2591
    /// macro_rules! app {
2592
    ///     () => {{
2593
    ///         App::new("prog")
2594
    ///             .arg(Arg::new("color").long("color")
2595
    ///                 .value_name("WHEN")
2596
    ///                 .possible_values(&["always", "auto", "never"])
2597
    ///                 .default_value("auto")
2598
    ///                 .overrides_with("color")
2599
    ///                 .min_values(0)
2600
    ///                 .require_equals(true)
2601
    ///                 .default_missing_value("always")
2602
    ///                 .about("Specify WHEN to colorize output.")
2603
    ///             )
2604
    ///    }};
2605
    /// }
2606
    ///
2607
    /// let mut m;
2608
    ///
2609
    /// // first, we'll provide no arguments
2610
    ///
2611
    /// m  = app!().get_matches_from(vec![
2612
    ///         "prog"
2613
    ///     ]);
2614
    ///
2615
    /// assert_eq!(m.value_of("color"), Some("auto"));
2616
    /// assert!(m.is_present("color"));
2617
    /// assert_eq!(m.occurrences_of("color"), 0);
2618
    ///
2619
    /// // next, we'll provide a runtime value to override the default (as usually done).
2620
    ///
2621
    /// m  = app!().get_matches_from(vec![
2622
    ///         "prog", "--color=never"
2623
    ///     ]);
2624
    ///
2625
    /// assert_eq!(m.value_of("color"), Some("never"));
2626
    /// assert!(m.is_present("color"));
2627
    /// assert_eq!(m.occurrences_of("color"), 1);
2628
    ///
2629
    /// // finally, we will use the shortcut and only provide the argument without a value.
2630
    ///
2631
    /// m  = app!().get_matches_from(vec![
2632
    ///         "prog", "--color"
2633
    ///     ]);
2634
    ///
2635
    /// assert_eq!(m.value_of("color"), Some("always"));
2636
    /// assert!(m.is_present("color"));
2637
    /// assert_eq!(m.occurrences_of("color"), 1);
2638
    /// ```
2639
    /// [`ArgMatches::occurrences_of`]: ArgMatches::occurrences_of()
2640
    /// [`ArgMatches::value_of`]: ArgMatches::value_of()
2641
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2642
    /// [`ArgMatches::is_present`]: ArgMatches::is_present()
2643
    /// [`Arg::default_value`]: Arg::default_value()
2644
    #[inline]
2645
    pub fn default_missing_value(self, val: &'help str) -> Self {
3✔
2646
        self.default_missing_values_os(&[OsStr::new(val)])
3✔
2647
    }
2648

2649
    /// Provides a default value in the exact same manner as [`Arg::default_missing_value`]
2650
    /// only using [`OsStr`]s instead.
2651
    ///
2652
    /// [`Arg::default_missing_value`]: Arg::default_missing_value()
2653
    /// [`OsStr`]: std::ffi::OsStr
2654
    #[inline]
2655
    pub fn default_missing_value_os(self, val: &'help OsStr) -> Self {
×
2656
        self.default_missing_values_os(&[val])
×
2657
    }
2658

2659
    /// Like [`Arg::default_missing_value`] but for args taking multiple values
2660
    ///
2661
    /// [`Arg::default_missing_value`]: Arg::default_missing_value()
2662
    #[inline]
2663
    pub fn default_missing_values(self, vals: &[&'help str]) -> Self {
×
2664
        let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect();
×
2665
        self.default_missing_values_os(&vals_vec[..])
×
2666
    }
2667

2668
    /// Provides default values in the exact same manner as [`Arg::default_missing_values`]
2669
    /// only using [`OsStr`]s instead.
2670
    ///
2671
    /// [`Arg::default_missing_values`]: Arg::default_missing_values()
2672
    /// [`OsStr`]: std::ffi::OsStr
2673
    #[inline]
2674
    pub fn default_missing_values_os(mut self, vals: &[&'help OsStr]) -> Self {
3✔
2675
        self.default_missing_vals = vals.to_vec();
3✔
2676
        self.takes_value(true)
3✔
2677
    }
2678

2679
    /// Specifies the value of the argument if `arg` has been used at runtime. If `val` is set to
2680
    /// `None`, `arg` only needs to be present. If `val` is set to `"some-val"` then `arg` must be
2681
    /// present at runtime **and** have the value `val`.
2682
    ///
2683
    /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value`] but slightly
2684
    /// different. `Arg::default_value` *only* takes affect when the user has not provided this arg
2685
    /// at runtime. This setting however only takes affect when the user has not provided a value at
2686
    /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value`
2687
    /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were
2688
    /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied.
2689
    ///
2690
    /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
2691
    ///
2692
    /// **NOTE:** If using YAML the values should be laid out as follows (`None` can be represented
2693
    /// as `null` in YAML)
2694
    ///
2695
    /// ```yaml
2696
    /// default_value_if:
2697
    ///     - [arg, val, default]
2698
    /// ```
2699
    ///
2700
    /// # Examples
2701
    ///
2702
    /// First we use the default value only if another arg is present at runtime.
2703
    ///
2704
    /// ```rust
2705
    /// # use clap::{App, Arg};
2706
    /// let m = App::new("prog")
2707
    ///     .arg(Arg::new("flag")
2708
    ///         .long("flag"))
2709
    ///     .arg(Arg::new("other")
2710
    ///         .long("other")
2711
    ///         .default_value_if("flag", None, Some("default")))
2712
    ///     .get_matches_from(vec![
2713
    ///         "prog", "--flag"
2714
    ///     ]);
2715
    ///
2716
    /// assert_eq!(m.value_of("other"), Some("default"));
2717
    /// ```
2718
    ///
2719
    /// Next we run the same test, but without providing `--flag`.
2720
    ///
2721
    /// ```rust
2722
    /// # use clap::{App, Arg};
2723
    /// let m = App::new("prog")
2724
    ///     .arg(Arg::new("flag")
2725
    ///         .long("flag"))
2726
    ///     .arg(Arg::new("other")
2727
    ///         .long("other")
2728
    ///         .default_value_if("flag", None, Some("default")))
2729
    ///     .get_matches_from(vec![
2730
    ///         "prog"
2731
    ///     ]);
2732
    ///
2733
    /// assert_eq!(m.value_of("other"), None);
2734
    /// ```
2735
    ///
2736
    /// Now lets only use the default value if `--opt` contains the value `special`.
2737
    ///
2738
    /// ```rust
2739
    /// # use clap::{App, Arg};
2740
    /// let m = App::new("prog")
2741
    ///     .arg(Arg::new("opt")
2742
    ///         .takes_value(true)
2743
    ///         .long("opt"))
2744
    ///     .arg(Arg::new("other")
2745
    ///         .long("other")
2746
    ///         .default_value_if("opt", Some("special"), Some("default")))
2747
    ///     .get_matches_from(vec![
2748
    ///         "prog", "--opt", "special"
2749
    ///     ]);
2750
    ///
2751
    /// assert_eq!(m.value_of("other"), Some("default"));
2752
    /// ```
2753
    ///
2754
    /// We can run the same test and provide any value *other than* `special` and we won't get a
2755
    /// default value.
2756
    ///
2757
    /// ```rust
2758
    /// # use clap::{App, Arg};
2759
    /// let m = App::new("prog")
2760
    ///     .arg(Arg::new("opt")
2761
    ///         .takes_value(true)
2762
    ///         .long("opt"))
2763
    ///     .arg(Arg::new("other")
2764
    ///         .long("other")
2765
    ///         .default_value_if("opt", Some("special"), Some("default")))
2766
    ///     .get_matches_from(vec![
2767
    ///         "prog", "--opt", "hahaha"
2768
    ///     ]);
2769
    ///
2770
    /// assert_eq!(m.value_of("other"), None);
2771
    /// ```
2772
    ///
2773
    /// If we want to unset the default value for an Arg based on the presence or
2774
    /// value of some other Arg.
2775
    ///
2776
    /// ```rust
2777
    /// # use clap::{App, Arg};
2778
    /// let m = App::new("prog")
2779
    ///     .arg(Arg::new("flag")
2780
    ///         .long("flag"))
2781
    ///     .arg(Arg::new("other")
2782
    ///         .long("other")
2783
    ///         .default_value("default")
2784
    ///         .default_value_if("flag", None, None))
2785
    ///     .get_matches_from(vec![
2786
    ///         "prog", "--flag"
2787
    ///     ]);
2788
    ///
2789
    /// assert_eq!(m.value_of("other"), None);
2790
    /// ```
2791
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2792
    /// [`Arg::default_value`]: Arg::default_value()
2793
    pub fn default_value_if<T: Key>(
5✔
2794
        self,
2795
        arg_id: T,
2796
        val: Option<&'help str>,
2797
        default: Option<&'help str>,
2798
    ) -> Self {
2799
        self.default_value_if_os(arg_id, val.map(OsStr::new), default.map(OsStr::new))
5✔
2800
    }
2801

2802
    /// Provides a conditional default value in the exact same manner as [`Arg::default_value_if`]
2803
    /// only using [`OsStr`]s instead.
2804
    ///
2805
    /// [`Arg::default_value_if`]: Arg::default_value_if()
2806
    /// [`OsStr`]: std::ffi::OsStr
2807
    pub fn default_value_if_os<T: Key>(
7✔
2808
        mut self,
2809
        arg_id: T,
2810
        val: Option<&'help OsStr>,
2811
        default: Option<&'help OsStr>,
2812
    ) -> Self {
2813
        let l = self.default_vals_ifs.len();
7✔
2814
        self.default_vals_ifs
12✔
2815
            .insert(l, (arg_id.into(), val, default));
14✔
2816
        self.takes_value(true)
7✔
2817
    }
2818

2819
    /// Specifies multiple values and conditions in the same manner as [`Arg::default_value_if`].
2820
    /// The method takes a slice of tuples in the `(arg, Option<val>, default)` format.
2821
    ///
2822
    /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first
2823
    /// if multiple conditions are true, the first one found will be applied and the ultimate value.
2824
    ///
2825
    /// **NOTE:** If using YAML the values should be laid out as follows
2826
    ///
2827
    /// ```yaml
2828
    /// default_value_if:
2829
    ///     - [arg, val, default]
2830
    ///     - [arg2, null, default2]
2831
    /// ```
2832
    ///
2833
    /// # Examples
2834
    ///
2835
    /// First we use the default value only if another arg is present at runtime.
2836
    ///
2837
    /// ```rust
2838
    /// # use clap::{App, Arg};
2839
    /// let m = App::new("prog")
2840
    ///     .arg(Arg::new("flag")
2841
    ///         .long("flag"))
2842
    ///     .arg(Arg::new("opt")
2843
    ///         .long("opt")
2844
    ///         .takes_value(true))
2845
    ///     .arg(Arg::new("other")
2846
    ///         .long("other")
2847
    ///         .default_value_ifs(&[
2848
    ///             ("flag", None, Some("default")),
2849
    ///             ("opt", Some("channal"), Some("chan")),
2850
    ///         ]))
2851
    ///     .get_matches_from(vec![
2852
    ///         "prog", "--opt", "channal"
2853
    ///     ]);
2854
    ///
2855
    /// assert_eq!(m.value_of("other"), Some("chan"));
2856
    /// ```
2857
    ///
2858
    /// Next we run the same test, but without providing `--flag`.
2859
    ///
2860
    /// ```rust
2861
    /// # use clap::{App, Arg};
2862
    /// let m = App::new("prog")
2863
    ///     .arg(Arg::new("flag")
2864
    ///         .long("flag"))
2865
    ///     .arg(Arg::new("other")
2866
    ///         .long("other")
2867
    ///         .default_value_ifs(&[
2868
    ///             ("flag", None, Some("default")),
2869
    ///             ("opt", Some("channal"), Some("chan")),
2870
    ///         ]))
2871
    ///     .get_matches_from(vec![
2872
    ///         "prog"
2873
    ///     ]);
2874
    ///
2875
    /// assert_eq!(m.value_of("other"), None);
2876
    /// ```
2877
    ///
2878
    /// We can also see that these values are applied in order, and if more than one condition is
2879
    /// true, only the first evaluated "wins"
2880
    ///
2881
    /// ```rust
2882
    /// # use clap::{App, Arg};
2883
    /// let m = App::new("prog")
2884
    ///     .arg(Arg::new("flag")
2885
    ///         .long("flag"))
2886
    ///     .arg(Arg::new("opt")
2887
    ///         .long("opt")
2888
    ///         .takes_value(true))
2889
    ///     .arg(Arg::new("other")
2890
    ///         .long("other")
2891
    ///         .default_value_ifs(&[
2892
    ///             ("flag", None, Some("default")),
2893
    ///             ("opt", Some("channal"), Some("chan")),
2894
    ///         ]))
2895
    ///     .get_matches_from(vec![
2896
    ///         "prog", "--opt", "channal", "--flag"
2897
    ///     ]);
2898
    ///
2899
    /// assert_eq!(m.value_of("other"), Some("default"));
2900
    /// ```
2901
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
2902
    /// [`Arg::default_value_if`]: Arg::default_value_if()
2903
    pub fn default_value_ifs<T: Key>(
2✔
2904
        mut self,
2905
        ifs: &[(T, Option<&'help str>, Option<&'help str>)],
2906
    ) -> Self {
2907
        for (arg, val, default) in ifs {
4✔
2908
            self = self.default_value_if_os(arg, val.map(OsStr::new), default.map(OsStr::new));
2✔
2909
        }
2910
        self
4✔
2911
    }
2912

2913
    /// Provides multiple conditional default values in the exact same manner as
2914
    /// [`Arg::default_value_ifs`] only using [`OsStr`]s instead.
2915
    ///
2916
    /// [`Arg::default_value_ifs`]: Arg::default_value_ifs()
2917
    /// [`OsStr`]: std::ffi::OsStr
2918
    pub fn default_value_ifs_os<T: Key>(
×
2919
        mut self,
2920
        ifs: &[(T, Option<&'help OsStr>, Option<&'help OsStr>)],
2921
    ) -> Self {
2922
        for (arg, val, default) in ifs {
×
2923
            self = self.default_value_if_os(arg.key(), *val, *default);
×
2924
        }
2925
        self
×
2926
    }
2927

2928
    /// Specifies that if the value is not passed in as an argument, that it should be retrieved
2929
    /// from the environment, if available. If it is not present in the environment, then default
2930
    /// rules will apply.
2931
    ///
2932
    /// If user sets the argument in the environment:
2933
    /// - When [`Arg::takes_value(true)`] is not set, the flag is considered raised.
2934
    /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will
2935
    ///   return value of the environment variable.
2936
    ///
2937
    /// If user doesn't set the argument in the environment:
2938
    /// - When [`Arg::takes_value(true)`] is not set, the flag is considered off.
2939
    /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will
2940
    ///   return the default specified.
2941
    ///
2942
    /// # Examples
2943
    ///
2944
    /// In this example, we show the variable coming from the environment:
2945
    ///
2946
    /// ```rust
2947
    /// # use std::env;
2948
    /// # use clap::{App, Arg};
2949
    ///
2950
    /// env::set_var("MY_FLAG", "env");
2951
    ///
2952
    /// let m = App::new("prog")
2953
    ///     .arg(Arg::new("flag")
2954
    ///         .long("flag")
2955
    ///         .env("MY_FLAG")
2956
    ///         .takes_value(true))
2957
    ///     .get_matches_from(vec![
2958
    ///         "prog"
2959
    ///     ]);
2960
    ///
2961
    /// assert_eq!(m.value_of("flag"), Some("env"));
2962
    /// ```
2963
    ///
2964
    /// In this example, we show the flag being raised but with no value because
2965
    /// of not setting [`Arg::takes_value(true)`]:
2966
    ///
2967
    /// ```rust
2968
    /// # use std::env;
2969
    /// # use clap::{App, Arg};
2970
    ///
2971
    /// env::set_var("MY_FLAG", "env");
2972
    ///
2973
    /// let m = App::new("prog")
2974
    ///     .arg(Arg::new("flag")
2975
    ///         .long("flag")
2976
    ///         .env("MY_FLAG"))
2977
    ///     .get_matches_from(vec![
2978
    ///         "prog"
2979
    ///     ]);
2980
    ///
2981
    /// assert!(m.is_present("flag"));
2982
    /// assert_eq!(m.value_of("flag"), None);
2983
    /// ```
2984
    ///
2985
    /// In this example, we show the variable coming from an option on the CLI:
2986
    ///
2987
    /// ```rust
2988
    /// # use std::env;
2989
    /// # use clap::{App, Arg};
2990
    ///
2991
    /// env::set_var("MY_FLAG", "env");
2992
    ///
2993
    /// let m = App::new("prog")
2994
    ///     .arg(Arg::new("flag")
2995
    ///         .long("flag")
2996
    ///         .env("MY_FLAG")
2997
    ///         .takes_value(true))
2998
    ///     .get_matches_from(vec![
2999
    ///         "prog", "--flag", "opt"
3000
    ///     ]);
3001
    ///
3002
    /// assert_eq!(m.value_of("flag"), Some("opt"));
3003
    /// ```
3004
    ///
3005
    /// In this example, we show the variable coming from the environment even with the
3006
    /// presence of a default:
3007
    ///
3008
    /// ```rust
3009
    /// # use std::env;
3010
    /// # use clap::{App, Arg};
3011
    ///
3012
    /// env::set_var("MY_FLAG", "env");
3013
    ///
3014
    /// let m = App::new("prog")
3015
    ///     .arg(Arg::new("flag")
3016
    ///         .long("flag")
3017
    ///         .env("MY_FLAG")
3018
    ///         .takes_value(true)
3019
    ///         .default_value("default"))
3020
    ///     .get_matches_from(vec![
3021
    ///         "prog"
3022
    ///     ]);
3023
    ///
3024
    /// assert_eq!(m.value_of("flag"), Some("env"));
3025
    /// ```
3026
    ///
3027
    /// In this example, we show the use of multiple values in a single environment variable:
3028
    ///
3029
    /// ```rust
3030
    /// # use std::env;
3031
    /// # use clap::{App, Arg};
3032
    ///
3033
    /// env::set_var("MY_FLAG_MULTI", "env1,env2");
3034
    ///
3035
    /// let m = App::new("prog")
3036
    ///     .arg(Arg::new("flag")
3037
    ///         .long("flag")
3038
    ///         .env("MY_FLAG_MULTI")
3039
    ///         .takes_value(true)
3040
    ///         .multiple(true)
3041
    ///         .use_delimiter(true))
3042
    ///     .get_matches_from(vec![
3043
    ///         "prog"
3044
    ///     ]);
3045
    ///
3046
    /// assert_eq!(m.values_of("flag").unwrap().collect::<Vec<_>>(), vec!["env1", "env2"]);
3047
    /// ```
3048
    /// [`ArgMatches::occurrences_of`]: ArgMatches::occurrences_of()
3049
    /// [`ArgMatches::value_of`]: ArgMatches::value_of()
3050
    /// [`ArgMatches::is_present`]: ArgMatches::is_present()
3051
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
3052
    /// [`Arg::multiple(true)`]: Arg::multiple()
3053
    /// [`Arg::use_delimiter(true)`]: Arg::use_delimiter()
3054
    #[inline]
3055
    pub fn env(self, name: &'help str) -> Self {
6✔
3056
        self.env_os(OsStr::new(name))
7✔
3057
    }
3058

3059
    /// Specifies that if the value is not passed in as an argument, that it should be retrieved
3060
    /// from the environment if available in the exact same manner as [`Arg::env`] only using
3061
    /// [`OsStr`]s instead.
3062
    #[inline]
3063
    pub fn env_os(mut self, name: &'help OsStr) -> Self {
7✔
3064
        self.env = Some((name, env::var_os(name)));
7✔
3065
        self
7✔
3066
    }
3067

3068
    /// Allows custom ordering of args within the help message. Args with a lower value will be
3069
    /// displayed first in the help message. This is helpful when one would like to emphasise
3070
    /// frequently used args, or prioritize those towards the top of the list. Duplicate values
3071
    /// **are** allowed. Args with duplicate display orders will be displayed in alphabetical
3072
    /// order.
3073
    ///
3074
    /// **NOTE:** The default is 999 for all arguments.
3075
    ///
3076
    /// **NOTE:** This setting is ignored for [positional arguments] which are always displayed in
3077
    /// [index] order.
3078
    ///
3079
    /// # Examples
3080
    ///
3081
    /// ```rust
3082
    /// # use clap::{App, Arg};
3083
    /// let m = App::new("prog")
3084
    ///     .arg(Arg::new("a") // Typically args are grouped alphabetically by name.
3085
    ///                              // Args without a display_order have a value of 999 and are
3086
    ///                              // displayed alphabetically with all other 999 valued args.
3087
    ///         .long("long-option")
3088
    ///         .short('o')
3089
    ///         .takes_value(true)
3090
    ///         .about("Some help and text"))
3091
    ///     .arg(Arg::new("b")
3092
    ///         .long("other-option")
3093
    ///         .short('O')
3094
    ///         .takes_value(true)
3095
    ///         .display_order(1)   // In order to force this arg to appear *first*
3096
    ///                             // all we have to do is give it a value lower than 999.
3097
    ///                             // Any other args with a value of 1 will be displayed
3098
    ///                             // alphabetically with this one...then 2 values, then 3, etc.
3099
    ///         .about("I should be first!"))
3100
    ///     .get_matches_from(vec![
3101
    ///         "prog", "--help"
3102
    ///     ]);
3103
    /// ```
3104
    ///
3105
    /// The above example displays the following help message
3106
    ///
3107
    /// ```text
3108
    /// cust-ord
3109
    ///
3110
    /// USAGE:
3111
    ///     cust-ord [FLAGS] [OPTIONS]
3112
    ///
3113
    /// FLAGS:
3114
    ///     -h, --help       Prints help information
3115
    ///     -V, --version    Prints version information
3116
    ///
3117
    /// OPTIONS:
3118
    ///     -O, --other-option <b>    I should be first!
3119
    ///     -o, --long-option <a>     Some help and text
3120
    /// ```
3121
    /// [positional arguments]: Arg::index()
3122
    /// [index]: Arg::index()
3123
    #[inline]
3124
    pub fn display_order(mut self, ord: usize) -> Self {
3✔
3125
        self.disp_ord = ord;
3✔
3126
        self
3✔
3127
    }
3128

3129
    /// Specifies that this arg is the last, or final, positional argument (i.e. has the highest
3130
    /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args --
3131
    /// last_arg`). Even, if no other arguments are left to parse, if the user omits the `--` syntax
3132
    /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also
3133
    /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
3134
    /// the `--` syntax is otherwise not possible.
3135
    ///
3136
    /// **NOTE:** This will change the usage string to look like `$ prog [FLAGS] [-- <ARG>]` if
3137
    /// `ARG` is marked as `.last(true)`.
3138
    ///
3139
    /// **NOTE:** This setting will imply [`AppSettings::DontCollapseArgsInUsage`] because failing
3140
    /// to set this can make the usage string very confusing.
3141
    ///
3142
    /// **NOTE**: This setting only applies to positional arguments, and has no affect on FLAGS /
3143
    /// OPTIONS
3144
    ///
3145
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3146
    ///
3147
    /// **CAUTION:** Using this setting *and* having child subcommands is not
3148
    /// recommended with the exception of *also* using [`AppSettings::ArgsNegateSubcommands`]
3149
    /// (or [`AppSettings::SubcommandsNegateReqs`] if the argument marked `Last` is also
3150
    /// marked [`ArgSettings::Required`])
3151
    ///
3152
    /// # Examples
3153
    ///
3154
    /// ```rust
3155
    /// # use clap::{Arg, ArgSettings};
3156
    /// Arg::new("args")
3157
    ///     .setting(ArgSettings::TakesValue)
3158
    ///     .setting(ArgSettings::Last)
3159
    /// # ;
3160
    /// ```
3161
    ///
3162
    /// Setting [`ArgSettings::Last`] ensures the arg has the highest [index] of all positional args
3163
    /// and requires that the `--` syntax be used to access it early.
3164
    ///
3165
    /// ```rust
3166
    /// # use clap::{App, Arg, ArgSettings};
3167
    /// let res = App::new("prog")
3168
    ///     .arg(Arg::new("first"))
3169
    ///     .arg(Arg::new("second"))
3170
    ///     .arg(Arg::new("third")
3171
    ///         .setting(ArgSettings::TakesValue)
3172
    ///         .setting(ArgSettings::Last))
3173
    ///     .try_get_matches_from(vec![
3174
    ///         "prog", "one", "--", "three"
3175
    ///     ]);
3176
    ///
3177
    /// assert!(res.is_ok());
3178
    /// let m = res.unwrap();
3179
    /// assert_eq!(m.value_of("third"), Some("three"));
3180
    /// assert!(m.value_of("second").is_none());
3181
    /// ```
3182
    ///
3183
    /// Even if the positional argument marked `Last` is the only argument left to parse,
3184
    /// failing to use the `--` syntax results in an error.
3185
    ///
3186
    /// ```rust
3187
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
3188
    /// let res = App::new("prog")
3189
    ///     .arg(Arg::new("first"))
3190
    ///     .arg(Arg::new("second"))
3191
    ///     .arg(Arg::new("third")
3192
    ///         .setting(ArgSettings::TakesValue)
3193
    ///         .setting(ArgSettings::Last))
3194
    ///     .try_get_matches_from(vec![
3195
    ///         "prog", "one", "two", "three"
3196
    ///     ]);
3197
    ///
3198
    /// assert!(res.is_err());
3199
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
3200
    /// ```
3201
    /// [index]: Arg::index()
3202
    /// [`UnknownArgument`]: ErrorKind::UnknownArgument
3203
    #[inline]
3204
    pub fn last(self, l: bool) -> Self {
5✔
3205
        if l {
5✔
3206
            self.setting(ArgSettings::Last)
5✔
3207
        } else {
3208
            self.unset_setting(ArgSettings::Last)
1✔
3209
        }
3210
    }
3211

3212
    /// Specifies that the argument is required by default. Required by default means it is
3213
    /// required, when no other conflicting rules or overrides have been evaluated. Conflicting
3214
    /// rules take precedence over being required.
3215
    ///
3216
    /// **NOTE:** The default is `false`.
3217
    ///
3218
    /// **Pro tip:** Flags (i.e. not positional, or arguments that take values) shouldn't be
3219
    /// required by default. This is because if a flag were to be required, it should simply be
3220
    /// implied. No additional information is required from user. Flags by their very nature are
3221
    /// simply boolean on/off switches. The only time a user *should* be required to use a flag
3222
    /// is if the operation is destructive in nature, and the user is essentially proving to you,
3223
    /// "Yes, I know what I'm doing."
3224
    ///
3225
    /// # Examples
3226
    ///
3227
    /// ```rust
3228
    /// # use clap::{Arg, ArgSettings};
3229
    /// Arg::new("config")
3230
    ///     .required(true)  // equivalent to .setting(ArgSettings::Required)
3231
    /// # ;
3232
    /// ```
3233
    ///
3234
    /// Setting [`Required`] requires that the argument be used at runtime.
3235
    ///
3236
    /// ```rust
3237
    /// # use clap::{App, Arg, ArgSettings};
3238
    /// let res = App::new("prog")
3239
    ///     .arg(Arg::new("cfg")
3240
    ///         .setting(ArgSettings::Required)
3241
    ///         .setting(ArgSettings::TakesValue)
3242
    ///         .long("config"))
3243
    ///     .try_get_matches_from(vec![
3244
    ///         "prog", "--config", "file.conf",
3245
    ///     ]);
3246
    ///
3247
    /// assert!(res.is_ok());
3248
    /// ```
3249
    ///
3250
    /// Setting [`Required`] and then *not* supplying that argument at runtime is an error.
3251
    ///
3252
    /// ```rust
3253
    /// # use clap::{App, Arg, ArgSettings, ErrorKind};
3254
    /// let res = App::new("prog")
3255
    ///     .arg(Arg::new("cfg")
3256
    ///         .setting(ArgSettings::Required)
3257
    ///         .setting(ArgSettings::TakesValue)
3258
    ///         .long("config"))
3259
    ///     .try_get_matches_from(vec![
3260
    ///         "prog"
3261
    ///     ]);
3262
    ///
3263
    /// assert!(res.is_err());
3264
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
3265
    /// ```
3266
    /// [`Required`]: ArgSettings::Required
3267
    #[inline]
3268
    pub fn required(self, r: bool) -> Self {
34✔
3269
        if r {
35✔
3270
            self.setting(ArgSettings::Required)
33✔
3271
        } else {
3272
            self.unset_setting(ArgSettings::Required)
9✔
3273
        }
3274
    }
3275

3276
    /// Specifies that the argument takes a value at run time.
3277
    ///
3278
    /// **NOTE:** values for arguments may be specified in any of the following methods
3279
    ///
3280
    /// * Using a space such as `-o value` or `--option value`
3281
    /// * Using an equals and no space such as `-o=value` or `--option=value`
3282
    /// * Use a short and no space such as `-ovalue`
3283
    ///
3284
    /// **NOTE:** By default, args which allow [multiple values] are delimited by commas, meaning
3285
    /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to
3286
    /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`],
3287
    /// alternatively you can turn delimiting values **OFF** by using
3288
    /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter)`]
3289
    ///
3290
    /// # Examples
3291
    ///
3292
    /// ```rust
3293
    /// # use clap::{App, Arg, ArgSettings};
3294
    /// Arg::new("config")
3295
    ///     .setting(ArgSettings::TakesValue)
3296
    /// # ;
3297
    /// ```
3298
    ///
3299
    /// ```rust
3300
    /// # use clap::{App, Arg, ArgSettings};
3301
    /// let m = App::new("prog")
3302
    ///     .arg(Arg::new("mode")
3303
    ///         .long("mode")
3304
    ///         .setting(ArgSettings::TakesValue))
3305
    ///     .get_matches_from(vec![
3306
    ///         "prog", "--mode", "fast"
3307
    ///     ]);
3308
    ///
3309
    /// assert!(m.is_present("mode"));
3310
    /// assert_eq!(m.value_of("mode"), Some("fast"));
3311
    /// ```
3312
    /// [`Arg::value_delimiter(char)`]: Arg::value_delimiter()
3313
    /// [`Arg::unset_setting(ArgSettings::UseValueDelimiter)`]: ArgSettings::UseValueDelimiter
3314
    /// [multiple values]: ArgSettings::MultipleValues
3315
    #[inline]
3316
    pub fn takes_value(self, tv: bool) -> Self {
88✔
3317
        if tv {
113✔
3318
            self.setting(ArgSettings::TakesValue)
89✔
3319
        } else {
3320
            self.unset_setting(ArgSettings::TakesValue)
5✔
3321
        }
3322
    }
3323

3324
    /// Allows values which start with a leading hyphen (`-`)
3325
    ///
3326
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3327
    ///
3328
    /// **WARNING**: Take caution when using this setting combined with
3329
    /// [`ArgSettings::MultipleValues`], as this becomes ambiguous `$ prog --arg -- -- val`. All
3330
    /// three `--, --, val` will be values when the user may have thought the second `--` would
3331
    /// constitute the normal, "Only positional args follow" idiom. To fix this, consider using
3332
    /// [`ArgSettings::MultipleOccurrences`] which only allows a single value at a time.
3333
    ///
3334
    /// **WARNING**: When building your CLIs, consider the effects of allowing leading hyphens and
3335
    /// the user passing in a value that matches a valid short. For example, `prog -opt -F` where
3336
    /// `-F` is supposed to be a value, yet `-F` is *also* a valid short for another arg.
3337
    /// Care should be taken when designing these args. This is compounded by the ability to "stack"
3338
    /// short args. I.e. if `-val` is supposed to be a value, but `-v`, `-a`, and `-l` are all valid
3339
    /// shorts.
3340
    ///
3341
    /// # Examples
3342
    ///
3343
    /// ```rust
3344
    /// # use clap::{Arg, ArgSettings};
3345
    /// Arg::new("pattern")
3346
    ///     .setting(ArgSettings::TakesValue)
3347
    ///     .setting(ArgSettings::AllowHyphenValues)
3348
    /// # ;
3349
    /// ```
3350
    ///
3351
    /// ```rust
3352
    /// # use clap::{App, Arg, ArgSettings};
3353
    /// let m = App::new("prog")
3354
    ///     .arg(Arg::new("pat")
3355
    ///         .setting(ArgSettings::TakesValue)
3356
    ///         .setting(ArgSettings::AllowHyphenValues)
3357
    ///         .long("pattern"))
3358
    ///     .get_matches_from(vec![
3359
    ///         "prog", "--pattern", "-file"
3360
    ///     ]);
3361
    ///
3362
    /// assert_eq!(m.value_of("pat"), Some("-file"));
3363
    /// ```
3364
    ///
3365
    /// Not setting `Arg::allow_hyphen_values(true)` and supplying a value which starts with a
3366
    /// hyphen is an error.
3367
    ///
3368
    /// ```rust
3369
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
3370
    /// let res = App::new("prog")
3371
    ///     .arg(Arg::new("pat")
3372
    ///         .setting(ArgSettings::TakesValue)
3373
    ///         .long("pattern"))
3374
    ///     .try_get_matches_from(vec![
3375
    ///         "prog", "--pattern", "-file"
3376
    ///     ]);
3377
    ///
3378
    /// assert!(res.is_err());
3379
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
3380
    /// ```
3381
    /// [`Arg::number_of_values(1)`]: Arg::number_of_values()
3382
    #[inline]
3383
    pub fn allow_hyphen_values(self, a: bool) -> Self {
2✔
3384
        if a {
2✔
3385
            self.setting(ArgSettings::AllowHyphenValues)
2✔
3386
        } else {
3387
            self.unset_setting(ArgSettings::AllowHyphenValues)
1✔
3388
        }
3389
    }
3390

3391
    /// Requires that options use the `--option=val` syntax (i.e. an equals between the option and
3392
    /// associated value) **Default:** `false`
3393
    ///
3394
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3395
    ///
3396
    /// # Examples
3397
    ///
3398
    /// ```rust
3399
    /// # use clap::{Arg, ArgSettings};
3400
    /// Arg::new("config")
3401
    ///     .long("config")
3402
    ///     .setting(ArgSettings::TakesValue)
3403
    ///     .setting(ArgSettings::RequireEquals)
3404
    /// # ;
3405
    /// ```
3406
    ///
3407
    /// Setting [`RequireEquals`] requires that the option have an equals sign between
3408
    /// it and the associated value.
3409
    ///
3410
    /// ```rust
3411
    /// # use clap::{App, Arg, ArgSettings};
3412
    /// let res = App::new("prog")
3413
    ///     .arg(Arg::new("cfg")
3414
    ///         .setting(ArgSettings::TakesValue)
3415
    ///         .setting(ArgSettings::RequireEquals)
3416
    ///         .long("config"))
3417
    ///     .try_get_matches_from(vec![
3418
    ///         "prog", "--config=file.conf"
3419
    ///     ]);
3420
    ///
3421
    /// assert!(res.is_ok());
3422
    /// ```
3423
    ///
3424
    /// Setting [`RequireEquals`] and *not* supplying the equals will cause an
3425
    /// error.
3426
    ///
3427
    /// ```rust
3428
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
3429
    /// let res = App::new("prog")
3430
    ///     .arg(Arg::new("cfg")
3431
    ///         .setting(ArgSettings::TakesValue)
3432
    ///         .setting(ArgSettings::RequireEquals)
3433
    ///         .long("config"))
3434
    ///     .try_get_matches_from(vec![
3435
    ///         "prog", "--config", "file.conf"
3436
    ///     ]);
3437
    ///
3438
    /// assert!(res.is_err());
3439
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::NoEquals);
3440
    /// ```
3441
    /// [`RequireEquals`]: ArgSettings::RequireEquals
3442
    #[inline]
3443
    pub fn require_equals(self, r: bool) -> Self {
6✔
3444
        if r {
6✔
3445
            self.setting(ArgSettings::RequireEquals)
6✔
3446
        } else {
3447
            self.unset_setting(ArgSettings::RequireEquals)
×
3448
        }
3449
    }
3450

3451
    /// Specifies that an argument can be matched to all child [``]s.
3452
    ///
3453
    /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however
3454
    /// their values once a user uses them will be propagated back up to parents. In effect, this
3455
    /// means one should *define* all global arguments at the top level, however it doesn't matter
3456
    /// where the user *uses* the global argument.
3457
    ///
3458
    /// # Examples
3459
    ///
3460
    /// ```rust
3461
    /// # use clap::{App, Arg, ArgSettings};
3462
    /// Arg::new("debug")
3463
    ///     .short('d')
3464
    ///     .global(true)
3465
    /// # ;
3466
    /// ```
3467
    ///
3468
    /// For example, assume an appliction with two subcommands, and you'd like to define a
3469
    /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't
3470
    /// want to clutter the source with three duplicate [`Arg`] definitions.
3471
    ///
3472
    /// ```rust
3473
    /// # use clap::{App, Arg, ArgSettings};
3474
    /// let m = App::new("prog")
3475
    ///     .arg(Arg::new("verb")
3476
    ///         .long("verbose")
3477
    ///         .short('v')
3478
    ///         .global(true))
3479
    ///     .subcommand(App::new("test"))
3480
    ///     .subcommand(App::new("do-stuff"))
3481
    ///     .get_matches_from(vec![
3482
    ///         "prog", "do-stuff", "--verbose"
3483
    ///     ]);
3484
    ///
3485
    /// assert_eq!(m.subcommand_name(), Some("do-stuff"));
3486
    /// let sub_m = m.subcommand_matches("do-stuff").unwrap();
3487
    /// assert!(sub_m.is_present("verb"));
3488
    /// ```
3489
    /// [``]: App::subcommand()
3490
    /// [required]: ArgSettings::Required
3491
    /// [`ArgMatches::is_present("flag")`]: ArgMatches::is_present()
3492
    #[inline]
3493
    pub fn global(mut self, g: bool) -> Self {
123✔
3494
        self.global = g;
123✔
3495
        self
123✔
3496
    }
3497

3498
    /// Specifies that *multiple values* may only be set using the delimiter. This means if an
3499
    /// if an option is encountered, and no delimiter is found, it automatically assumed that no
3500
    /// additional values for that option follow. This is unlike the default, where it is generally
3501
    /// assumed that more values will follow regardless of whether or not a delimiter is used.
3502
    ///
3503
    /// **NOTE:** The default is `false`.
3504
    ///
3505
    /// **NOTE:** Setting this requires [`ArgSettings::UseValueDelimiter`] and
3506
    /// [`ArgSettings::TakesValue`]
3507
    ///
3508
    /// **NOTE:** It's a good idea to inform the user that use of a delimiter is required, either
3509
    /// through help text or other means.
3510
    ///
3511
    /// # Examples
3512
    ///
3513
    /// These examples demonstrate what happens when `require_delimiter(true)` is used. Notice
3514
    /// everything works in this first example, as we use a delimiter, as expected.
3515
    ///
3516
    /// ```rust
3517
    /// # use clap::{App, Arg, ArgSettings};
3518
    /// let delims = App::new("prog")
3519
    ///     .arg(Arg::new("opt")
3520
    ///         .short('o')
3521
    ///         .setting(ArgSettings::TakesValue)
3522
    ///         .setting(ArgSettings::UseValueDelimiter)
3523
    ///         .setting(ArgSettings::RequireDelimiter)
3524
    ///         .setting(ArgSettings::MultipleValues))
3525
    ///     .get_matches_from(vec![
3526
    ///         "prog", "-o", "val1,val2,val3",
3527
    ///     ]);
3528
    ///
3529
    /// assert!(delims.is_present("opt"));
3530
    /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
3531
    /// ```
3532
    /// In this next example, we will *not* use a delimiter. Notice it's now an error.
3533
    ///
3534
    /// ```rust
3535
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
3536
    /// let res = App::new("prog")
3537
    ///     .arg(Arg::new("opt")
3538
    ///         .short('o')
3539
    ///         .setting(ArgSettings::TakesValue)
3540
    ///         .setting(ArgSettings::UseValueDelimiter)
3541
    ///         .setting(ArgSettings::RequireDelimiter))
3542
    ///     .try_get_matches_from(vec![
3543
    ///         "prog", "-o", "val1", "val2", "val3",
3544
    ///     ]);
3545
    ///
3546
    /// assert!(res.is_err());
3547
    /// let err = res.unwrap_err();
3548
    /// assert_eq!(err.kind, ErrorKind::UnknownArgument);
3549
    /// ```
3550
    /// What's happening is `-o` is getting `val1`, and because delimiters are required yet none
3551
    /// were present, it stops parsing `-o`. At this point it reaches `val2` and because no
3552
    /// positional arguments have been defined, it's an error of an unexpected argument.
3553
    ///
3554
    /// In this final example, we contrast the above with `clap`'s default behavior where the above
3555
    /// is *not* an error.
3556
    ///
3557
    /// ```rust
3558
    /// # use clap::{App, Arg, ArgSettings};
3559
    /// let delims = App::new("prog")
3560
    ///     .arg(Arg::new("opt")
3561
    ///         .short('o')
3562
    ///         .setting(ArgSettings::TakesValue)
3563
    ///         .setting(ArgSettings::MultipleValues))
3564
    ///     .get_matches_from(vec![
3565
    ///         "prog", "-o", "val1", "val2", "val3",
3566
    ///     ]);
3567
    ///
3568
    /// assert!(delims.is_present("opt"));
3569
    /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
3570
    /// ```
3571
    #[inline]
3572
    pub fn require_delimiter(self, d: bool) -> Self {
7✔
3573
        if d {
9✔
3574
            self.setting(ArgSettings::RequireDelimiter)
7✔
3575
        } else {
3576
            self.unset_setting(ArgSettings::RequireDelimiter)
×
3577
        }
3578
    }
3579

3580
    /// Specifies if the possible values of an argument should be displayed in the help text or
3581
    /// not. Defaults to `false` (i.e. show possible values)
3582
    ///
3583
    /// This is useful for args with many values, or ones which are explained elsewhere in the
3584
    /// help text.
3585
    ///
3586
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3587
    ///
3588
    /// # Examples
3589
    ///
3590
    /// ```rust
3591
    /// # use clap::{App, Arg, ArgSettings};
3592
    /// Arg::new("config")
3593
    ///     .setting(ArgSettings::TakesValue)
3594
    ///     .setting(ArgSettings::HidePossibleValues)
3595
    /// # ;
3596
    /// ```
3597
    ///
3598
    /// ```rust
3599
    /// # use clap::{App, Arg, ArgSettings};
3600
    /// let m = App::new("prog")
3601
    ///     .arg(Arg::new("mode")
3602
    ///         .long("mode")
3603
    ///         .possible_values(&["fast", "slow"])
3604
    ///         .setting(ArgSettings::TakesValue)
3605
    ///         .setting(ArgSettings::HidePossibleValues));
3606
    /// ```
3607
    /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of
3608
    /// the help text would be omitted.
3609
    #[inline]
3610
    pub fn hide_possible_values(self, hide: bool) -> Self {
1✔
3611
        if hide {
1✔
3612
            self.setting(ArgSettings::HidePossibleValues)
1✔
3613
        } else {
3614
            self.unset_setting(ArgSettings::HidePossibleValues)
×
3615
        }
3616
    }
3617

3618
    /// Specifies that the default value of an argument should not be displayed in the help text.
3619
    ///
3620
    /// This is useful when default behavior of an arg is explained elsewhere in the help text.
3621
    ///
3622
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3623
    ///
3624
    /// # Examples
3625
    ///
3626
    /// ```rust
3627
    /// # use clap::{App, Arg, ArgSettings};
3628
    /// Arg::new("config")
3629
    ///     .setting(ArgSettings::TakesValue)
3630
    ///     .setting(ArgSettings::HideDefaultValue)
3631
    /// # ;
3632
    /// ```
3633
    ///
3634
    /// ```rust
3635
    /// # use clap::{App, Arg, ArgSettings};
3636
    /// let m = App::new("connect")
3637
    ///     .arg(Arg::new("host")
3638
    ///         .long("host")
3639
    ///         .default_value("localhost")
3640
    ///         .setting(ArgSettings::TakesValue)
3641
    ///         .setting(ArgSettings::HideDefaultValue));
3642
    ///
3643
    /// ```
3644
    ///
3645
    /// If we were to run the above program with `--help` the `[default: localhost]` portion of
3646
    /// the help text would be omitted.
3647
    #[inline]
3648
    pub fn hide_default_value(self, hide: bool) -> Self {
1✔
3649
        if hide {
1✔
3650
            self.setting(ArgSettings::HideDefaultValue)
1✔
3651
        } else {
3652
            self.unset_setting(ArgSettings::HideDefaultValue)
×
3653
        }
3654
    }
3655

3656
    /// Hides an argument from help message output.
3657
    ///
3658
    /// **NOTE:** This does **not** hide the argument from usage strings on error
3659
    ///
3660
    /// # Examples
3661
    ///
3662
    /// ```rust
3663
    /// # use clap::{App, Arg, ArgSettings};
3664
    /// Arg::new("debug")
3665
    ///     .setting(ArgSettings::Hidden)
3666
    /// # ;
3667
    /// ```
3668
    /// Setting `Hidden` will hide the argument when displaying help text
3669
    ///
3670
    /// ```rust
3671
    /// # use clap::{App, Arg, ArgSettings};
3672
    /// let m = App::new("prog")
3673
    ///     .arg(Arg::new("cfg")
3674
    ///         .long("config")
3675
    ///         .setting(ArgSettings::Hidden)
3676
    ///         .about("Some help text describing the --config arg"))
3677
    ///     .get_matches_from(vec![
3678
    ///         "prog", "--help"
3679
    ///     ]);
3680
    /// ```
3681
    ///
3682
    /// The above example displays
3683
    ///
3684
    /// ```text
3685
    /// helptest
3686
    ///
3687
    /// USAGE:
3688
    ///    helptest [FLAGS]
3689
    ///
3690
    /// FLAGS:
3691
    /// -h, --help       Prints help information
3692
    /// -V, --version    Prints version information
3693
    /// ```
3694
    #[inline]
3695
    pub fn hidden(self, h: bool) -> Self {
2✔
3696
        if h {
2✔
3697
            self.setting(ArgSettings::Hidden)
2✔
3698
        } else {
3699
            self.unset_setting(ArgSettings::Hidden)
×
3700
        }
3701
    }
3702

3703
    /// When used with [`Arg::possible_values`] it allows the argument value to pass validation even
3704
    /// if the case differs from that of the specified `possible_value`.
3705
    ///
3706
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3707
    ///
3708
    /// # Examples
3709
    ///
3710
    /// ```rust
3711
    /// # use clap::{App, Arg, ArgSettings};
3712
    /// let m = App::new("pv")
3713
    ///     .arg(Arg::new("option")
3714
    ///         .long("--option")
3715
    ///         .setting(ArgSettings::TakesValue)
3716
    ///         .setting(ArgSettings::IgnoreCase)
3717
    ///         .possible_value("test123"))
3718
    ///     .get_matches_from(vec![
3719
    ///         "pv", "--option", "TeSt123",
3720
    ///     ]);
3721
    ///
3722
    /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
3723
    /// ```
3724
    ///
3725
    /// This setting also works when multiple values can be defined:
3726
    ///
3727
    /// ```rust
3728
    /// # use clap::{App, Arg, ArgSettings};
3729
    /// let m = App::new("pv")
3730
    ///     .arg(Arg::new("option")
3731
    ///         .short('o')
3732
    ///         .long("--option")
3733
    ///         .setting(ArgSettings::IgnoreCase)
3734
    ///         .setting(ArgSettings::TakesValue)
3735
    ///         .setting(ArgSettings::MultipleValues)
3736
    ///         .possible_value("test123")
3737
    ///         .possible_value("test321"))
3738
    ///     .get_matches_from(vec![
3739
    ///         "pv", "--option", "TeSt123", "teST123", "tESt321"
3740
    ///     ]);
3741
    ///
3742
    /// let matched_vals = m.values_of("option").unwrap().collect::<Vec<_>>();
3743
    /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
3744
    /// ```
3745
    #[inline]
3746
    pub fn case_insensitive(self, ci: bool) -> Self {
4✔
3747
        if ci {
6✔
3748
            self.setting(ArgSettings::IgnoreCase)
4✔
3749
        } else {
3750
            self.unset_setting(ArgSettings::IgnoreCase)
1✔
3751
        }
3752
    }
3753

3754
    /// Specifies that an argument should allow grouping of multiple values via a
3755
    /// delimiter. I.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`,
3756
    /// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the
3757
    /// value delimiter for all arguments that accept values (options and positional arguments)
3758
    ///
3759
    /// **NOTE:** When this setting is used, it will default [`Arg::value_delimiter`]
3760
    /// to the comma `,`.
3761
    ///
3762
    /// **NOTE:** Implicitly sets [`ArgSettings::TakesValue`]
3763
    ///
3764
    /// # Examples
3765
    ///
3766
    /// The following example shows the default behavior.
3767
    ///
3768
    /// ```rust
3769
    /// # use clap::{App, Arg, ArgSettings};
3770
    /// let delims = App::new("prog")
3771
    ///     .arg(Arg::new("option")
3772
    ///         .long("option")
3773
    ///         .setting(ArgSettings::UseValueDelimiter)
3774
    ///         .takes_value(true))
3775
    ///     .get_matches_from(vec![
3776
    ///         "prog", "--option=val1,val2,val3",
3777
    ///     ]);
3778
    ///
3779
    /// assert!(delims.is_present("option"));
3780
    /// assert_eq!(delims.occurrences_of("option"), 1);
3781
    /// assert_eq!(delims.values_of("option").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
3782
    /// ```
3783
    /// The next example shows the difference when turning delimiters off. This is the default
3784
    /// behavior
3785
    ///
3786
    /// ```rust
3787
    /// # use clap::{App, Arg, ArgSettings};
3788
    /// let nodelims = App::new("prog")
3789
    ///     .arg(Arg::new("option")
3790
    ///         .long("option")
3791
    ///         .setting(ArgSettings::TakesValue))
3792
    ///     .get_matches_from(vec![
3793
    ///         "prog", "--option=val1,val2,val3",
3794
    ///     ]);
3795
    ///
3796
    /// assert!(nodelims.is_present("option"));
3797
    /// assert_eq!(nodelims.occurrences_of("option"), 1);
3798
    /// assert_eq!(nodelims.value_of("option").unwrap(), "val1,val2,val3");
3799
    /// ```
3800
    /// [`Arg::value_delimiter`]: Arg::value_delimiter()
3801
    #[inline]
3802
    pub fn use_delimiter(mut self, d: bool) -> Self {
11✔
3803
        if d {
13✔
3804
            if self.val_delim.is_none() {
11✔
3805
                self.val_delim = Some(',');
11✔
3806
            }
3807
            self.takes_value(true)
13✔
3808
                .setting(ArgSettings::UseValueDelimiter)
2✔
3809
        } else {
3810
            self.val_delim = None;
2✔
3811
            self.unset_setting(ArgSettings::UseValueDelimiter)
2✔
3812
        }
3813
    }
3814

3815
    /// Specifies that environment variable arguments should not be displayed in the help text.
3816
    ///
3817
    /// This is useful when the variable option is explained elsewhere in the help text.
3818
    ///
3819
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3820
    ///
3821
    /// # Examples
3822
    ///
3823
    /// ```rust
3824
    /// # use clap::{App, Arg, ArgSettings};
3825
    /// Arg::new("config")
3826
    ///     .setting(ArgSettings::TakesValue)
3827
    ///     .setting(ArgSettings::HideEnv)
3828
    /// # ;
3829
    /// ```
3830
    ///
3831
    /// ```rust
3832
    /// # use clap::{App, Arg, ArgSettings};
3833
    /// let m = App::new("prog")
3834
    ///     .arg(Arg::new("mode")
3835
    ///         .long("mode")
3836
    ///         .env("MODE")
3837
    ///         .setting(ArgSettings::TakesValue)
3838
    ///         .setting(ArgSettings::HideEnv));
3839
    ///
3840
    /// ```
3841
    ///
3842
    /// If we were to run the above program with `--help` the `[env: MODE]` portion of the help
3843
    /// text would be omitted.
3844
    #[inline]
3845
    pub fn hide_env(self, hide: bool) -> Self {
1✔
3846
        if hide {
1✔
3847
            self.setting(ArgSettings::HideEnv)
1✔
3848
        } else {
3849
            self.unset_setting(ArgSettings::HideEnv)
1✔
3850
        }
3851
    }
3852

3853
    /// Specifies that any values inside the associated ENV variables of an argument should not be
3854
    /// displayed in the help text.
3855
    ///
3856
    /// This is useful when ENV vars contain sensitive values.
3857
    ///
3858
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`]
3859
    ///
3860
    /// # Examples
3861
    ///
3862
    /// ```rust
3863
    /// # use clap::{App, Arg, ArgSettings};
3864
    /// Arg::new("config")
3865
    ///     .setting(ArgSettings::TakesValue)
3866
    ///     .setting(ArgSettings::HideEnvValues)
3867
    /// # ;
3868
    /// ```
3869
    ///
3870
    /// ```rust
3871
    /// # use clap::{App, Arg, ArgSettings};
3872
    /// let m = App::new("connect")
3873
    ///     .arg(Arg::new("host")
3874
    ///         .long("host")
3875
    ///         .env("CONNECT")
3876
    ///         .setting(ArgSettings::TakesValue)
3877
    ///         .setting(ArgSettings::HideEnvValues));
3878
    ///
3879
    /// ```
3880
    ///
3881
    /// If we were to run the above program with `$ CONNECT=super_secret connect --help` the
3882
    /// `[default: CONNECT=super_secret]` portion of the help text would be omitted.
3883
    #[inline]
3884
    pub fn hide_env_values(self, hide: bool) -> Self {
1✔
3885
        if hide {
1✔
3886
            self.setting(ArgSettings::HideEnvValues)
1✔
3887
        } else {
3888
            self.unset_setting(ArgSettings::HideEnvValues)
×
3889
        }
3890
    }
3891

3892
    /// When set to `true` the help string will be displayed on the line after the argument and
3893
    /// indented once. This can be helpful for arguments with very long or complex help messages.
3894
    /// This can also be helpful for arguments with very long flag names, or many/long value names.
3895
    ///
3896
    /// **NOTE:** To apply this setting to all arguments consider using
3897
    /// [`AppSettings::NextLineHelp`]
3898
    ///
3899
    /// # Examples
3900
    ///
3901
    /// ```rust
3902
    /// # use clap::{App, Arg, ArgSettings};
3903
    /// let m = App::new("prog")
3904
    ///     .arg(Arg::new("opt")
3905
    ///         .long("long-option-flag")
3906
    ///         .short('o')
3907
    ///         .setting(ArgSettings::TakesValue)
3908
    ///         .setting(ArgSettings::NextLineHelp)
3909
    ///         .value_names(&["value1", "value2"])
3910
    ///         .about("Some really long help and complex\n\
3911
    ///                help that makes more sense to be\n\
3912
    ///                on a line after the option"))
3913
    ///     .get_matches_from(vec![
3914
    ///         "prog", "--help"
3915
    ///     ]);
3916
    /// ```
3917
    ///
3918
    /// The above example displays the following help message
3919
    ///
3920
    /// ```text
3921
    /// nlh
3922
    ///
3923
    /// USAGE:
3924
    ///     nlh [FLAGS] [OPTIONS]
3925
    ///
3926
    /// FLAGS:
3927
    ///     -h, --help       Prints help information
3928
    ///     -V, --version    Prints version information
3929
    ///
3930
    /// OPTIONS:
3931
    ///     -o, --long-option-flag <value1> <value2>
3932
    ///         Some really long help and complex
3933
    ///         help that makes more sense to be
3934
    ///         on a line after the option
3935
    /// ```
3936
    #[inline]
3937
    pub fn next_line_help(self, nlh: bool) -> Self {
2✔
3938
        if nlh {
2✔
3939
            self.setting(ArgSettings::NextLineHelp)
2✔
3940
        } else {
3941
            self.unset_setting(ArgSettings::NextLineHelp)
×
3942
        }
3943
    }
3944

3945
    /// Specifies that the argument may have an unknown number of multiple values. Without any other
3946
    /// settings, this argument may appear only *once*.
3947
    ///
3948
    /// For example, `--opt val1 val2` is allowed, but `--opt val1 val2 --opt val3` is not.
3949
    ///
3950
    /// **NOTE:** Implicitly sets [`ArgSettings::TakesValue`]
3951
    ///
3952
    /// **WARNING:**
3953
    ///
3954
    /// Setting `MultipleValues` for an argument that takes a value, but with no other details can
3955
    /// be dangerous in some circumstances. Because multiple values are allowed,
3956
    /// `--option val1 val2 val3` is perfectly valid. Be careful when designing a CLI where
3957
    /// positional arguments are *also* expected as `clap` will continue parsing *values* until one
3958
    /// of the following happens:
3959
    ///
3960
    /// * It reaches the [maximum number of values]
3961
    /// * It reaches a [specific number of values]
3962
    /// * It finds another flag or option (i.e. something that starts with a `-`)
3963
    ///
3964
    /// **WARNING:**
3965
    ///
3966
    /// When using args with `MultipleValues` and [subcommands], one needs to consider the
3967
    /// possibility of an argument value being the same as a valid subcommand. By default `clap` will
3968
    /// parse the argument in question as a value *only if* a value is possible at that moment.
3969
    /// Otherwise it will be parsed as a subcommand. In effect, this means using `MultipleValues` with no
3970
    /// additional parameters and a value that coincides with a subcommand name, the subcommand
3971
    /// cannot be called unless another argument is passed between them.
3972
    ///
3973
    /// As an example, consider a CLI with an option `--ui-paths=<paths>...` and subcommand `signer`
3974
    ///
3975
    /// The following would be parsed as values to `--ui-paths`.
3976
    ///
3977
    /// ```text
3978
    /// $ program --ui-paths path1 path2 signer
3979
    /// ```
3980
    ///
3981
    /// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values
3982
    /// until another argument is reached and it knows `--ui-paths` is done parsing.
3983
    ///
3984
    /// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding
3985
    /// [`Arg::number_of_values(1)`] or using *only* [`MultipleOccurrences`]. The following are all
3986
    /// valid, and `signer` is parsed as a subcommand in the first case, but a value in the second
3987
    /// case.
3988
    ///
3989
    /// ```text
3990
    /// $ program --ui-paths path1 signer
3991
    /// $ program --ui-paths path1 --ui-paths signer signer
3992
    /// ```
3993
    ///
3994
    /// # Examples
3995
    ///
3996
    /// ```rust
3997
    /// # use clap::{App, Arg, ArgSettings};
3998
    /// Arg::new("debug")
3999
    ///     .short('d')
4000
    ///     .setting(ArgSettings::TakesValue)
4001
    ///     .setting(ArgSettings::MultipleValues)
4002
    /// # ;
4003
    /// ```
4004
    /// An example with flags
4005
    ///
4006
    /// ```rust
4007
    /// # use clap::{App, Arg, ArgSettings};
4008
    /// let m = App::new("prog")
4009
    ///     .arg(Arg::new("verbose")
4010
    ///         .setting(ArgSettings::MultipleOccurrences)
4011
    ///         .short('v'))
4012
    ///     .get_matches_from(vec![
4013
    ///         "prog", "-v", "-v", "-v"    // note, -vvv would have same result
4014
    ///     ]);
4015
    ///
4016
    /// assert!(m.is_present("verbose"));
4017
    /// assert_eq!(m.occurrences_of("verbose"), 3);
4018
    /// ```
4019
    ///
4020
    /// An example with options
4021
    ///
4022
    /// ```rust
4023
    /// # use clap::{App, Arg, ArgSettings};
4024
    /// let m = App::new("prog")
4025
    ///     .arg(Arg::new("file")
4026
    ///         .setting(ArgSettings::TakesValue)
4027
    ///         .setting(ArgSettings::MultipleValues)
4028
    ///         .short('F'))
4029
    ///     .get_matches_from(vec![
4030
    ///         "prog", "-F", "file1", "file2", "file3"
4031
    ///     ]);
4032
    ///
4033
    /// assert!(m.is_present("file"));
4034
    /// assert_eq!(m.occurrences_of("file"), 1); // notice only one occurrence
4035
    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
4036
    /// assert_eq!(files, ["file1", "file2", "file3"]);
4037
    /// ```
4038
    /// Although `MultipleVlaues` has been specified, we cannot use the argument more than once.
4039
    ///
4040
    /// ```rust
4041
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
4042
    /// let res = App::new("prog")
4043
    ///     .arg(Arg::new("file")
4044
    ///         .setting(ArgSettings::TakesValue)
4045
    ///         .setting(ArgSettings::MultipleValues)
4046
    ///         .short('F'))
4047
    ///     .try_get_matches_from(vec![
4048
    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
4049
    ///     ]);
4050
    /// assert!(res.is_err());
4051
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnexpectedMultipleUsage)
4052
    /// ```
4053
    ///
4054
    /// A common mistake is to define an option which allows multiple values, and a positional
4055
    /// argument.
4056
    ///
4057
    /// ```rust
4058
    /// # use clap::{App, Arg, ArgSettings};
4059
    /// let m = App::new("prog")
4060
    ///     .arg(Arg::new("file")
4061
    ///         .setting(ArgSettings::TakesValue)
4062
    ///         .setting(ArgSettings::MultipleValues)
4063
    ///         .short('F'))
4064
    ///     .arg(Arg::new("word")
4065
    ///         .index(1))
4066
    ///     .get_matches_from(vec![
4067
    ///         "prog", "-F", "file1", "file2", "file3", "word"
4068
    ///     ]);
4069
    ///
4070
    /// assert!(m.is_present("file"));
4071
    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
4072
    /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?!
4073
    /// assert!(!m.is_present("word")); // but we clearly used word!
4074
    /// ```
4075
    /// The problem is `clap` doesn't know when to stop parsing values for "files". This is further
4076
    /// compounded by if we'd said `word -F file1 file2` it would have worked fine, so it would
4077
    /// appear to only fail sometimes...not good!
4078
    ///
4079
    /// A solution for the example above is to limit how many values with a [maxium], or [specific]
4080
    /// number, or to say [`MultipleOccurrences`] is ok, but multiple values is not.
4081
    ///
4082
    /// ```rust
4083
    /// # use clap::{App, Arg, ArgSettings};
4084
    /// let m = App::new("prog")
4085
    ///     .arg(Arg::new("file")
4086
    ///         .setting(ArgSettings::MultipleOccurrences)
4087
    ///         .setting(ArgSettings::TakesValue)
4088
    ///         .short('F'))
4089
    ///     .arg(Arg::new("word")
4090
    ///         .index(1))
4091
    ///     .get_matches_from(vec![
4092
    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word"
4093
    ///     ]);
4094
    ///
4095
    /// assert!(m.is_present("file"));
4096
    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
4097
    /// assert_eq!(files, ["file1", "file2", "file3"]);
4098
    /// assert!(m.is_present("word"));
4099
    /// assert_eq!(m.value_of("word"), Some("word"));
4100
    /// ```
4101
    /// As a final example, let's fix the above error and get a pretty message to the user :)
4102
    ///
4103
    /// ```rust
4104
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
4105
    /// let res = App::new("prog")
4106
    ///     .arg(Arg::new("file")
4107
    ///         .setting(ArgSettings::MultipleOccurrences)
4108
    ///         .setting(ArgSettings::TakesValue)
4109
    ///         .short('F'))
4110
    ///     .arg(Arg::new("word")
4111
    ///         .index(1))
4112
    ///     .try_get_matches_from(vec![
4113
    ///         "prog", "-F", "file1", "file2", "file3", "word"
4114
    ///     ]);
4115
    ///
4116
    /// assert!(res.is_err());
4117
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
4118
    /// ```
4119
    /// [option]: ArgSettings::TakesValue
4120
    /// [options]: ArgSettings::TakesValue
4121
    /// [subcommands]: App::subcommand()
4122
    /// [positionals]: Arg::index()
4123
    /// [`Arg::number_of_values(1)`]: Arg::number_of_values()
4124
    /// [`MultipleOccurrences`]: ArgSettings::MultipleOccurrences
4125
    /// [`MultipleValues`]: ArgSettings::MultipleValues
4126
    /// [maximum number of values]: Arg::max_values()
4127
    /// [specific number of values]: Arg::number_of_values()
4128
    /// [maximum]: Arg::max_values()
4129
    /// [specific]: Arg::number_of_values()
4130
    #[inline]
4131
    pub fn multiple(self, multi: bool) -> Self {
28✔
4132
        self.multiple_occurrences(multi).multiple_values(multi)
28✔
4133
    }
4134

4135
    /// Don't allow an argument to accept explicitly empty values. An empty value
4136
    /// must be specified at the command line with an explicit `""`, `''`, or
4137
    /// `--option=`
4138
    ///
4139
    /// **NOTE:** By default empty values are allowed.
4140
    ///
4141
    /// **NOTE:** Setting this requires [`ArgSettings::TakesValue`].
4142
    ///
4143
    /// # Examples
4144
    ///
4145
    /// ```rust
4146
    /// # use clap::{App, Arg, ArgSettings};
4147
    /// Arg::new("file")
4148
    ///     .long("file")
4149
    ///     .takes_value(true)
4150
    ///     .forbid_empty_values(true)
4151
    /// # ;
4152
    /// ```
4153
    ///
4154
    /// The default is allowing empty values.
4155
    ///
4156
    /// ```rust
4157
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
4158
    /// let res = App::new("prog")
4159
    ///     .arg(Arg::new("cfg")
4160
    ///         .long("config")
4161
    ///         .short('v')
4162
    ///         .takes_value(true))
4163
    ///     .try_get_matches_from(vec![
4164
    ///         "prog", "--config="
4165
    ///     ]);
4166
    ///
4167
    /// assert!(res.is_ok());
4168
    /// assert_eq!(res.unwrap().value_of("config"), None);
4169
    /// ```
4170
    ///
4171
    /// By adding this setting, we can forbid empty values.
4172
    ///
4173
    /// ```rust
4174
    /// # use clap::{App, Arg, ErrorKind, ArgSettings};
4175
    /// let res = App::new("prog")
4176
    ///     .arg(Arg::new("cfg")
4177
    ///         .long("config")
4178
    ///         .short('v')
4179
    ///         .takes_value(true)
4180
    ///         .forbid_empty_values(true))
4181
    ///     .try_get_matches_from(vec![
4182
    ///         "prog", "--config="
4183
    ///     ]);
4184
    ///
4185
    /// assert!(res.is_err());
4186
    /// assert_eq!(res.unwrap_err().kind, ErrorKind::EmptyValue);
4187
    /// ```
4188
    #[inline]
4189
    pub fn forbid_empty_values(self, empty: bool) -> Self {
2✔
4190
        if empty {
2✔
4191
            self.setting(ArgSettings::NoEmptyValues)
2✔
4192
        } else {
4193
            self.unset_setting(ArgSettings::NoEmptyValues)
×
4194
        }
4195
    }
4196

4197
    /// Placeholder documentation
4198
    #[inline]
4199
    pub fn multiple_values(self, multi: bool) -> Self {
43✔
4200
        if multi {
45✔
4201
            self.setting(ArgSettings::MultipleValues)
42✔
4202
        } else {
4203
            self.unset_setting(ArgSettings::MultipleValues)
5✔
4204
        }
4205
    }
4206

4207
    /// Specifies that the argument may appear more than once.
4208
    /// For flags, this results
4209
    /// in the number of occurrences of the flag being recorded. For example `-ddd` or `-d -d -d`
4210
    /// would count as three occurrences. For options or arguments that take a value, this
4211
    /// *does not* affect how many values they can accept. (i.e. only one at a time is allowed)
4212
    ///
4213
    /// For example, `--opt val1 --opt val2` is allowed, but `--opt val1 val2` is not.
4214
    ///
4215
    /// # Examples
4216
    ///
4217
    /// ```rust
4218
    /// # use clap::{App, Arg, ArgSettings};
4219
    /// Arg::new("debug")
4220
    ///     .short('d')
4221
    ///     .setting(ArgSettings::MultipleOccurrences)
4222
    /// # ;
4223
    /// ```
4224
    /// An example with flags
4225
    ///
4226
    /// ```rust
4227
    /// # use clap::{App, Arg, ArgSettings};
4228
    /// let m = App::new("prog")
4229
    ///     .arg(Arg::new("verbose")
4230
    ///         .setting(ArgSettings::MultipleOccurrences)
4231
    ///         .short('v'))
4232
    ///     .get_matches_from(vec![
4233
    ///         "prog", "-v", "-v", "-v"    // note, -vvv would have same result
4234
    ///     ]);
4235
    ///
4236
    /// assert!(m.is_present("verbose"));
4237
    /// assert_eq!(m.occurrences_of("verbose"), 3);
4238
    /// ```
4239
    ///
4240
    /// An example with options
4241
    ///
4242
    /// ```rust
4243
    /// # use clap::{App, Arg, ArgSettings};
4244
    /// let m = App::new("prog")
4245
    ///     .arg(Arg::new("file")
4246
    ///         .setting(ArgSettings::MultipleOccurrences)
4247
    ///         .setting(ArgSettings::TakesValue)
4248
    ///         .short('F'))
4249
    ///     .get_matches_from(vec![
4250
    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
4251
    ///     ]);
4252
    ///
4253
    /// assert!(m.is_present("file"));
4254
    /// assert_eq!(m.occurrences_of("file"), 3);
4255
    /// let files: Vec<_> = m.values_of("file").unwrap().collect();
4256
    /// assert_eq!(files, ["file1", "file2", "file3"]);
4257
    /// ```
4258
    /// [option]: ArgSettings::TakesValue
4259
    /// [options]: ArgSettings::TakesValue
4260
    /// [subcommands]: App::subcommand()
4261
    /// [positionals]: Arg::index()
4262
    /// [`Arg::number_of_values(1)`]: Arg::number_of_values()
4263
    /// [`MultipleOccurrences`]: ArgSettings::MultipleOccurrences
4264
    /// [`MultipleValues`]: ArgSettings::MultipleValues
4265
    /// [maximum number of values]: Arg::max_values()
4266
    /// [specific number of values]: Arg::number_of_values()
4267
    /// [maximum]: Arg::max_values()
4268
    /// [specific]: Arg::number_of_values()
4269
    #[inline]
4270
    pub fn multiple_occurrences(self, multi: bool) -> Self {
31✔
4271
        if multi {
33✔
4272
            self.setting(ArgSettings::MultipleOccurrences)
30✔
4273
        } else {
4274
            self.unset_setting(ArgSettings::MultipleOccurrences)
5✔
4275
        }
4276
    }
4277

4278
    /// Indicates that all parameters passed after this should not be parsed
4279
    /// individually, but rather passed in their entirety. It is worth noting
4280
    /// that setting this requires all values to come after a `--` to indicate they
4281
    /// should all be captured. For example:
4282
    ///
4283
    /// ```text
4284
    /// --foo something -- -v -v -v -b -b -b --baz -q -u -x
4285
    /// ```
4286
    /// Will result in everything after `--` to be considered one raw argument. This behavior
4287
    /// may not be exactly what you are expecting and using [`AppSettings::TrailingVarArg`]
4288
    /// may be more appropriate.
4289
    ///
4290
    /// **NOTE:** Implicitly sets [`Arg::takes_value(true)`] [`Arg::multiple(true)`], [`Arg::allow_hyphen_values(true)`], and
4291
    /// [`Arg::last(true)`] when set to `true`
4292
    ///
4293
    /// [`Arg::takes_value(true)`]: Arg::takes_value()
4294
    /// [`Arg::multiple(true)`]: Arg::multiple()
4295
    /// [`Arg::allow_hyphen_values(true)`]: Arg::allow_hyphen_values()
4296
    /// [`Arg::last(true)`]: Arg::last()
4297
    #[inline]
4298
    pub fn raw(self, raw: bool) -> Self {
1✔
4299
        self.takes_value(raw)
1✔
4300
            .multiple(raw)
×
4301
            .allow_hyphen_values(raw)
×
4302
            .last(raw)
×
4303
    }
4304

4305
    /// Hides an argument from short help message output.
4306
    ///
4307
    /// **NOTE:** This does **not** hide the argument from usage strings on error
4308
    ///
4309
    /// **NOTE:** Setting this option will cause next-line-help output style to be used
4310
    /// when long help (`--help`) is called.
4311
    ///
4312
    /// # Examples
4313
    ///
4314
    /// ```rust
4315
    /// # use clap::{App, Arg};
4316
    /// Arg::new("debug")
4317
    ///     .hidden_short_help(true)
4318
    /// # ;
4319
    /// ```
4320
    /// Setting `hidden_short_help(true)` will hide the argument when displaying short help text
4321
    ///
4322
    /// ```rust
4323
    /// # use clap::{App, Arg};
4324
    /// let m = App::new("prog")
4325
    ///     .arg(Arg::new("cfg")
4326
    ///         .long("config")
4327
    ///         .hidden_short_help(true)
4328
    ///         .about("Some help text describing the --config arg"))
4329
    ///     .get_matches_from(vec![
4330
    ///         "prog", "-h"
4331
    ///     ]);
4332
    /// ```
4333
    ///
4334
    /// The above example displays
4335
    ///
4336
    /// ```text
4337
    /// helptest
4338
    ///
4339
    /// USAGE:
4340
    ///    helptest [FLAGS]
4341
    ///
4342
    /// FLAGS:
4343
    /// -h, --help       Prints help information
4344
    /// -V, --version    Prints version information
4345
    /// ```
4346
    ///
4347
    /// However, when --help is called
4348
    ///
4349
    /// ```rust
4350
    /// # use clap::{App, Arg};
4351
    /// let m = App::new("prog")
4352
    ///     .arg(Arg::new("cfg")
4353
    ///         .long("config")
4354
    ///         .hidden_short_help(true)
4355
    ///         .about("Some help text describing the --config arg"))
4356
    ///     .get_matches_from(vec![
4357
    ///         "prog", "--help"
4358
    ///     ]);
4359
    /// ```
4360
    ///
4361
    /// Then the following would be displayed
4362
    ///
4363
    /// ```text
4364
    /// helptest
4365
    ///
4366
    /// USAGE:
4367
    ///    helptest [FLAGS]
4368
    ///
4369
    /// FLAGS:
4370
    ///     --config     Some help text describing the --config arg
4371
    /// -h, --help       Prints help information
4372
    /// -V, --version    Prints version information
4373
    /// ```
4374
    #[inline]
4375
    pub fn hidden_short_help(self, hide: bool) -> Self {
2✔
4376
        if hide {
2✔
4377
            self.setting(ArgSettings::HiddenShortHelp)
2✔
4378
        } else {
4379
            self.unset_setting(ArgSettings::HiddenShortHelp)
×
4380
        }
4381
    }
4382

4383
    /// Hides an argument from long help message output.
4384
    ///
4385
    /// **NOTE:** This does **not** hide the argument from usage strings on error
4386
    ///
4387
    /// **NOTE:** Setting this option will cause next-line-help output style to be used
4388
    /// when long help (`--help`) is called.
4389
    ///
4390
    /// # Examples
4391
    ///
4392
    /// ```rust
4393
    /// # use clap::{App, Arg};
4394
    /// Arg::new("debug")
4395
    ///     .hidden_long_help(true)
4396
    /// # ;
4397
    /// ```
4398
    /// Setting `hidden_long_help(true)` will hide the argument when displaying long help text
4399
    ///
4400
    /// ```rust
4401
    /// # use clap::{App, Arg};
4402
    /// let m = App::new("prog")
4403
    ///     .arg(Arg::new("cfg")
4404
    ///         .long("config")
4405
    ///         .hidden_long_help(true)
4406
    ///         .about("Some help text describing the --config arg"))
4407
    ///     .get_matches_from(vec![
4408
    ///         "prog", "--help"
4409
    ///     ]);
4410
    /// ```
4411
    ///
4412
    /// The above example displays
4413
    ///
4414
    /// ```text
4415
    /// helptest
4416
    ///
4417
    /// USAGE:
4418
    ///    helptest [FLAGS]
4419
    ///
4420
    /// FLAGS:
4421
    /// -h, --help       Prints help information
4422
    /// -V, --version    Prints version information
4423
    /// ```
4424
    ///
4425
    /// However, when -h is called
4426
    ///
4427
    /// ```rust
4428
    /// # use clap::{App, Arg};
4429
    /// let m = App::new("prog")
4430
    ///     .arg(Arg::new("cfg")
4431
    ///         .long("config")
4432
    ///         .hidden_long_help(true)
4433
    ///         .about("Some help text describing the --config arg"))
4434
    ///     .get_matches_from(vec![
4435
    ///         "prog", "-h"
4436
    ///     ]);
4437
    /// ```
4438
    ///
4439
    /// Then the following would be displayed
4440
    ///
4441
    /// ```text
4442
    /// helptest
4443
    ///
4444
    /// USAGE:
4445
    ///    helptest [FLAGS]
4446
    ///
4447
    /// FLAGS:
4448
    ///     --config     Some help text describing the --config arg
4449
    /// -h, --help       Prints help information
4450
    /// -V, --version    Prints version information
4451
    /// ```
4452
    #[inline]
4453
    pub fn hidden_long_help(self, hide: bool) -> Self {
1✔
4454
        if hide {
1✔
4455
            self.setting(ArgSettings::HiddenLongHelp)
1✔
4456
        } else {
4457
            self.unset_setting(ArgSettings::HiddenLongHelp)
×
4458
        }
4459
    }
4460

4461
    // @TODO @docs @v3-beta: write better docs as ArgSettings is now critical
4462
    /// Checks if one of the [`ArgSettings`] is set for the argument
4463
    ///
4464
    #[inline]
4465
    pub fn is_set(&self, s: ArgSettings) -> bool {
104✔
4466
        self.settings.is_set(s)
104✔
4467
    }
4468

4469
    /// Enables a single setting for the current (this `Arg` instance) argument.
4470
    ///
4471
    /// See [`ArgSettings`] for a full list of possibilities and examples.
4472
    ///
4473
    /// # Examples
4474
    ///
4475
    /// ```no_run
4476
    /// # use clap::{Arg, ArgSettings};
4477
    /// Arg::new("config")
4478
    ///     .setting(ArgSettings::Required)
4479
    ///     .setting(ArgSettings::TakesValue)
4480
    /// # ;
4481
    /// ```
4482
    #[inline]
4483
    pub fn setting(mut self, setting: ArgSettings) -> Self {
94✔
4484
        self.settings.set(setting);
95✔
4485
        self
96✔
4486
    }
4487

4488
    /// Disables a single setting for the current (this `Arg` instance) argument.
4489
    ///
4490
    /// See [`ArgSettings`] for a full list of possibilities and examples.
4491
    ///
4492
    /// # Examples
4493
    ///
4494
    /// ```no_run
4495
    /// # use clap::{Arg, ArgSettings};
4496
    /// Arg::new("config")
4497
    ///     .unset_setting(ArgSettings::Required)
4498
    /// # ;
4499
    /// ```
4500
    #[inline]
4501
    pub fn unset_setting(mut self, setting: ArgSettings) -> Self {
18✔
4502
        self.settings.unset(setting);
18✔
4503
        self
18✔
4504
    }
4505

4506
    /// Set a custom heading for this arg to be printed under
4507
    #[inline]
4508
    pub fn help_heading(mut self, s: Option<&'help str>) -> Self {
3✔
4509
        self.help_heading = s;
3✔
4510
        self
3✔
4511
    }
4512

4513
    /// Sets a hint about the type of the value for shell completions
4514
    ///
4515
    /// Currently this is only supported by the zsh completions generator.
4516
    ///
4517
    /// For example, to take a username as argument:
4518
    /// ```
4519
    /// # use clap::{Arg, ValueHint};
4520
    /// Arg::new("user")
4521
    ///     .short('u')
4522
    ///     .long("user")
4523
    ///     .value_hint(ValueHint::Username)
4524
    /// # ;
4525
    /// ```
4526
    ///
4527
    /// To take a full command line and its arguments (for example, when writing a command wrapper):
4528
    /// ```
4529
    /// # use clap::{App, AppSettings, Arg, ValueHint};
4530
    /// App::new("prog")
4531
    ///     .setting(AppSettings::TrailingVarArg)
4532
    ///     .arg(
4533
    ///         Arg::new("command")
4534
    ///             .takes_value(true)
4535
    ///             .multiple(true)
4536
    ///             .value_hint(ValueHint::CommandWithArguments)
4537
    ///     )
4538
    /// # ;
4539
    /// ```
4540
    pub fn value_hint(mut self, value_hint: ValueHint) -> Self {
3✔
4541
        self.settings.set(ArgSettings::TakesValue);
3✔
4542
        self.value_hint = value_hint;
3✔
4543
        self
3✔
4544
    }
4545

4546
    // FIXME: (@CreepySkeleton)
4547
    #[doc(hidden)]
4548
    pub fn _build(&mut self) {
102✔
4549
        if (self.is_set(ArgSettings::UseValueDelimiter)
307✔
4550
            || self.is_set(ArgSettings::RequireDelimiter))
103✔
4551
            && self.val_delim.is_none()
12✔
4552
        {
4553
            self.val_delim = Some(',');
1✔
4554
        }
4555
        if !(self.index.is_some() || (self.short.is_none() && self.long.is_none()))
369✔
4556
            && self.is_set(ArgSettings::TakesValue)
104✔
4557
            && self.val_names.len() > 1
102✔
4558
        {
4559
            self.num_vals = Some(self.val_names.len());
10✔
4560
        }
4561
    }
4562

4563
    pub(crate) fn has_switch(&self) -> bool {
55✔
4564
        self.short.is_some() || self.long.is_some()
108✔
4565
    }
4566

4567
    pub(crate) fn longest_filter(&self) -> bool {
32✔
4568
        self.is_set(ArgSettings::TakesValue) || self.long.is_some() || self.short.is_none()
64✔
4569
    }
4570

4571
    pub(crate) fn is_positional(&self) -> bool {
96✔
4572
        self.long.is_none() && self.short.is_none()
192✔
4573
    }
4574

4575
    // Used for positionals when printing
4576
    pub(crate) fn multiple_str(&self) -> &str {
13✔
4577
        // FIXME: This should probably be > 1
4578
        let mult_vals = self.val_names.len() < 2;
14✔
4579
        if (self.is_set(ArgSettings::MultipleValues)
38✔
4580
            || self.is_set(ArgSettings::MultipleOccurrences))
10✔
4581
            && mult_vals
×
4582
        {
4583
            "..."
6✔
4584
        } else {
4585
            ""
10✔
4586
        }
4587
    }
4588

4589
    // Used for positionals when printing
4590
    pub(crate) fn name_no_brackets(&self) -> Cow<str> {
15✔
4591
        debug!("Arg::name_no_brackets:{}", self.name);
×
4592
        let mut delim = String::new();
15✔
4593
        delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
45✔
4594
            self.val_delim.expect(INTERNAL_ERROR_MSG)
×
4595
        } else {
4596
            ' '
15✔
4597
        });
4598
        if !self.val_names.is_empty() {
31✔
4599
            debug!("Arg::name_no_brackets: val_names={:#?}", self.val_names);
×
4600

4601
            if self.val_names.len() > 1 {
2✔
4602
                Cow::Owned(
4603
                    self.val_names
×
4604
                        .values()
×
4605
                        .map(|n| format!("<{}>", n))
×
4606
                        .collect::<Vec<_>>()
×
4607
                        .join(&*delim),
×
4608
                )
4609
            } else {
4610
                Cow::Borrowed(self.val_names.values().next().expect(INTERNAL_ERROR_MSG))
4✔
4611
            }
4612
        } else {
4613
            debug!("Arg::name_no_brackets: just name");
×
4614
            Cow::Borrowed(self.name)
14✔
4615
        }
4616
    }
4617
}
4618

4619
#[cfg(feature = "yaml")]
4620
impl<'help> From<&'help Yaml> for Arg<'help> {
4621
    /// Creates a new instance of [`Arg`] from a .yaml (YAML) file.
4622
    ///
4623
    /// # Examples
4624
    ///
4625
    /// ```ignore
4626
    /// use clap::{Arg, load_yaml};
4627
    /// let yaml = load_yaml!("arg.yaml");
4628
    /// let arg = Arg::from(yaml);
4629
    /// ```
4630
    #[allow(clippy::cognitive_complexity)]
4631
    fn from(y: &'help Yaml) -> Self {
3✔
4632
        let y = y.as_hash().unwrap();
2✔
4633
        // We WANT this to panic on error...so expect() is good.
4634
        let name_yaml = y.keys().next().unwrap();
2✔
4635
        let name_str = name_yaml.as_str().unwrap();
2✔
4636
        let mut a = Arg::new(name_str);
2✔
4637
        let arg_settings = y.get(name_yaml).unwrap().as_hash().unwrap();
2✔
4638

4639
        for (k, v) in arg_settings.iter() {
4✔
4640
            a = match k.as_str().unwrap() {
61✔
4641
                "short" => yaml_to_char!(a, v, short),
4✔
4642
                "long" => yaml_to_str!(a, v, long),
4✔
4643
                "aliases" => yaml_vec_or_str!(a, v, alias),
4✔
4644
                "short_aliases" => yaml_to_chars!(a, v, short_aliases),
4✔
4645
                "about" => yaml_to_str!(a, v, about),
4✔
4646
                "long_about" => yaml_to_str!(a, v, long_about),
2✔
4647
                "help" => yaml_to_str!(a, v, about),
4✔
4648
                "long_help" => yaml_to_str!(a, v, long_about),
2✔
4649
                "required" => yaml_to_bool!(a, v, required),
2✔
4650
                "required_if_eq" => yaml_tuple2!(a, v, required_if_eq),
4✔
4651
                "required_if_eq_any" => yaml_array_tuple2!(a, v, required_if_eq_any),
2✔
4652
                "required_if_eq_all" => yaml_array_tuple2!(a, v, required_if_eq_all),
2✔
4653
                "takes_value" => yaml_to_bool!(a, v, takes_value),
4✔
4654
                "index" => yaml_to_usize!(a, v, index),
4✔
4655
                "global" => yaml_to_bool!(a, v, global),
4✔
4656
                "multiple" => yaml_to_bool!(a, v, multiple),
4✔
4657
                "hidden" => yaml_to_bool!(a, v, hidden),
2✔
4658
                "next_line_help" => yaml_to_bool!(a, v, next_line_help),
2✔
4659
                "group" => yaml_to_str!(a, v, group),
2✔
4660
                "number_of_values" => yaml_to_usize!(a, v, number_of_values),
2✔
4661
                "max_values" => yaml_to_usize!(a, v, max_values),
4✔
4662
                "min_values" => yaml_to_usize!(a, v, min_values),
4✔
4663
                "value_name" => yaml_to_str!(a, v, value_name),
2✔
4664
                "use_delimiter" => yaml_to_bool!(a, v, use_delimiter),
4✔
4665
                "allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values),
2✔
4666
                "require_equals" => yaml_to_bool!(a, v, require_equals),
2✔
4667
                "require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
4✔
4668
                "value_delimiter" => yaml_to_str!(a, v, value_delimiter),
2✔
4669
                "required_unless_present" => yaml_to_str!(a, v, required_unless_present),
2✔
4670
                "display_order" => yaml_to_usize!(a, v, display_order),
2✔
4671
                "default_value" => yaml_to_str!(a, v, default_value),
2✔
4672
                "default_value_if" => yaml_tuple3!(a, v, default_value_if),
4✔
4673
                "default_value_ifs" => yaml_tuple3!(a, v, default_value_if),
2✔
4674
                "default_missing_value" => yaml_to_str!(a, v, default_missing_value),
2✔
4675
                "env" => yaml_to_str!(a, v, env),
2✔
4676
                "value_names" => yaml_vec_or_str!(a, v, value_name),
4✔
4677
                "groups" => yaml_vec_or_str!(a, v, group),
2✔
4678
                "requires" => yaml_vec_or_str!(a, v, requires),
4✔
4679
                "requires_if" => yaml_tuple2!(a, v, requires_if),
4✔
4680
                "requires_ifs" => yaml_tuple2!(a, v, requires_if),
2✔
4681
                "conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
4✔
4682
                "exclusive" => yaml_to_bool!(a, v, exclusive),
4✔
4683
                "value_hint" => yaml_str_parse!(a, v, value_hint),
4✔
4684
                "hide_default_value" => yaml_to_bool!(a, v, hide_default_value),
2✔
4685
                "overrides_with" => yaml_vec_or_str!(a, v, overrides_with),
2✔
4686
                "possible_values" => yaml_vec_or_str!(a, v, possible_value),
4✔
4687
                "case_insensitive" => yaml_to_bool!(a, v, case_insensitive),
4✔
4688
                "required_unless_present_any" => yaml_vec!(a, v, required_unless_present_any),
2✔
4689
                "required_unless_present_all" => {
2✔
4690
                    a = yaml_vec!(a, v, required_unless_present_all);
×
4691
                    a.settings.set(ArgSettings::RequiredUnlessAll);
×
4692
                    a
×
4693
                }
4694
                "visible_alias" => yaml_to_str!(a, v, visible_alias),
4✔
4695
                "visible_aliases" => yaml_vec_or_str!(a, v, visible_alias),
4✔
4696
                "visible_short_alias" => yaml_to_char!(a, v, visible_short_alias),
4✔
4697
                "visible_short_aliases" => yaml_to_chars!(a, v, visible_short_aliases),
4✔
4698
                #[cfg(feature = "regex")]
×
4699
                "validator_regex" => {
2✔
4700
                    if let Some(vec) = v.as_vec() {
4✔
4701
                        debug_assert_eq!(2, vec.len());
2✔
4702
                        let regex = yaml_str!(vec[0]);
4✔
4703

4704
                        match Regex::new(regex) {
2✔
4705
                            Err(e) => panic!(
3✔
4706
                                "Failed to convert \"{}\" into regular expression: {}",
×
4707
                                regex, e
×
4708
                            ),
4709
                            Ok(regex) => a.validator_regex(regex, yaml_str!(vec[1])),
2✔
4710
                        }
4711
                    } else {
4712
                        panic!("Failed to convert YAML value to vector")
×
4713
                    }
4714
                }
4715

4716
                _ => continue, // Ignore extra fields
4717
            }
4718
        }
4719

4720
        a
2✔
4721
    }
4722
}
4723

4724
impl<'help> From<&'_ Arg<'help>> for Arg<'help> {
4725
    fn from(a: &Arg<'help>) -> Self {
15✔
4726
        a.clone()
15✔
4727
    }
4728
}
4729

4730
impl<'help> From<&'help str> for Arg<'help> {
4731
    fn from(s: &'help str) -> Self {
31✔
4732
        UsageParser::from_usage(s).parse()
31✔
4733
    }
4734
}
4735

4736
impl<'help> PartialEq for Arg<'help> {
4737
    fn eq(&self, other: &Arg<'help>) -> bool {
×
4738
        self.name == other.name
×
4739
    }
4740
}
4741

4742
impl<'help> Display for Arg<'help> {
4743
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
60✔
4744
        if self.index.is_some() || (self.long.is_none() && self.short.is_none()) {
60✔
4745
            // Positional
4746
            let mut delim = String::new();
33✔
4747
            delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
98✔
4748
                self.val_delim.expect(INTERNAL_ERROR_MSG)
×
4749
            } else {
4750
                ' '
32✔
4751
            });
4752
            if !self.val_names.is_empty() {
66✔
4753
                write!(
3✔
4754
                    f,
×
4755
                    "{}",
4756
                    self.val_names
6✔
4757
                        .values()
×
4758
                        .map(|n| format!("<{}>", n))
6✔
4759
                        .collect::<Vec<_>>()
×
4760
                        .join(&*delim)
3✔
4761
                )?;
4762
            } else {
4763
                write!(f, "<{}>", self.name)?;
63✔
4764
            }
4765
            if self.settings.is_set(ArgSettings::MultipleValues) && self.val_names.len() < 2 {
41✔
4766
                write!(f, "...")?;
10✔
4767
            }
4768
            return Ok(());
31✔
4769
        } else if !self.is_set(ArgSettings::TakesValue) {
135✔
4770
            // Flag
4771
            if let Some(l) = self.long {
120✔
4772
                write!(f, "--{}", l)?;
38✔
4773
            } else if let Some(s) = self.short {
8✔
4774
                write!(f, "-{}", s)?;
8✔
4775
            }
4776

4777
            return Ok(());
38✔
4778
        }
4779
        let sep = if self.is_set(ArgSettings::RequireEquals) {
97✔
4780
            "="
5✔
4781
        } else {
4782
            " "
32✔
4783
        };
4784
        // Write the name such --long or -l
4785
        if let Some(l) = self.long {
102✔
4786
            write!(f, "--{}{}", l, sep)?;
30✔
4787
        } else {
4788
            write!(f, "-{}{}", self.short.unwrap(), sep)?;
23✔
4789
        }
4790
        let delim = if self.is_set(ArgSettings::RequireDelimiter) {
73✔
4791
            self.val_delim.expect(INTERNAL_ERROR_MSG)
3✔
4792
        } else {
4793
            ' '
34✔
4794
        };
4795

4796
        // Write the values such as <name1> <name2>
4797
        if !self.val_names.is_empty() {
78✔
4798
            let mut it = self.val_names.iter().peekable();
17✔
4799
            while let Some((_, val)) = it.next() {
50✔
4800
                write!(f, "<{}>", val)?;
17✔
4801
                if it.peek().is_some() {
37✔
4802
                    write!(f, "{}", delim)?;
5✔
4803
                }
4804
            }
4805
            let num = self.val_names.len();
18✔
4806
            if self.is_set(ArgSettings::MultipleValues) && num == 1 {
20✔
4807
                write!(f, "...")?;
2✔
4808
            }
4809
        } else if let Some(num) = self.num_vals {
31✔
4810
            let mut it = (0..num).peekable();
3✔
4811
            while let Some(_) = it.next() {
6✔
4812
                write!(f, "<{}>", self.name)?;
3✔
4813
                if it.peek().is_some() {
8✔
4814
                    write!(f, "{}", delim)?;
2✔
4815
                }
4816
            }
4817
            if self.is_set(ArgSettings::MultipleValues) && num == 1 {
5✔
4818
                write!(f, "...")?;
1✔
4819
            }
4820
        } else {
4821
            write!(
24✔
4822
                f,
×
4823
                "<{}>{}",
4824
                self.name,
26✔
4825
                if self.is_set(ArgSettings::MultipleOccurrences) {
72✔
4826
                    "..."
8✔
4827
                } else {
4828
                    ""
21✔
4829
                }
4830
            )?;
4831
        }
4832

4833
        Ok(())
36✔
4834
    }
4835
}
4836

4837
impl<'help> PartialOrd for Arg<'help> {
4838
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
×
4839
        Some(self.cmp(other))
×
4840
    }
4841
}
4842

4843
impl<'help> Ord for Arg<'help> {
4844
    fn cmp(&self, other: &Arg) -> Ordering {
×
4845
        self.name.cmp(&other.name)
×
4846
    }
4847
}
4848

4849
impl<'help> Eq for Arg<'help> {}
4850

4851
impl<'help> fmt::Debug for Arg<'help> {
4852
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
×
4853
        f.debug_struct("Arg")
×
4854
            .field("id", &self.id)
×
4855
            .field("provider", &self.provider)
×
4856
            .field("name", &self.name)
×
4857
            .field("about", &self.about)
×
4858
            .field("long_about", &self.long_about)
×
4859
            .field("blacklist", &self.blacklist)
×
4860
            .field("settings", &self.settings)
×
4861
            .field("overrides", &self.overrides)
×
4862
            .field("groups", &self.groups)
×
4863
            .field("requires", &self.requires)
×
4864
            .field("r_ifs", &self.r_ifs)
×
4865
            .field("r_unless", &self.r_unless)
×
4866
            .field("short", &self.short)
×
4867
            .field("long", &self.long)
×
4868
            .field("aliases", &self.aliases)
×
4869
            .field("short_aliases", &self.short_aliases)
×
4870
            .field("disp_ord", &self.disp_ord)
×
4871
            .field("unified_ord", &self.unified_ord)
×
4872
            .field("possible_vals", &self.possible_vals)
×
4873
            .field("val_names", &self.val_names)
×
4874
            .field("num_vals", &self.num_vals)
×
4875
            .field("max_vals", &self.max_vals)
×
4876
            .field("min_vals", &self.min_vals)
×
4877
            .field(
4878
                "validator",
4879
                &self.validator.as_ref().map_or("None", |_| "Some(FnMut)"),
×
4880
            )
4881
            .field(
4882
                "validator_os",
4883
                &self.validator_os.as_ref().map_or("None", |_| "Some(FnMut)"),
×
4884
            )
4885
            .field("val_delim", &self.val_delim)
×
4886
            .field("default_vals", &self.default_vals)
×
4887
            .field("default_vals_ifs", &self.default_vals_ifs)
×
4888
            .field("env", &self.env)
×
4889
            .field("terminator", &self.terminator)
×
4890
            .field("index", &self.index)
×
4891
            .field("help_heading", &self.help_heading)
×
4892
            .field("global", &self.global)
×
4893
            .field("exclusive", &self.exclusive)
×
4894
            .field("value_hint", &self.value_hint)
×
4895
            .field("default_missing_vals", &self.default_missing_vals)
×
4896
            .finish()
4897
    }
4898
}
4899

4900
// Flags
4901
#[cfg(test)]
4902
mod test {
4903
    use super::Arg;
4904
    use crate::build::ArgSettings;
4905
    use crate::util::VecMap;
4906

4907
    #[test]
4908
    fn flag_display() {
3✔
4909
        let mut f = Arg::new("flg");
1✔
4910
        f.settings.set(ArgSettings::MultipleOccurrences);
1✔
4911
        f.long = Some("flag");
1✔
4912

4913
        assert_eq!(&*format!("{}", f), "--flag");
1✔
4914

4915
        let mut f2 = Arg::new("flg");
1✔
4916
        f2.short = Some('f');
1✔
4917

4918
        assert_eq!(&*format!("{}", f2), "-f");
1✔
4919
    }
4920

4921
    #[test]
4922
    fn flag_display_single_alias() {
3✔
4923
        let mut f = Arg::new("flg");
1✔
4924
        f.long = Some("flag");
1✔
4925
        f.aliases = vec![("als", true)];
1✔
4926

4927
        assert_eq!(&*format!("{}", f), "--flag")
1✔
4928
    }
4929

4930
    #[test]
4931
    fn flag_display_multiple_aliases() {
3✔
4932
        let mut f = Arg::new("flg");
1✔
4933
        f.short = Some('f');
1✔
4934
        f.aliases = vec![
1✔
4935
            ("alias_not_visible", false),
4936
            ("f2", true),
4937
            ("f3", true),
4938
            ("f4", true),
4939
        ];
4940
        assert_eq!(&*format!("{}", f), "-f");
1✔
4941
    }
4942

4943
    #[test]
4944
    fn flag_display_single_short_alias() {
3✔
4945
        let mut f = Arg::new("flg");
1✔
4946
        f.short = Some('a');
1✔
4947
        f.short_aliases = vec![('b', true)];
1✔
4948

4949
        assert_eq!(&*format!("{}", f), "-a")
1✔
4950
    }
4951

4952
    #[test]
4953
    fn flag_display_multiple_short_aliases() {
3✔
4954
        let mut f = Arg::new("flg");
1✔
4955
        f.short = Some('a');
1✔
4956
        f.short_aliases = vec![('b', false), ('c', true), ('d', true), ('e', true)];
1✔
4957
        assert_eq!(&*format!("{}", f), "-a");
1✔
4958
    }
4959

4960
    // Options
4961

4962
    #[test]
4963
    fn option_display1() {
3✔
4964
        let o = Arg::new("opt")
4965
            .long("option")
4966
            .takes_value(true)
4967
            .multiple(true);
4968

4969
        assert_eq!(&*format!("{}", o), "--option <opt>...");
1✔
4970
    }
4971

4972
    #[test]
4973
    fn option_display2() {
3✔
4974
        let o2 = Arg::new("opt").short('o').value_names(&["file", "name"]);
1✔
4975

4976
        assert_eq!(&*format!("{}", o2), "-o <file> <name>");
1✔
4977
    }
4978

4979
    #[test]
4980
    fn option_display3() {
3✔
4981
        let o2 = Arg::new("opt")
4982
            .short('o')
4983
            .takes_value(true)
4984
            .multiple(true)
4985
            .value_names(&["file", "name"]);
4986

4987
        assert_eq!(&*format!("{}", o2), "-o <file> <name>");
1✔
4988
    }
4989

4990
    #[test]
4991
    fn option_display_single_alias() {
3✔
4992
        let o = Arg::new("opt")
4993
            .takes_value(true)
4994
            .long("option")
4995
            .visible_alias("als");
4996

4997
        assert_eq!(&*format!("{}", o), "--option <opt>");
1✔
4998
    }
4999

5000
    #[test]
5001
    fn option_display_multiple_aliases() {
3✔
5002
        let o = Arg::new("opt")
5003
            .long("option")
5004
            .takes_value(true)
5005
            .visible_aliases(&["als2", "als3", "als4"])
5006
            .alias("als_not_visible");
5007

5008
        assert_eq!(&*format!("{}", o), "--option <opt>");
1✔
5009
    }
5010

5011
    #[test]
5012
    fn option_display_single_short_alias() {
3✔
5013
        let o = Arg::new("opt")
5014
            .takes_value(true)
5015
            .short('a')
5016
            .visible_short_alias('b');
5017

5018
        assert_eq!(&*format!("{}", o), "-a <opt>");
1✔
5019
    }
5020

5021
    #[test]
5022
    fn option_display_multiple_short_aliases() {
3✔
5023
        let o = Arg::new("opt")
5024
            .short('a')
5025
            .takes_value(true)
5026
            .visible_short_aliases(&['b', 'c', 'd'])
5027
            .short_alias('e');
5028

5029
        assert_eq!(&*format!("{}", o), "-a <opt>");
1✔
5030
    }
5031

5032
    // Positionals
5033

5034
    #[test]
5035
    fn positiona_display_mult() {
3✔
5036
        let p = Arg::new("pos")
5037
            .index(1)
5038
            .setting(ArgSettings::TakesValue)
5039
            .setting(ArgSettings::MultipleValues);
5040

5041
        assert_eq!(&*format!("{}", p), "<pos>...");
1✔
5042
    }
5043

5044
    #[test]
5045
    fn positional_display_required() {
3✔
5046
        let p2 = Arg::new("pos").index(1).setting(ArgSettings::Required);
1✔
5047

5048
        assert_eq!(&*format!("{}", p2), "<pos>");
1✔
5049
    }
5050

5051
    #[test]
5052
    fn positional_display_val_names() {
3✔
5053
        let mut p2 = Arg::new("pos").index(1);
1✔
5054
        let mut vm = VecMap::new();
1✔
5055
        vm.insert(0, "file1");
1✔
5056
        vm.insert(1, "file2");
1✔
5057
        p2.val_names = vm;
1✔
5058

5059
        assert_eq!(&*format!("{}", p2), "<file1> <file2>");
1✔
5060
    }
5061

5062
    #[test]
5063
    fn positional_display_val_names_req() {
3✔
5064
        let mut p2 = Arg::new("pos").index(1).setting(ArgSettings::Required);
1✔
5065
        let mut vm = VecMap::new();
1✔
5066
        vm.insert(0, "file1");
1✔
5067
        vm.insert(1, "file2");
1✔
5068
        p2.val_names = vm;
1✔
5069

5070
        assert_eq!(&*format!("{}", p2), "<file1> <file2>");
1✔
5071
    }
5072
}
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