1 #![allow(deprecated)]
2 
3 // Std
4 use std::{
5     borrow::Cow,
6     cmp::{Ord, Ordering},
7     error::Error,
8     ffi::OsStr,
9     fmt::{self, Display, Formatter},
10     str,
11     sync::{Arc, Mutex},
12 };
13 #[cfg(feature = "env")]
14 use std::{env, ffi::OsString};
15 
16 #[cfg(feature = "yaml")]
17 use yaml_rust::Yaml;
18 
19 // Internal
20 use crate::builder::usage_parser::UsageParser;
21 use crate::builder::ArgPredicate;
22 use crate::util::{Id, Key};
23 use crate::ArgAction;
24 use crate::PossibleValue;
25 use crate::ValueHint;
26 use crate::INTERNAL_ERROR_MSG;
27 use crate::{ArgFlags, ArgSettings};
28 
29 #[cfg(feature = "regex")]
30 use crate::builder::RegexRef;
31 
32 /// The abstract representation of a command line argument. Used to set all the options and
33 /// relationships that define a valid argument for the program.
34 ///
35 /// There are two methods for constructing [`Arg`]s, using the builder pattern and setting options
36 /// manually, or using a usage string which is far less verbose but has fewer options. You can also
37 /// use a combination of the two methods to achieve the best of both worlds.
38 ///
39 /// - [Basic API][crate::Arg#basic-api]
40 /// - [Value Handling][crate::Arg#value-handling]
41 /// - [Help][crate::Arg#help-1]
42 /// - [Advanced Argument Relations][crate::Arg#advanced-argument-relations]
43 /// - [Reflection][crate::Arg#reflection]
44 ///
45 /// # Examples
46 ///
47 /// ```rust
48 /// # use clap::{Arg, arg};
49 /// // Using the traditional builder pattern and setting each option manually
50 /// let cfg = Arg::new("config")
51 ///       .short('c')
52 ///       .long("config")
53 ///       .takes_value(true)
54 ///       .value_name("FILE")
55 ///       .help("Provides a config file to myprog");
56 /// // Using a usage string (setting a similar argument to the one above)
57 /// let input = arg!(-i --input <FILE> "Provides an input file to the program");
58 /// ```
59 #[allow(missing_debug_implementations)]
60 #[derive(Default, Clone)]
61 pub struct Arg<'help> {
62     pub(crate) id: Id,
63     pub(crate) provider: ArgProvider,
64     pub(crate) name: &'help str,
65     pub(crate) help: Option<&'help str>,
66     pub(crate) long_help: Option<&'help str>,
67     pub(crate) action: Option<ArgAction>,
68     pub(crate) value_parser: Option<super::ValueParser>,
69     pub(crate) blacklist: Vec<Id>,
70     pub(crate) settings: ArgFlags,
71     pub(crate) overrides: Vec<Id>,
72     pub(crate) groups: Vec<Id>,
73     pub(crate) requires: Vec<(ArgPredicate<'help>, Id)>,
74     pub(crate) r_ifs: Vec<(Id, &'help str)>,
75     pub(crate) r_ifs_all: Vec<(Id, &'help str)>,
76     pub(crate) r_unless: Vec<Id>,
77     pub(crate) r_unless_all: Vec<Id>,
78     pub(crate) short: Option<char>,
79     pub(crate) long: Option<&'help str>,
80     pub(crate) aliases: Vec<(&'help str, bool)>, // (name, visible)
81     pub(crate) short_aliases: Vec<(char, bool)>, // (name, visible)
82     pub(crate) disp_ord: DisplayOrder,
83     pub(crate) possible_vals: Vec<PossibleValue<'help>>,
84     pub(crate) val_names: Vec<&'help str>,
85     pub(crate) num_vals: Option<usize>,
86     pub(crate) max_occurs: Option<usize>,
87     pub(crate) max_vals: Option<usize>,
88     pub(crate) min_vals: Option<usize>,
89     pub(crate) validator: Option<Arc<Mutex<Validator<'help>>>>,
90     pub(crate) validator_os: Option<Arc<Mutex<ValidatorOs<'help>>>>,
91     pub(crate) val_delim: Option<char>,
92     pub(crate) default_vals: Vec<&'help OsStr>,
93     pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate<'help>, Option<&'help OsStr>)>,
94     pub(crate) default_missing_vals: Vec<&'help OsStr>,
95     #[cfg(feature = "env")]
96     pub(crate) env: Option<(&'help OsStr, Option<OsString>)>,
97     pub(crate) terminator: Option<&'help str>,
98     pub(crate) index: Option<usize>,
99     pub(crate) help_heading: Option<Option<&'help str>>,
100     pub(crate) value_hint: Option<ValueHint>,
101 }
102 
103 /// # Basic API
104 impl<'help> Arg<'help> {
105     /// Create a new [`Arg`] with a unique name.
106     ///
107     /// The name is used to check whether or not the argument was used at
108     /// runtime, get values, set relationships with other args, etc..
109     ///
110     /// **NOTE:** In the case of arguments that take values (i.e. [`Arg::takes_value(true)`])
111     /// and positional arguments (i.e. those without a preceding `-` or `--`) the name will also
112     /// be displayed when the user prints the usage/help information of the program.
113     ///
114     /// # Examples
115     ///
116     /// ```rust
117     /// # use clap::{Command, Arg};
118     /// Arg::new("config")
119     /// # ;
120     /// ```
121     /// [`Arg::takes_value(true)`]: Arg::takes_value()
new<S: Into<&'help str>>(n: S) -> Self122     pub fn new<S: Into<&'help str>>(n: S) -> Self {
123         Arg::default().name(n)
124     }
125 
126     /// Set the identifier used for referencing this argument in the clap API.
127     ///
128     /// See [`Arg::new`] for more details.
129     #[must_use]
id<S: Into<&'help str>>(mut self, n: S) -> Self130     pub fn id<S: Into<&'help str>>(mut self, n: S) -> Self {
131         let name = n.into();
132         self.id = Id::from(&*name);
133         self.name = name;
134         self
135     }
136 
137     /// Deprecated, replaced with [`Arg::id`] to avoid confusion with [`Arg::value_name`]
138     ///
139     /// Builder: replaced `arg.name(...)` with `arg.id(...)`
140     #[cfg_attr(
141         feature = "deprecated",
142         deprecated(
143             since = "3.1.0",
144             note = "Replaced with `Arg::id` to avoid confusion with `Arg::value_name`
145 
146 Builder: replaced `arg.name(...)` with `arg.id(...)`
147 "
148         )
149     )]
name<S: Into<&'help str>>(self, n: S) -> Self150     pub fn name<S: Into<&'help str>>(self, n: S) -> Self {
151         self.id(n)
152     }
153 
154     /// Sets the short version of the argument without the preceding `-`.
155     ///
156     /// By default `V` and `h` are used by the auto-generated `version` and `help` arguments,
157     /// respectively. You may use the uppercase `V` or lowercase `h` for your own arguments, in
158     /// which case `clap` simply will not assign those to the auto-generated
159     /// `version` or `help` arguments.
160     ///
161     /// # Examples
162     ///
163     /// When calling `short`, use a single valid UTF-8 character which will allow using the
164     /// argument via a single hyphen (`-`) such as `-c`:
165     ///
166     /// ```rust
167     /// # use clap::{Command, Arg};
168     /// let m = Command::new("prog")
169     ///     .arg(Arg::new("config")
170     ///         .short('c')
171     ///         .takes_value(true))
172     ///     .get_matches_from(vec![
173     ///         "prog", "-c", "file.toml"
174     ///     ]);
175     ///
176     /// assert_eq!(m.get_one::<String>("config").map(String::as_str), Some("file.toml"));
177     /// ```
178     #[inline]
179     #[must_use]
short(mut self, s: char) -> Self180     pub fn short(mut self, s: char) -> Self {
181         assert!(s != '-', "short option name cannot be `-`");
182 
183         self.short = Some(s);
184         self
185     }
186 
187     /// Sets the long version of the argument without the preceding `--`.
188     ///
189     /// By default `version` and `help` are used by the auto-generated `version` and `help`
190     /// arguments, respectively. You may use the word `version` or `help` for the long form of your
191     /// own arguments, in which case `clap` simply will not assign those to the auto-generated
192     /// `version` or `help` arguments.
193     ///
194     /// **NOTE:** Any leading `-` characters will be stripped
195     ///
196     /// # Examples
197     ///
198     /// To set `long` use a word containing valid UTF-8. If you supply a double leading
199     /// `--` such as `--config` they will be stripped. Hyphens in the middle of the word, however,
200     /// will *not* be stripped (i.e. `config-file` is allowed).
201     ///
202     /// Setting `long` allows using the argument via a double hyphen (`--`) such as `--config`
203     ///
204     /// ```rust
205     /// # use clap::{Command, Arg};
206     /// let m = Command::new("prog")
207     ///     .arg(Arg::new("cfg")
208     ///         .long("config")
209     ///         .takes_value(true))
210     ///     .get_matches_from(vec![
211     ///         "prog", "--config", "file.toml"
212     ///     ]);
213     ///
214     /// assert_eq!(m.get_one::<String>("cfg").map(String::as_str), Some("file.toml"));
215     /// ```
216     #[inline]
217     #[must_use]
long(mut self, l: &'help str) -> Self218     pub fn long(mut self, l: &'help str) -> Self {
219         #[cfg(feature = "unstable-v4")]
220         {
221             self.long = Some(l);
222         }
223         #[cfg(not(feature = "unstable-v4"))]
224         {
225             self.long = Some(l.trim_start_matches(|c| c == '-'));
226         }
227         self
228     }
229 
230     /// Add an alias, which functions as a hidden long flag.
231     ///
232     /// This is more efficient, and easier than creating multiple hidden arguments as one only
233     /// needs to check for the existence of this command, and not all variants.
234     ///
235     /// # Examples
236     ///
237     /// ```rust
238     /// # use clap::{Command, Arg};
239     /// let m = Command::new("prog")
240     ///             .arg(Arg::new("test")
241     ///             .long("test")
242     ///             .alias("alias")
243     ///             .takes_value(true))
244     ///        .get_matches_from(vec![
245     ///             "prog", "--alias", "cool"
246     ///         ]);
247     /// assert!(m.contains_id("test"));
248     /// assert_eq!(m.value_of("test"), Some("cool"));
249     /// ```
250     #[must_use]
alias<S: Into<&'help str>>(mut self, name: S) -> Self251     pub fn alias<S: Into<&'help str>>(mut self, name: S) -> Self {
252         self.aliases.push((name.into(), false));
253         self
254     }
255 
256     /// Add an alias, which functions as a hidden short flag.
257     ///
258     /// This is more efficient, and easier than creating multiple hidden arguments as one only
259     /// needs to check for the existence of this command, and not all variants.
260     ///
261     /// # Examples
262     ///
263     /// ```rust
264     /// # use clap::{Command, Arg};
265     /// let m = Command::new("prog")
266     ///             .arg(Arg::new("test")
267     ///             .short('t')
268     ///             .short_alias('e')
269     ///             .takes_value(true))
270     ///        .get_matches_from(vec![
271     ///             "prog", "-e", "cool"
272     ///         ]);
273     /// assert!(m.contains_id("test"));
274     /// assert_eq!(m.value_of("test"), Some("cool"));
275     /// ```
276     #[must_use]
short_alias(mut self, name: char) -> Self277     pub fn short_alias(mut self, name: char) -> Self {
278         assert!(name != '-', "short alias name cannot be `-`");
279 
280         self.short_aliases.push((name, false));
281         self
282     }
283 
284     /// Add aliases, which function as hidden long flags.
285     ///
286     /// This is more efficient, and easier than creating multiple hidden subcommands as one only
287     /// needs to check for the existence of this command, and not all variants.
288     ///
289     /// # Examples
290     ///
291     /// ```rust
292     /// # use clap::{Command, Arg, ArgAction};
293     /// let m = Command::new("prog")
294     ///             .arg(Arg::new("test")
295     ///                     .long("test")
296     ///                     .aliases(&["do-stuff", "do-tests", "tests"])
297     ///                     .action(ArgAction::SetTrue)
298     ///                     .help("the file to add")
299     ///                     .required(false))
300     ///             .get_matches_from(vec![
301     ///                 "prog", "--do-tests"
302     ///             ]);
303     /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
304     /// ```
305     #[must_use]
aliases(mut self, names: &[&'help str]) -> Self306     pub fn aliases(mut self, names: &[&'help str]) -> Self {
307         self.aliases.extend(names.iter().map(|&x| (x, false)));
308         self
309     }
310 
311     /// Add aliases, which functions as a hidden short flag.
312     ///
313     /// This is more efficient, and easier than creating multiple hidden subcommands as one only
314     /// needs to check for the existence of this command, and not all variants.
315     ///
316     /// # Examples
317     ///
318     /// ```rust
319     /// # use clap::{Command, Arg, ArgAction};
320     /// let m = Command::new("prog")
321     ///             .arg(Arg::new("test")
322     ///                     .short('t')
323     ///                     .short_aliases(&['e', 's'])
324     ///                     .action(ArgAction::SetTrue)
325     ///                     .help("the file to add")
326     ///                     .required(false))
327     ///             .get_matches_from(vec![
328     ///                 "prog", "-s"
329     ///             ]);
330     /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
331     /// ```
332     #[must_use]
short_aliases(mut self, names: &[char]) -> Self333     pub fn short_aliases(mut self, names: &[char]) -> Self {
334         for s in names {
335             assert!(s != &'-', "short alias name cannot be `-`");
336             self.short_aliases.push((*s, false));
337         }
338         self
339     }
340 
341     /// Add an alias, which functions as a visible long flag.
342     ///
343     /// Like [`Arg::alias`], except that they are visible inside the help message.
344     ///
345     /// # Examples
346     ///
347     /// ```rust
348     /// # use clap::{Command, Arg};
349     /// let m = Command::new("prog")
350     ///             .arg(Arg::new("test")
351     ///                 .visible_alias("something-awesome")
352     ///                 .long("test")
353     ///                 .takes_value(true))
354     ///        .get_matches_from(vec![
355     ///             "prog", "--something-awesome", "coffee"
356     ///         ]);
357     /// assert!(m.contains_id("test"));
358     /// assert_eq!(m.value_of("test"), Some("coffee"));
359     /// ```
360     /// [`Command::alias`]: Arg::alias()
361     #[must_use]
visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self362     pub fn visible_alias<S: Into<&'help str>>(mut self, name: S) -> Self {
363         self.aliases.push((name.into(), true));
364         self
365     }
366 
367     /// Add an alias, which functions as a visible short flag.
368     ///
369     /// Like [`Arg::short_alias`], except that they are visible inside the help message.
370     ///
371     /// # Examples
372     ///
373     /// ```rust
374     /// # use clap::{Command, Arg};
375     /// let m = Command::new("prog")
376     ///             .arg(Arg::new("test")
377     ///                 .long("test")
378     ///                 .visible_short_alias('t')
379     ///                 .takes_value(true))
380     ///        .get_matches_from(vec![
381     ///             "prog", "-t", "coffee"
382     ///         ]);
383     /// assert!(m.contains_id("test"));
384     /// assert_eq!(m.value_of("test"), Some("coffee"));
385     /// ```
386     #[must_use]
visible_short_alias(mut self, name: char) -> Self387     pub fn visible_short_alias(mut self, name: char) -> Self {
388         assert!(name != '-', "short alias name cannot be `-`");
389 
390         self.short_aliases.push((name, true));
391         self
392     }
393 
394     /// Add aliases, which function as visible long flags.
395     ///
396     /// Like [`Arg::aliases`], except that they are visible inside the help message.
397     ///
398     /// # Examples
399     ///
400     /// ```rust
401     /// # use clap::{Command, Arg, ArgAction};
402     /// let m = Command::new("prog")
403     ///             .arg(Arg::new("test")
404     ///                 .long("test")
405     ///                 .action(ArgAction::SetTrue)
406     ///                 .visible_aliases(&["something", "awesome", "cool"]))
407     ///        .get_matches_from(vec![
408     ///             "prog", "--awesome"
409     ///         ]);
410     /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
411     /// ```
412     /// [`Command::aliases`]: Arg::aliases()
413     #[must_use]
visible_aliases(mut self, names: &[&'help str]) -> Self414     pub fn visible_aliases(mut self, names: &[&'help str]) -> Self {
415         self.aliases.extend(names.iter().map(|n| (*n, true)));
416         self
417     }
418 
419     /// Add aliases, which function as visible short flags.
420     ///
421     /// Like [`Arg::short_aliases`], except that they are visible inside the help message.
422     ///
423     /// # Examples
424     ///
425     /// ```rust
426     /// # use clap::{Command, Arg, ArgAction};
427     /// let m = Command::new("prog")
428     ///             .arg(Arg::new("test")
429     ///                 .long("test")
430     ///                 .action(ArgAction::SetTrue)
431     ///                 .visible_short_aliases(&['t', 'e']))
432     ///        .get_matches_from(vec![
433     ///             "prog", "-t"
434     ///         ]);
435     /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
436     /// ```
437     #[must_use]
visible_short_aliases(mut self, names: &[char]) -> Self438     pub fn visible_short_aliases(mut self, names: &[char]) -> Self {
439         for n in names {
440             assert!(n != &'-', "short alias name cannot be `-`");
441             self.short_aliases.push((*n, true));
442         }
443         self
444     }
445 
446     /// Specifies the index of a positional argument **starting at** 1.
447     ///
448     /// **NOTE:** The index refers to position according to **other positional argument**. It does
449     /// not define position in the argument list as a whole.
450     ///
451     /// **NOTE:** You can optionally leave off the `index` method, and the index will be
452     /// assigned in order of evaluation. Utilizing the `index` method allows for setting
453     /// indexes out of order
454     ///
455     /// **NOTE:** This is only meant to be used for positional arguments and shouldn't to be used
456     /// with [`Arg::short`] or [`Arg::long`].
457     ///
458     /// **NOTE:** When utilized with [`Arg::multiple_values(true)`], only the **last** positional argument
459     /// may be defined as multiple (i.e. with the highest index)
460     ///
461     /// # Panics
462     ///
463     /// [`Command`] will [`panic!`] if indexes are skipped (such as defining `index(1)` and `index(3)`
464     /// but not `index(2)`, or a positional argument is defined as multiple and is not the highest
465     /// index
466     ///
467     /// # Examples
468     ///
469     /// ```rust
470     /// # use clap::{Command, Arg};
471     /// Arg::new("config")
472     ///     .index(1)
473     /// # ;
474     /// ```
475     ///
476     /// ```rust
477     /// # use clap::{Command, Arg};
478     /// let m = Command::new("prog")
479     ///     .arg(Arg::new("mode")
480     ///         .index(1))
481     ///     .arg(Arg::new("debug")
482     ///         .long("debug"))
483     ///     .get_matches_from(vec![
484     ///         "prog", "--debug", "fast"
485     ///     ]);
486     ///
487     /// assert!(m.contains_id("mode"));
488     /// assert_eq!(m.value_of("mode"), Some("fast")); // notice index(1) means "first positional"
489     ///                                               // *not* first argument
490     /// ```
491     /// [`Arg::short`]: Arg::short()
492     /// [`Arg::long`]: Arg::long()
493     /// [`Arg::multiple_values(true)`]: Arg::multiple_values()
494     /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html
495     /// [`Command`]: crate::Command
496     #[inline]
497     #[must_use]
index(mut self, idx: usize) -> Self498     pub fn index(mut self, idx: usize) -> Self {
499         self.index = Some(idx);
500         self
501     }
502 
503     /// This arg is the last, or final, positional argument (i.e. has the highest
504     /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args --
505     /// last_arg`).
506     ///
507     /// Even, if no other arguments are left to parse, if the user omits the `--` syntax
508     /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also
509     /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
510     /// the `--` syntax is otherwise not possible.
511     ///
512     /// **NOTE:** This will change the usage string to look like `$ prog [OPTIONS] [-- <ARG>]` if
513     /// `ARG` is marked as `.last(true)`.
514     ///
515     /// **NOTE:** This setting will imply [`crate::Command::dont_collapse_args_in_usage`] because failing
516     /// to set this can make the usage string very confusing.
517     ///
518     /// **NOTE**: This setting only applies to positional arguments, and has no effect on OPTIONS
519     ///
520     /// **NOTE:** Setting this requires [`Arg::takes_value`]
521     ///
522     /// **CAUTION:** Using this setting *and* having child subcommands is not
523     /// recommended with the exception of *also* using
524     /// [`crate::Command::args_conflicts_with_subcommands`]
525     /// (or [`crate::Command::subcommand_negates_reqs`] if the argument marked `Last` is also
526     /// marked [`Arg::required`])
527     ///
528     /// # Examples
529     ///
530     /// ```rust
531     /// # use clap::Arg;
532     /// Arg::new("args")
533     ///     .takes_value(true)
534     ///     .last(true)
535     /// # ;
536     /// ```
537     ///
538     /// Setting `last` ensures the arg has the highest [index] of all positional args
539     /// and requires that the `--` syntax be used to access it early.
540     ///
541     /// ```rust
542     /// # use clap::{Command, Arg};
543     /// let res = Command::new("prog")
544     ///     .arg(Arg::new("first"))
545     ///     .arg(Arg::new("second"))
546     ///     .arg(Arg::new("third")
547     ///         .takes_value(true)
548     ///         .last(true))
549     ///     .try_get_matches_from(vec![
550     ///         "prog", "one", "--", "three"
551     ///     ]);
552     ///
553     /// assert!(res.is_ok());
554     /// let m = res.unwrap();
555     /// assert_eq!(m.value_of("third"), Some("three"));
556     /// assert!(m.value_of("second").is_none());
557     /// ```
558     ///
559     /// Even if the positional argument marked `Last` is the only argument left to parse,
560     /// failing to use the `--` syntax results in an error.
561     ///
562     /// ```rust
563     /// # use clap::{Command, Arg, ErrorKind};
564     /// let res = Command::new("prog")
565     ///     .arg(Arg::new("first"))
566     ///     .arg(Arg::new("second"))
567     ///     .arg(Arg::new("third")
568     ///         .takes_value(true)
569     ///         .last(true))
570     ///     .try_get_matches_from(vec![
571     ///         "prog", "one", "two", "three"
572     ///     ]);
573     ///
574     /// assert!(res.is_err());
575     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
576     /// ```
577     /// [index]: Arg::index()
578     /// [`UnknownArgument`]: crate::ErrorKind::UnknownArgument
579     #[inline]
580     #[must_use]
last(self, yes: bool) -> Self581     pub fn last(self, yes: bool) -> Self {
582         if yes {
583             self.setting(ArgSettings::Last)
584         } else {
585             self.unset_setting(ArgSettings::Last)
586         }
587     }
588 
589     /// Specifies that the argument must be present.
590     ///
591     /// Required by default means it is required, when no other conflicting rules or overrides have
592     /// been evaluated. Conflicting rules take precedence over being required.
593     ///
594     /// **Pro tip:** Flags (i.e. not positional, or arguments that take values) shouldn't be
595     /// required by default. This is because if a flag were to be required, it should simply be
596     /// implied. No additional information is required from user. Flags by their very nature are
597     /// simply boolean on/off switches. The only time a user *should* be required to use a flag
598     /// is if the operation is destructive in nature, and the user is essentially proving to you,
599     /// "Yes, I know what I'm doing."
600     ///
601     /// # Examples
602     ///
603     /// ```rust
604     /// # use clap::Arg;
605     /// Arg::new("config")
606     ///     .required(true)
607     /// # ;
608     /// ```
609     ///
610     /// Setting required requires that the argument be used at runtime.
611     ///
612     /// ```rust
613     /// # use clap::{Command, Arg};
614     /// let res = Command::new("prog")
615     ///     .arg(Arg::new("cfg")
616     ///         .required(true)
617     ///         .takes_value(true)
618     ///         .long("config"))
619     ///     .try_get_matches_from(vec![
620     ///         "prog", "--config", "file.conf",
621     ///     ]);
622     ///
623     /// assert!(res.is_ok());
624     /// ```
625     ///
626     /// Setting required and then *not* supplying that argument at runtime is an error.
627     ///
628     /// ```rust
629     /// # use clap::{Command, Arg, ErrorKind};
630     /// let res = Command::new("prog")
631     ///     .arg(Arg::new("cfg")
632     ///         .required(true)
633     ///         .takes_value(true)
634     ///         .long("config"))
635     ///     .try_get_matches_from(vec![
636     ///         "prog"
637     ///     ]);
638     ///
639     /// assert!(res.is_err());
640     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
641     /// ```
642     #[inline]
643     #[must_use]
required(self, yes: bool) -> Self644     pub fn required(self, yes: bool) -> Self {
645         if yes {
646             self.setting(ArgSettings::Required)
647         } else {
648             self.unset_setting(ArgSettings::Required)
649         }
650     }
651 
652     /// Sets an argument that is required when this one is present
653     ///
654     /// i.e. when using this argument, the following argument *must* be present.
655     ///
656     /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required
657     ///
658     /// # Examples
659     ///
660     /// ```rust
661     /// # use clap::Arg;
662     /// Arg::new("config")
663     ///     .requires("input")
664     /// # ;
665     /// ```
666     ///
667     /// Setting [`Arg::requires(name)`] requires that the argument be used at runtime if the
668     /// defining argument is used. If the defining argument isn't used, the other argument isn't
669     /// required
670     ///
671     /// ```rust
672     /// # use clap::{Command, Arg};
673     /// let res = Command::new("prog")
674     ///     .arg(Arg::new("cfg")
675     ///         .takes_value(true)
676     ///         .requires("input")
677     ///         .long("config"))
678     ///     .arg(Arg::new("input"))
679     ///     .try_get_matches_from(vec![
680     ///         "prog"
681     ///     ]);
682     ///
683     /// assert!(res.is_ok()); // We didn't use cfg, so input wasn't required
684     /// ```
685     ///
686     /// Setting [`Arg::requires(name)`] and *not* supplying that argument is an error.
687     ///
688     /// ```rust
689     /// # use clap::{Command, Arg, ErrorKind};
690     /// let res = Command::new("prog")
691     ///     .arg(Arg::new("cfg")
692     ///         .takes_value(true)
693     ///         .requires("input")
694     ///         .long("config"))
695     ///     .arg(Arg::new("input"))
696     ///     .try_get_matches_from(vec![
697     ///         "prog", "--config", "file.conf"
698     ///     ]);
699     ///
700     /// assert!(res.is_err());
701     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
702     /// ```
703     /// [`Arg::requires(name)`]: Arg::requires()
704     /// [Conflicting]: Arg::conflicts_with()
705     /// [override]: Arg::overrides_with()
706     #[must_use]
requires<T: Key>(mut self, arg_id: T) -> Self707     pub fn requires<T: Key>(mut self, arg_id: T) -> Self {
708         self.requires.push((ArgPredicate::IsPresent, arg_id.into()));
709         self
710     }
711 
712     /// This argument must be passed alone; it conflicts with all other arguments.
713     ///
714     /// # Examples
715     ///
716     /// ```rust
717     /// # use clap::Arg;
718     /// Arg::new("config")
719     ///     .exclusive(true)
720     /// # ;
721     /// ```
722     ///
723     /// Setting an exclusive argument and having any other arguments present at runtime
724     /// is an error.
725     ///
726     /// ```rust
727     /// # use clap::{Command, Arg, ErrorKind};
728     /// let res = Command::new("prog")
729     ///     .arg(Arg::new("exclusive")
730     ///         .takes_value(true)
731     ///         .exclusive(true)
732     ///         .long("exclusive"))
733     ///     .arg(Arg::new("debug")
734     ///         .long("debug"))
735     ///     .arg(Arg::new("input"))
736     ///     .try_get_matches_from(vec![
737     ///         "prog", "--exclusive", "file.conf", "file.txt"
738     ///     ]);
739     ///
740     /// assert!(res.is_err());
741     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict);
742     /// ```
743     #[inline]
744     #[must_use]
exclusive(self, yes: bool) -> Self745     pub fn exclusive(self, yes: bool) -> Self {
746         if yes {
747             self.setting(ArgSettings::Exclusive)
748         } else {
749             self.unset_setting(ArgSettings::Exclusive)
750         }
751     }
752 
753     /// Specifies that an argument can be matched to all child [`Subcommand`]s.
754     ///
755     /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however
756     /// their values once a user uses them will be propagated back up to parents. In effect, this
757     /// means one should *define* all global arguments at the top level, however it doesn't matter
758     /// where the user *uses* the global argument.
759     ///
760     /// # Examples
761     ///
762     /// Assume an application with two subcommands, and you'd like to define a
763     /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't
764     /// want to clutter the source with three duplicate [`Arg`] definitions.
765     ///
766     /// ```rust
767     /// # use clap::{Command, Arg, ArgAction};
768     /// let m = Command::new("prog")
769     ///     .arg(Arg::new("verb")
770     ///         .long("verbose")
771     ///         .short('v')
772     ///         .action(ArgAction::SetTrue)
773     ///         .global(true))
774     ///     .subcommand(Command::new("test"))
775     ///     .subcommand(Command::new("do-stuff"))
776     ///     .get_matches_from(vec![
777     ///         "prog", "do-stuff", "--verbose"
778     ///     ]);
779     ///
780     /// assert_eq!(m.subcommand_name(), Some("do-stuff"));
781     /// let sub_m = m.subcommand_matches("do-stuff").unwrap();
782     /// assert_eq!(*sub_m.get_one::<bool>("verb").expect("defaulted by clap"), true);
783     /// ```
784     ///
785     /// [`Subcommand`]: crate::Subcommand
786     #[inline]
787     #[must_use]
global(self, yes: bool) -> Self788     pub fn global(self, yes: bool) -> Self {
789         if yes {
790             self.setting(ArgSettings::Global)
791         } else {
792             self.unset_setting(ArgSettings::Global)
793         }
794     }
795 
796     /// Deprecated, replaced with [`Arg::action`] ([Issue #3772](https://github.com/clap-rs/clap/issues/3772))
797     #[inline]
798     #[must_use]
799     #[cfg_attr(
800         feature = "deprecated",
801         deprecated(
802             since = "3.2.0",
803             note = "Replaced with `Arg::action` (Issue #3772)
804 
805 Builder: replace `arg.multiple_occurrences(true)` with `arg.action(ArgAction::Append)` when taking a value and `arg.action(ArgAction::Count)` with `matches.get_count` when not
806 "
807         )
808     )]
multiple_occurrences(self, yes: bool) -> Self809     pub fn multiple_occurrences(self, yes: bool) -> Self {
810         if yes {
811             self.setting(ArgSettings::MultipleOccurrences)
812         } else {
813             self.unset_setting(ArgSettings::MultipleOccurrences)
814         }
815     }
816 
817     /// Deprecated, for flags, this is replaced with `RangedI64ValueParser::range`
818     ///
819     /// Derive: `#[clap(action = ArgAction::Count, value_parser = value_parser!(u8).range(..max))]`
820     ///
821     /// Builder: `arg.action(ArgAction::Count).value_parser(value_parser!(u8).range(..max))`
822     #[inline]
823     #[must_use]
824     #[cfg_attr(
825         feature = "deprecated",
826         deprecated(
827             since = "3.2.0",
828             note = "For flags, this is replaced with `RangedI64ValueParser::range`
829 
830 Derive: `#[clap(action = ArgAction::Count, value_parser = value_parser!(u8).range(..max))]`
831 
832 Builder: `arg.action(ArgAction::Count).value_parser(value_parser!(u8).range(..max))`
833 "
834         )
835     )]
max_occurrences(mut self, qty: usize) -> Self836     pub fn max_occurrences(mut self, qty: usize) -> Self {
837         self.max_occurs = Some(qty);
838         if qty > 1 {
839             self.multiple_occurrences(true)
840         } else {
841             self
842         }
843     }
844 
845     /// Check if the [`ArgSettings`] variant is currently set on the argument.
846     ///
847     /// [`ArgSettings`]: crate::ArgSettings
848     #[inline]
is_set(&self, s: ArgSettings) -> bool849     pub fn is_set(&self, s: ArgSettings) -> bool {
850         self.settings.is_set(s)
851     }
852 
853     /// Apply a setting to the argument.
854     ///
855     /// See [`ArgSettings`] for a full list of possibilities and examples.
856     ///
857     /// # Examples
858     ///
859     /// ```no_run
860     /// # use clap::{Arg, ArgSettings};
861     /// Arg::new("config")
862     ///     .setting(ArgSettings::Required)
863     ///     .setting(ArgSettings::TakesValue)
864     /// # ;
865     /// ```
866     ///
867     /// ```no_run
868     /// # use clap::{Arg, ArgSettings};
869     /// Arg::new("config")
870     ///     .setting(ArgSettings::Required | ArgSettings::TakesValue)
871     /// # ;
872     /// ```
873     #[inline]
874     #[must_use]
setting<F>(mut self, setting: F) -> Self where F: Into<ArgFlags>,875     pub fn setting<F>(mut self, setting: F) -> Self
876     where
877         F: Into<ArgFlags>,
878     {
879         self.settings.insert(setting.into());
880         self
881     }
882 
883     /// Remove a setting from the argument.
884     ///
885     /// See [`ArgSettings`] for a full list of possibilities and examples.
886     ///
887     /// # Examples
888     ///
889     /// ```no_run
890     /// # use clap::{Arg, ArgSettings};
891     /// Arg::new("config")
892     ///     .unset_setting(ArgSettings::Required)
893     ///     .unset_setting(ArgSettings::TakesValue)
894     /// # ;
895     /// ```
896     ///
897     /// ```no_run
898     /// # use clap::{Arg, ArgSettings};
899     /// Arg::new("config")
900     ///     .unset_setting(ArgSettings::Required | ArgSettings::TakesValue)
901     /// # ;
902     /// ```
903     #[inline]
904     #[must_use]
unset_setting<F>(mut self, setting: F) -> Self where F: Into<ArgFlags>,905     pub fn unset_setting<F>(mut self, setting: F) -> Self
906     where
907         F: Into<ArgFlags>,
908     {
909         self.settings.remove(setting.into());
910         self
911     }
912 }
913 
914 /// # Value Handling
915 impl<'help> Arg<'help> {
916     /// Specifies that the argument takes a value at run time.
917     ///
918     /// **NOTE:** values for arguments may be specified in any of the following methods
919     ///
920     /// - Using a space such as `-o value` or `--option value`
921     /// - Using an equals and no space such as `-o=value` or `--option=value`
922     /// - Use a short and no space such as `-ovalue`
923     ///
924     /// **NOTE:** By default, args which allow [multiple values] are delimited by commas, meaning
925     /// `--option=val1,val2,val3` is three values for the `--option` argument. If you wish to
926     /// change the delimiter to another character you can use [`Arg::value_delimiter(char)`],
927     /// alternatively you can turn delimiting values **OFF** by using
928     /// [`Arg::use_value_delimiter(false)`][Arg::use_value_delimiter]
929     ///
930     /// # Examples
931     ///
932     /// ```rust
933     /// # use clap::{Command, Arg};
934     /// let m = Command::new("prog")
935     ///     .arg(Arg::new("mode")
936     ///         .long("mode")
937     ///         .takes_value(true))
938     ///     .get_matches_from(vec![
939     ///         "prog", "--mode", "fast"
940     ///     ]);
941     ///
942     /// assert!(m.contains_id("mode"));
943     /// assert_eq!(m.value_of("mode"), Some("fast"));
944     /// ```
945     /// [`Arg::value_delimiter(char)`]: Arg::value_delimiter()
946     /// [multiple values]: Arg::multiple_values
947     #[inline]
948     #[must_use]
takes_value(self, yes: bool) -> Self949     pub fn takes_value(self, yes: bool) -> Self {
950         if yes {
951             self.setting(ArgSettings::TakesValue)
952         } else {
953             self.unset_setting(ArgSettings::TakesValue)
954         }
955     }
956 
957     /// Specify the behavior when parsing an argument
958     ///
959     /// # Examples
960     ///
961     /// ```rust
962     /// # use clap::Command;
963     /// # use clap::Arg;
964     /// let cmd = Command::new("mycmd")
965     ///     .arg(
966     ///         Arg::new("flag")
967     ///             .long("flag")
968     ///             .action(clap::ArgAction::Set)
969     ///     );
970     ///
971     /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap();
972     /// assert!(matches.contains_id("flag"));
973     /// assert_eq!(matches.occurrences_of("flag"), 0);
974     /// assert_eq!(
975     ///     matches.get_many::<String>("flag").unwrap_or_default().map(|v| v.as_str()).collect::<Vec<_>>(),
976     ///     vec!["value"]
977     /// );
978     /// ```
979     #[inline]
980     #[must_use]
action(mut self, action: ArgAction) -> Self981     pub fn action(mut self, action: ArgAction) -> Self {
982         self.action = Some(action);
983         self
984     }
985 
986     /// Specify the type of the argument.
987     ///
988     /// This allows parsing and validating a value before storing it into
989     /// [`ArgMatches`][crate::ArgMatches].
990     ///
991     /// See also
992     /// - [`value_parser!`][crate::value_parser!] for auto-selecting a value parser for a given type
993     ///   - [`BoolishValueParser`][crate::builder::BoolishValueParser], and [`FalseyValueParser`][crate::builder::FalseyValueParser] for alternative `bool` implementations
994     ///   - [`NonEmptyStringValueParser`][crate::builder::NonEmptyStringValueParser] for basic validation for strings
995     /// - [`RangedI64ValueParser`][crate::builder::RangedI64ValueParser] and [`RangedU64ValueParser`][crate::builder::RangedU64ValueParser] for numeric ranges
996     /// - [`EnumValueParser`][crate::builder::EnumValueParser] and  [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values
997     /// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation
998     ///
999     /// ```rust
1000     /// let mut cmd = clap::Command::new("raw")
1001     ///     .arg(
1002     ///         clap::Arg::new("color")
1003     ///             .long("color")
1004     ///             .value_parser(["always", "auto", "never"])
1005     ///             .default_value("auto")
1006     ///     )
1007     ///     .arg(
1008     ///         clap::Arg::new("hostname")
1009     ///             .long("hostname")
1010     ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
1011     ///             .takes_value(true)
1012     ///             .required(true)
1013     ///     )
1014     ///     .arg(
1015     ///         clap::Arg::new("port")
1016     ///             .long("port")
1017     ///             .value_parser(clap::value_parser!(u16).range(3000..))
1018     ///             .takes_value(true)
1019     ///             .required(true)
1020     ///     );
1021     ///
1022     /// let m = cmd.try_get_matches_from_mut(
1023     ///     ["cmd", "--hostname", "rust-lang.org", "--port", "3001"]
1024     /// ).unwrap();
1025     ///
1026     /// let color: &String = m.get_one("color")
1027     ///     .expect("default");
1028     /// assert_eq!(color, "auto");
1029     ///
1030     /// let hostname: &String = m.get_one("hostname")
1031     ///     .expect("required");
1032     /// assert_eq!(hostname, "rust-lang.org");
1033     ///
1034     /// let port: u16 = *m.get_one("port")
1035     ///     .expect("required");
1036     /// assert_eq!(port, 3001);
1037     /// ```
value_parser(mut self, parser: impl Into<super::ValueParser>) -> Self1038     pub fn value_parser(mut self, parser: impl Into<super::ValueParser>) -> Self {
1039         self.value_parser = Some(parser.into());
1040         self
1041     }
1042 
1043     /// Specifies that the argument may have an unknown number of values
1044     ///
1045     /// Without any other settings, this argument may appear only *once*.
1046     ///
1047     /// For example, `--opt val1 val2` is allowed, but `--opt val1 val2 --opt val3` is not.
1048     ///
1049     /// **NOTE:** Setting this requires [`Arg::takes_value`].
1050     ///
1051     /// **WARNING:**
1052     ///
1053     /// Setting `multiple_values` for an argument that takes a value, but with no other details can
1054     /// be dangerous in some circumstances. Because multiple values are allowed,
1055     /// `--option val1 val2 val3` is perfectly valid. Be careful when designing a CLI where
1056     /// positional arguments are *also* expected as `clap` will continue parsing *values* until one
1057     /// of the following happens:
1058     ///
1059     /// - It reaches the [maximum number of values]
1060     /// - It reaches a [specific number of values]
1061     /// - It finds another flag or option (i.e. something that starts with a `-`)
1062     /// - It reaches a [value terminator][Arg::value_terminator] is reached
1063     ///
1064     /// Alternatively, [require a delimiter between values][Arg::require_delimiter].
1065     ///
1066     /// **WARNING:**
1067     ///
1068     /// When using args with `multiple_values` and [`subcommands`], one needs to consider the
1069     /// possibility of an argument value being the same as a valid subcommand. By default `clap` will
1070     /// parse the argument in question as a value *only if* a value is possible at that moment.
1071     /// Otherwise it will be parsed as a subcommand. In effect, this means using `multiple_values` with no
1072     /// additional parameters and a value that coincides with a subcommand name, the subcommand
1073     /// cannot be called unless another argument is passed between them.
1074     ///
1075     /// As an example, consider a CLI with an option `--ui-paths=<paths>...` and subcommand `signer`
1076     ///
1077     /// The following would be parsed as values to `--ui-paths`.
1078     ///
1079     /// ```text
1080     /// $ program --ui-paths path1 path2 signer
1081     /// ```
1082     ///
1083     /// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values
1084     /// until another argument is reached and it knows `--ui-paths` is done parsing.
1085     ///
1086     /// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding
1087     /// [`Arg::number_of_values(1)`] or using *only* [`ArgAction::Append`]. The following are all
1088     /// valid, and `signer` is parsed as a subcommand in the first case, but a value in the second
1089     /// case.
1090     ///
1091     /// ```text
1092     /// $ program --ui-paths path1 signer
1093     /// $ program --ui-paths path1 --ui-paths signer signer
1094     /// ```
1095     ///
1096     /// # Examples
1097     ///
1098     /// An example with options
1099     ///
1100     /// ```rust
1101     /// # use clap::{Command, Arg};
1102     /// let m = Command::new("prog")
1103     ///     .arg(Arg::new("file")
1104     ///         .takes_value(true)
1105     ///         .multiple_values(true)
1106     ///         .short('F'))
1107     ///     .get_matches_from(vec![
1108     ///         "prog", "-F", "file1", "file2", "file3"
1109     ///     ]);
1110     ///
1111     /// assert!(m.contains_id("file"));
1112     /// let files: Vec<_> = m.values_of("file").unwrap().collect();
1113     /// assert_eq!(files, ["file1", "file2", "file3"]);
1114     /// ```
1115     ///
1116     /// Although `multiple_values` has been specified, we cannot use the argument more than once.
1117     ///
1118     /// ```rust
1119     /// # use clap::{Command, Arg, ErrorKind};
1120     /// let res = Command::new("prog")
1121     ///     .arg(Arg::new("file")
1122     ///         .takes_value(true)
1123     ///         .multiple_values(true)
1124     ///         .short('F'))
1125     ///     .try_get_matches_from(vec![
1126     ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3"
1127     ///     ]);
1128     ///
1129     /// assert!(res.is_err());
1130     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnexpectedMultipleUsage)
1131     /// ```
1132     ///
1133     /// A common mistake is to define an option which allows multiple values, and a positional
1134     /// argument.
1135     ///
1136     /// ```rust
1137     /// # use clap::{Command, Arg};
1138     /// let m = Command::new("prog")
1139     ///     .arg(Arg::new("file")
1140     ///         .takes_value(true)
1141     ///         .multiple_values(true)
1142     ///         .short('F'))
1143     ///     .arg(Arg::new("word"))
1144     ///     .get_matches_from(vec![
1145     ///         "prog", "-F", "file1", "file2", "file3", "word"
1146     ///     ]);
1147     ///
1148     /// assert!(m.contains_id("file"));
1149     /// let files: Vec<_> = m.values_of("file").unwrap().collect();
1150     /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?!
1151     /// assert!(!m.contains_id("word")); // but we clearly used word!
1152     /// ```
1153     ///
1154     /// The problem is `clap` doesn't know when to stop parsing values for "files". This is further
1155     /// compounded by if we'd said `word -F file1 file2` it would have worked fine, so it would
1156     /// appear to only fail sometimes...not good!
1157     ///
1158     /// A solution for the example above is to limit how many values with a [maximum], or [specific]
1159     /// number, or to say [`ArgAction::Append`] is ok, but multiple values is not.
1160     ///
1161     /// ```rust
1162     /// # use clap::{Command, Arg, ArgAction};
1163     /// let m = Command::new("prog")
1164     ///     .arg(Arg::new("file")
1165     ///         .takes_value(true)
1166     ///         .action(ArgAction::Append)
1167     ///         .short('F'))
1168     ///     .arg(Arg::new("word"))
1169     ///     .get_matches_from(vec![
1170     ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word"
1171     ///     ]);
1172     ///
1173     /// assert!(m.contains_id("file"));
1174     /// let files: Vec<_> = m.values_of("file").unwrap().collect();
1175     /// assert_eq!(files, ["file1", "file2", "file3"]);
1176     /// assert!(m.contains_id("word"));
1177     /// assert_eq!(m.value_of("word"), Some("word"));
1178     /// ```
1179     ///
1180     /// As a final example, let's fix the above error and get a pretty message to the user :)
1181     ///
1182     /// ```rust
1183     /// # use clap::{Command, Arg, ErrorKind, ArgAction};
1184     /// let res = Command::new("prog")
1185     ///     .arg(Arg::new("file")
1186     ///         .takes_value(true)
1187     ///         .action(ArgAction::Append)
1188     ///         .short('F'))
1189     ///     .arg(Arg::new("word"))
1190     ///     .try_get_matches_from(vec![
1191     ///         "prog", "-F", "file1", "file2", "file3", "word"
1192     ///     ]);
1193     ///
1194     /// assert!(res.is_err());
1195     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1196     /// ```
1197     ///
1198     /// [`subcommands`]: crate::Command::subcommand()
1199     /// [`Arg::number_of_values(1)`]: Arg::number_of_values()
1200     /// [maximum number of values]: Arg::max_values()
1201     /// [specific number of values]: Arg::number_of_values()
1202     /// [maximum]: Arg::max_values()
1203     /// [specific]: Arg::number_of_values()
1204     #[inline]
1205     #[must_use]
multiple_values(self, yes: bool) -> Self1206     pub fn multiple_values(self, yes: bool) -> Self {
1207         if yes {
1208             self.setting(ArgSettings::MultipleValues)
1209         } else {
1210             self.unset_setting(ArgSettings::MultipleValues)
1211         }
1212     }
1213 
1214     /// The number of values allowed for this argument.
1215     ///
1216     /// For example, if you had a
1217     /// `-f <file>` argument where you wanted exactly 3 'files' you would set
1218     /// `.number_of_values(3)`, and this argument wouldn't be satisfied unless the user provided
1219     /// 3 and only 3 values.
1220     ///
1221     /// **NOTE:** Does *not* require [`Arg::multiple_occurrences(true)`] to be set. Setting
1222     /// [`Arg::multiple_occurrences(true)`] would allow `-f <file> <file> <file> -f <file> <file> <file>` where
1223     /// as *not* setting it would only allow one occurrence of this argument.
1224     ///
1225     /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] and [`Arg::multiple_values(true)`].
1226     ///
1227     /// # Examples
1228     ///
1229     /// ```rust
1230     /// # use clap::{Command, Arg};
1231     /// Arg::new("file")
1232     ///     .short('f')
1233     ///     .number_of_values(3);
1234     /// ```
1235     ///
1236     /// Not supplying the correct number of values is an error
1237     ///
1238     /// ```rust
1239     /// # use clap::{Command, Arg, ErrorKind};
1240     /// let res = Command::new("prog")
1241     ///     .arg(Arg::new("file")
1242     ///         .takes_value(true)
1243     ///         .number_of_values(2)
1244     ///         .short('F'))
1245     ///     .try_get_matches_from(vec![
1246     ///         "prog", "-F", "file1"
1247     ///     ]);
1248     ///
1249     /// assert!(res.is_err());
1250     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::WrongNumberOfValues);
1251     /// ```
1252     /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences()
1253     #[inline]
1254     #[must_use]
number_of_values(mut self, qty: usize) -> Self1255     pub fn number_of_values(mut self, qty: usize) -> Self {
1256         self.num_vals = Some(qty);
1257         self.takes_value(true).multiple_values(true)
1258     }
1259 
1260     /// The *maximum* number of values are for this argument.
1261     ///
1262     /// For example, if you had a
1263     /// `-f <file>` argument where you wanted up to 3 'files' you would set `.max_values(3)`, and
1264     /// this argument would be satisfied if the user provided, 1, 2, or 3 values.
1265     ///
1266     /// **NOTE:** This does *not* implicitly set [`Arg::multiple_occurrences(true)`]. This is because
1267     /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single
1268     /// occurrence with multiple values. For positional arguments this **does** set
1269     /// [`Arg::multiple_occurrences(true)`] because there is no way to determine the difference between multiple
1270     /// occurrences and multiple values.
1271     ///
1272     /// # Examples
1273     ///
1274     /// ```rust
1275     /// # use clap::{Command, Arg};
1276     /// Arg::new("file")
1277     ///     .short('f')
1278     ///     .max_values(3);
1279     /// ```
1280     ///
1281     /// Supplying less than the maximum number of values is allowed
1282     ///
1283     /// ```rust
1284     /// # use clap::{Command, Arg};
1285     /// let res = Command::new("prog")
1286     ///     .arg(Arg::new("file")
1287     ///         .takes_value(true)
1288     ///         .max_values(3)
1289     ///         .short('F'))
1290     ///     .try_get_matches_from(vec![
1291     ///         "prog", "-F", "file1", "file2"
1292     ///     ]);
1293     ///
1294     /// assert!(res.is_ok());
1295     /// let m = res.unwrap();
1296     /// let files: Vec<_> = m.values_of("file").unwrap().collect();
1297     /// assert_eq!(files, ["file1", "file2"]);
1298     /// ```
1299     ///
1300     /// Supplying more than the maximum number of values is an error
1301     ///
1302     /// ```rust
1303     /// # use clap::{Command, Arg, ErrorKind};
1304     /// let res = Command::new("prog")
1305     ///     .arg(Arg::new("file")
1306     ///         .takes_value(true)
1307     ///         .max_values(2)
1308     ///         .short('F'))
1309     ///     .try_get_matches_from(vec![
1310     ///         "prog", "-F", "file1", "file2", "file3"
1311     ///     ]);
1312     ///
1313     /// assert!(res.is_err());
1314     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1315     /// ```
1316     /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences()
1317     #[inline]
1318     #[must_use]
max_values(mut self, qty: usize) -> Self1319     pub fn max_values(mut self, qty: usize) -> Self {
1320         self.max_vals = Some(qty);
1321         self.takes_value(true).multiple_values(true)
1322     }
1323 
1324     /// The *minimum* number of values for this argument.
1325     ///
1326     /// For example, if you had a
1327     /// `-f <file>` argument where you wanted at least 2 'files' you would set
1328     /// `.min_values(2)`, and this argument would be satisfied if the user provided, 2 or more
1329     /// values.
1330     ///
1331     /// **NOTE:** This does not implicitly set [`Arg::multiple_occurrences(true)`]. This is because
1332     /// `-o val -o val` is multiple occurrences but a single value and `-o val1 val2` is a single
1333     /// occurrence with multiple values. For positional arguments this **does** set
1334     /// [`Arg::multiple_occurrences(true)`] because there is no way to determine the difference between multiple
1335     /// occurrences and multiple values.
1336     ///
1337     /// **NOTE:** Passing a non-zero value is not the same as specifying [`Arg::required(true)`].
1338     /// This is due to min and max validation only being performed for present arguments,
1339     /// marking them as required will thus perform validation and a min value of 1
1340     /// is unnecessary, ignored if not required.
1341     ///
1342     /// # Examples
1343     ///
1344     /// ```rust
1345     /// # use clap::{Command, Arg};
1346     /// Arg::new("file")
1347     ///     .short('f')
1348     ///     .min_values(3);
1349     /// ```
1350     ///
1351     /// Supplying more than the minimum number of values is allowed
1352     ///
1353     /// ```rust
1354     /// # use clap::{Command, Arg};
1355     /// let res = Command::new("prog")
1356     ///     .arg(Arg::new("file")
1357     ///         .takes_value(true)
1358     ///         .min_values(2)
1359     ///         .short('F'))
1360     ///     .try_get_matches_from(vec![
1361     ///         "prog", "-F", "file1", "file2", "file3"
1362     ///     ]);
1363     ///
1364     /// assert!(res.is_ok());
1365     /// let m = res.unwrap();
1366     /// let files: Vec<_> = m.values_of("file").unwrap().collect();
1367     /// assert_eq!(files, ["file1", "file2", "file3"]);
1368     /// ```
1369     ///
1370     /// Supplying less than the minimum number of values is an error
1371     ///
1372     /// ```rust
1373     /// # use clap::{Command, Arg, ErrorKind};
1374     /// let res = Command::new("prog")
1375     ///     .arg(Arg::new("file")
1376     ///         .takes_value(true)
1377     ///         .min_values(2)
1378     ///         .short('F'))
1379     ///     .try_get_matches_from(vec![
1380     ///         "prog", "-F", "file1"
1381     ///     ]);
1382     ///
1383     /// assert!(res.is_err());
1384     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::TooFewValues);
1385     /// ```
1386     /// [`Arg::multiple_occurrences(true)`]: Arg::multiple_occurrences()
1387     /// [`Arg::required(true)`]: Arg::required()
1388     #[inline]
1389     #[must_use]
min_values(mut self, qty: usize) -> Self1390     pub fn min_values(mut self, qty: usize) -> Self {
1391         self.min_vals = Some(qty);
1392         self.takes_value(true).multiple_values(true)
1393     }
1394 
1395     /// Placeholder for the argument's value in the help message / usage.
1396     ///
1397     /// This name is cosmetic only; the name is **not** used to access arguments.
1398     /// This setting can be very helpful when describing the type of input the user should be
1399     /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to
1400     /// use all capital letters for the value name.
1401     ///
1402     /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]
1403     ///
1404     /// # Examples
1405     ///
1406     /// ```rust
1407     /// # use clap::{Command, Arg};
1408     /// Arg::new("cfg")
1409     ///     .long("config")
1410     ///     .value_name("FILE")
1411     /// # ;
1412     /// ```
1413     ///
1414     /// ```rust
1415     /// # use clap::{Command, Arg};
1416     /// let m = Command::new("prog")
1417     ///     .arg(Arg::new("config")
1418     ///         .long("config")
1419     ///         .value_name("FILE")
1420     ///         .help("Some help text"))
1421     ///     .get_matches_from(vec![
1422     ///         "prog", "--help"
1423     ///     ]);
1424     /// ```
1425     /// Running the above program produces the following output
1426     ///
1427     /// ```text
1428     /// valnames
1429     ///
1430     /// USAGE:
1431     ///    valnames [OPTIONS]
1432     ///
1433     /// OPTIONS:
1434     ///     --config <FILE>     Some help text
1435     ///     -h, --help          Print help information
1436     ///     -V, --version       Print version information
1437     /// ```
1438     /// [option]: Arg::takes_value()
1439     /// [positional]: Arg::index()
1440     /// [`Arg::takes_value(true)`]: Arg::takes_value()
1441     #[inline]
1442     #[must_use]
value_name(self, name: &'help str) -> Self1443     pub fn value_name(self, name: &'help str) -> Self {
1444         self.value_names(&[name])
1445     }
1446 
1447     /// Placeholders for the argument's values in the help message / usage.
1448     ///
1449     /// These names are cosmetic only, used for help and usage strings only. The names are **not**
1450     /// used to access arguments. The values of the arguments are accessed in numeric order (i.e.
1451     /// if you specify two names `one` and `two` `one` will be the first matched value, `two` will
1452     /// be the second).
1453     ///
1454     /// This setting can be very helpful when describing the type of input the user should be
1455     /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to
1456     /// use all capital letters for the value name.
1457     ///
1458     /// **Pro Tip:** It may help to use [`Arg::next_line_help(true)`] if there are long, or
1459     /// multiple value names in order to not throw off the help text alignment of all options.
1460     ///
1461     /// **NOTE:** implicitly sets [`Arg::takes_value(true)`] and [`Arg::multiple_values(true)`].
1462     ///
1463     /// # Examples
1464     ///
1465     /// ```rust
1466     /// # use clap::{Command, Arg};
1467     /// Arg::new("speed")
1468     ///     .short('s')
1469     ///     .value_names(&["fast", "slow"]);
1470     /// ```
1471     ///
1472     /// ```rust
1473     /// # use clap::{Command, Arg};
1474     /// let m = Command::new("prog")
1475     ///     .arg(Arg::new("io")
1476     ///         .long("io-files")
1477     ///         .value_names(&["INFILE", "OUTFILE"]))
1478     ///     .get_matches_from(vec![
1479     ///         "prog", "--help"
1480     ///     ]);
1481     /// ```
1482     ///
1483     /// Running the above program produces the following output
1484     ///
1485     /// ```text
1486     /// valnames
1487     ///
1488     /// USAGE:
1489     ///    valnames [OPTIONS]
1490     ///
1491     /// OPTIONS:
1492     ///     -h, --help                       Print help information
1493     ///     --io-files <INFILE> <OUTFILE>    Some help text
1494     ///     -V, --version                    Print version information
1495     /// ```
1496     /// [`Arg::next_line_help(true)`]: Arg::next_line_help()
1497     /// [`Arg::number_of_values`]: Arg::number_of_values()
1498     /// [`Arg::takes_value(true)`]: Arg::takes_value()
1499     /// [`Arg::multiple_values(true)`]: Arg::multiple_values()
1500     #[must_use]
value_names(mut self, names: &[&'help str]) -> Self1501     pub fn value_names(mut self, names: &[&'help str]) -> Self {
1502         self.val_names = names.to_vec();
1503         self.takes_value(true)
1504     }
1505 
1506     /// Provide the shell a hint about how to complete this argument.
1507     ///
1508     /// See [`ValueHint`][crate::ValueHint] for more information.
1509     ///
1510     /// **NOTE:** implicitly sets [`Arg::takes_value(true)`].
1511     ///
1512     /// For example, to take a username as argument:
1513     ///
1514     /// ```
1515     /// # use clap::{Arg, ValueHint};
1516     /// Arg::new("user")
1517     ///     .short('u')
1518     ///     .long("user")
1519     ///     .value_hint(ValueHint::Username);
1520     /// ```
1521     ///
1522     /// To take a full command line and its arguments (for example, when writing a command wrapper):
1523     ///
1524     /// ```
1525     /// # use clap::{Command, Arg, ValueHint};
1526     /// Command::new("prog")
1527     ///     .trailing_var_arg(true)
1528     ///     .arg(
1529     ///         Arg::new("command")
1530     ///             .takes_value(true)
1531     ///             .multiple_values(true)
1532     ///             .value_hint(ValueHint::CommandWithArguments)
1533     ///     );
1534     /// ```
1535     #[must_use]
value_hint(mut self, value_hint: ValueHint) -> Self1536     pub fn value_hint(mut self, value_hint: ValueHint) -> Self {
1537         self.value_hint = Some(value_hint);
1538         self.takes_value(true)
1539     }
1540 
1541     /// Deprecated, replaced with [`Arg::value_parser(...)`]
1542     ///
1543     /// Derive: replace `#[clap(validator = ...)]` with `#[clap(value_parser = ...)]`
1544     ///
1545     /// Builder: replace `arg.validator(...)` with `arg.value_parser(...)` and `matches.value_of` with
1546     /// `matches.get_one::<T>` or `matches.values_of` with `matches.get_many::<T>`
1547     #[inline]
1548     #[must_use]
1549     #[cfg_attr(
1550         feature = "deprecated",
1551         deprecated(
1552             since = "3.2.0",
1553             note = "Replaced with `Arg::value_parser(...)`
1554 
1555 Derive: replace `#[clap(validator = <fn>)]` with `#[clap(value_parser = <fn>)]`
1556 
1557 Builder: replace `arg.validator(<fn>)` with `arg.value_parser(<fn>)` and `matches.value_of` with
1558 `matches.get_one::<T>` or `matches.values_of` with `matches.get_many::<T>`
1559 "
1560         )
1561     )]
validator<F, O, E>(mut self, mut f: F) -> Self where F: FnMut(&str) -> Result<O, E> + Send + 'help, E: Into<Box<dyn Error + Send + Sync + 'static>>,1562     pub fn validator<F, O, E>(mut self, mut f: F) -> Self
1563     where
1564         F: FnMut(&str) -> Result<O, E> + Send + 'help,
1565         E: Into<Box<dyn Error + Send + Sync + 'static>>,
1566     {
1567         self.validator = Some(Arc::new(Mutex::new(move |s: &str| {
1568             f(s).map(|_| ()).map_err(|e| e.into())
1569         })));
1570         self
1571     }
1572 
1573     /// Deprecated, replaced with [`Arg::value_parser(...)`]
1574     #[must_use]
1575     #[cfg_attr(
1576         feature = "deprecated",
1577         deprecated(
1578             since = "3.2.0",
1579             note = "Replaced with `Arg::value_parser(...)`
1580 
1581 Derive: replace `#[clap(validator = <fn>)]` with `#[clap(value_parser = <TypedValueParser>)]`
1582 
1583 Builder: replace `arg.validator(<fn>)` with `arg.value_parser(<TypedValueParser>)` and `matches.value_of_os` with
1584 `matches.get_one::<T>` or `matches.values_of_os` with `matches.get_many::<T>`
1585 "
1586         )
1587     )]
validator_os<F, O, E>(mut self, mut f: F) -> Self where F: FnMut(&OsStr) -> Result<O, E> + Send + 'help, E: Into<Box<dyn Error + Send + Sync + 'static>>,1588     pub fn validator_os<F, O, E>(mut self, mut f: F) -> Self
1589     where
1590         F: FnMut(&OsStr) -> Result<O, E> + Send + 'help,
1591         E: Into<Box<dyn Error + Send + Sync + 'static>>,
1592     {
1593         self.validator_os = Some(Arc::new(Mutex::new(move |s: &OsStr| {
1594             f(s).map(|_| ()).map_err(|e| e.into())
1595         })));
1596         self
1597     }
1598 
1599     /// Deprecated in [Issue #3743](https://github.com/clap-rs/clap/issues/3743), replaced with [`Arg::value_parser(...)`]
1600     ///
1601     /// Derive: replace `#[clap(validator_regex = ...)]` with `#[clap(value_parser = |s: &str| regex.is_match(s).then(|| s.to_owned()).ok_or_else(|| ...))]`
1602     ///
1603     /// Builder: replace `arg.validator_regex(...)` with `arg.value_parser(|s: &str| regex.is_match(s).then(|| s.to_owned()).ok_or_else(|| ...))`
1604     #[cfg_attr(
1605         feature = "deprecated",
1606         deprecated(
1607             since = "3.2.0",
1608             note = "Deprecated in Issue #3743; replaced with `Arg::value_parser(...)`
1609 
1610 Derive: replace `#[clap(validator_regex = ...)]` with `#[clap(value_parser = |s: &str| regex.is_match(s).then(|| s.to_owned()).ok_or_else(|| ...))]`
1611 
1612 Builder: replace `arg.validator_regex(...)` with `arg.value_parser(|s: &str| regex.is_match(s).then(|| s.to_owned()).ok_or_else(|| ...))`
1613 "
1614         )
1615     )]
1616     #[cfg(feature = "regex")]
1617     #[must_use]
validator_regex( self, regex: impl Into<RegexRef<'help>>, err_message: &'help str, ) -> Self1618     pub fn validator_regex(
1619         self,
1620         regex: impl Into<RegexRef<'help>>,
1621         err_message: &'help str,
1622     ) -> Self {
1623         let regex = regex.into();
1624         self.validator(move |s: &str| {
1625             if regex.is_match(s) {
1626                 Ok(())
1627             } else {
1628                 Err(err_message)
1629             }
1630         })
1631     }
1632 
1633     /// Deprecated, replaced with [`Arg::value_parser(PossibleValuesParser::new(...))`]
1634     ///
1635     /// Derive: replace `#[clap(possible_value = <1>, possible_value = <2>, ...)]` with `#[clap(value_parser = [<1>, <2>])]`.
1636     /// If the field is not a `String`, instead do `#[clap(value_parser = PossibleValueParser::new([<1>, <2>]).map(T::from_str))]`
1637     ///
1638     /// Builder: replace `arg.possible_value(<1>).possible_value(<2>) with `arg.value_parser([<1>, <2>])`
1639     #[cfg_attr(
1640         feature = "deprecated",
1641         deprecated(
1642             since = "3.2.0",
1643             note = "Replaced with `Arg::value_parser(PossibleValuesParser::new(...)).takes_value(true)`
1644 
1645 Derive: replace `#[clap(possible_value = <1>, possible_value = <2>, ...)]` with `#[clap(value_parser = [<1>, <2>])]`.
1646 If the field is not a `String`, instead do `#[clap(value_parser = PossibleValueParser::new([<1>, <2>]).map(T::from_str))]`
1647 
1648 Builder: replace `arg.possible_value(<1>).possible_value(<2>) with `arg.value_parser([<1>, <2>])`
1649 "
1650         )
1651     )]
1652     #[must_use]
possible_value<T>(mut self, value: T) -> Self where T: Into<PossibleValue<'help>>,1653     pub fn possible_value<T>(mut self, value: T) -> Self
1654     where
1655         T: Into<PossibleValue<'help>>,
1656     {
1657         self.possible_vals.push(value.into());
1658         self.takes_value(true)
1659     }
1660 
1661     /// Deprecated, replaced with [`Arg::value_parser(PossibleValuesParser::new(...))`]
1662     ///
1663     /// Derive: replace `#[clap(possible_values = [<1>, <2>])]` with `#[clap(value_parser = [<1>, <2>])]`.
1664     /// If the field is not a `String`, instead do `#[clap(value_parser = PossibleValueParser::new([<1>, <2>]).map(T::from_str))]`
1665     ///
1666     /// Builder: replace `arg.possible_values([<1>, <2>) with `arg.value_parser([<1>, <2>])`
1667     #[cfg_attr(
1668         feature = "deprecated",
1669         deprecated(
1670             since = "3.2.0",
1671             note = "Replaced with `Arg::value_parser(PossibleValuesParser::new(...)).takes_value(true)`
1672 
1673 Derive: replace `#[clap(possible_values = [<1>, <2>])]` with `#[clap(value_parser = [<1>, <2>])]`.
1674 If the field is not a `String`, instead do `#[clap(value_parser = PossibleValueParser::new([<1>, <2>]).map(T::from_str))]`
1675 
1676 Builder: replace `arg.possible_values([<1>, <2>) with `arg.value_parser([<1>, <2>])`
1677 "
1678         )
1679     )]
1680     #[must_use]
possible_values<I, T>(mut self, values: I) -> Self where I: IntoIterator<Item = T>, T: Into<PossibleValue<'help>>,1681     pub fn possible_values<I, T>(mut self, values: I) -> Self
1682     where
1683         I: IntoIterator<Item = T>,
1684         T: Into<PossibleValue<'help>>,
1685     {
1686         self.possible_vals
1687             .extend(values.into_iter().map(|value| value.into()));
1688         self.takes_value(true)
1689     }
1690 
1691     /// Match values against [`Arg::possible_values`] without matching case.
1692     ///
1693     /// When other arguments are conditionally required based on the
1694     /// value of a case-insensitive argument, the equality check done
1695     /// by [`Arg::required_if_eq`], [`Arg::required_if_eq_any`], or
1696     /// [`Arg::required_if_eq_all`] is case-insensitive.
1697     ///
1698     ///
1699     /// **NOTE:** Setting this requires [`Arg::takes_value`]
1700     ///
1701     /// **NOTE:** To do unicode case folding, enable the `unicode` feature flag.
1702     ///
1703     /// # Examples
1704     ///
1705     /// ```rust
1706     /// # use clap::{Command, Arg};
1707     /// let m = Command::new("pv")
1708     ///     .arg(Arg::new("option")
1709     ///         .long("option")
1710     ///         .takes_value(true)
1711     ///         .ignore_case(true)
1712     ///         .value_parser(["test123"]))
1713     ///     .get_matches_from(vec![
1714     ///         "pv", "--option", "TeSt123",
1715     ///     ]);
1716     ///
1717     /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
1718     /// ```
1719     ///
1720     /// This setting also works when multiple values can be defined:
1721     ///
1722     /// ```rust
1723     /// # use clap::{Command, Arg};
1724     /// let m = Command::new("pv")
1725     ///     .arg(Arg::new("option")
1726     ///         .short('o')
1727     ///         .long("option")
1728     ///         .takes_value(true)
1729     ///         .ignore_case(true)
1730     ///         .multiple_values(true)
1731     ///         .value_parser(["test123", "test321"]))
1732     ///     .get_matches_from(vec![
1733     ///         "pv", "--option", "TeSt123", "teST123", "tESt321"
1734     ///     ]);
1735     ///
1736     /// let matched_vals = m.values_of("option").unwrap().collect::<Vec<_>>();
1737     /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
1738     /// ```
1739     #[inline]
1740     #[must_use]
ignore_case(self, yes: bool) -> Self1741     pub fn ignore_case(self, yes: bool) -> Self {
1742         if yes {
1743             self.setting(ArgSettings::IgnoreCase)
1744         } else {
1745             self.unset_setting(ArgSettings::IgnoreCase)
1746         }
1747     }
1748 
1749     /// Allows values which start with a leading hyphen (`-`)
1750     ///
1751     /// **NOTE:** Setting this requires [`Arg::takes_value`]
1752     ///
1753     /// **WARNING**: Take caution when using this setting combined with
1754     /// [`Arg::multiple_values`], as this becomes ambiguous `$ prog --arg -- -- val`. All
1755     /// three `--, --, val` will be values when the user may have thought the second `--` would
1756     /// constitute the normal, "Only positional args follow" idiom. To fix this, consider using
1757     /// [`Arg::multiple_occurrences`] which only allows a single value at a time.
1758     ///
1759     /// **WARNING**: When building your CLIs, consider the effects of allowing leading hyphens and
1760     /// the user passing in a value that matches a valid short. For example, `prog -opt -F` where
1761     /// `-F` is supposed to be a value, yet `-F` is *also* a valid short for another arg.
1762     /// Care should be taken when designing these args. This is compounded by the ability to "stack"
1763     /// short args. I.e. if `-val` is supposed to be a value, but `-v`, `-a`, and `-l` are all valid
1764     /// shorts.
1765     ///
1766     /// # Examples
1767     ///
1768     /// ```rust
1769     /// # use clap::{Command, Arg};
1770     /// let m = Command::new("prog")
1771     ///     .arg(Arg::new("pat")
1772     ///         .takes_value(true)
1773     ///         .allow_hyphen_values(true)
1774     ///         .long("pattern"))
1775     ///     .get_matches_from(vec![
1776     ///         "prog", "--pattern", "-file"
1777     ///     ]);
1778     ///
1779     /// assert_eq!(m.value_of("pat"), Some("-file"));
1780     /// ```
1781     ///
1782     /// Not setting `Arg::allow_hyphen_values(true)` and supplying a value which starts with a
1783     /// hyphen is an error.
1784     ///
1785     /// ```rust
1786     /// # use clap::{Command, Arg, ErrorKind};
1787     /// let res = Command::new("prog")
1788     ///     .arg(Arg::new("pat")
1789     ///         .takes_value(true)
1790     ///         .long("pattern"))
1791     ///     .try_get_matches_from(vec![
1792     ///         "prog", "--pattern", "-file"
1793     ///     ]);
1794     ///
1795     /// assert!(res.is_err());
1796     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1797     /// ```
1798     /// [`Arg::number_of_values(1)`]: Arg::number_of_values()
1799     #[inline]
1800     #[must_use]
allow_hyphen_values(self, yes: bool) -> Self1801     pub fn allow_hyphen_values(self, yes: bool) -> Self {
1802         if yes {
1803             self.setting(ArgSettings::AllowHyphenValues)
1804         } else {
1805             self.unset_setting(ArgSettings::AllowHyphenValues)
1806         }
1807     }
1808 
1809     /// Deprecated, replaced with [`value_parser`][Arg::value_parser]
1810     ///
1811     /// Derive: replace `#[clap(allow_invalid_utf8 = true)]` with `#[clap(action)]` (which opts-in to the
1812     /// new clap v4 behavior which gets the type via `value_parser!`)
1813     ///
1814     /// Builder: replace `arg.allow_invalid_utf8(true)` with `arg.value_parser(value_parser!(T))` where
1815     /// `T` is the type of interest, like `OsString` or `PathBuf`, and `matches.value_of_os` with
1816     /// `matches.get_one::<T>` or `matches.values_of_os` with `matches.get_many::<T>`
1817     #[inline]
1818     #[must_use]
1819     #[cfg_attr(
1820         feature = "deprecated",
1821         deprecated(
1822             since = "3.2.0",
1823             note = "Replaced with `value_parser`
1824 
1825 Derive: replace `#[clap(allow_invalid_utf8 = true)]` with `#[clap(action)]` (which opts-in to the
1826 new clap v4 behavior which gets the type via `value_parser!`)
1827 
1828 Builder: replace `arg.allow_invalid_utf8(true)` with `arg.value_parser(value_parser!(T))` where
1829 `T` is the type of interest, like `OsString` or `PathBuf`, and `matches.value_of_os` with
1830 `matches.get_one::<T>` or `matches.values_of_os` with `matches.get_many::<T>`
1831 "
1832         )
1833     )]
allow_invalid_utf8(self, yes: bool) -> Self1834     pub fn allow_invalid_utf8(self, yes: bool) -> Self {
1835         if yes {
1836             self.setting(ArgSettings::AllowInvalidUtf8)
1837         } else {
1838             self.unset_setting(ArgSettings::AllowInvalidUtf8)
1839         }
1840     }
1841 
1842     /// Deprecated, replaced with [`Arg::value_parser(NonEmptyStringValueParser::new())`]
1843     ///
1844     /// Derive: replace `#[clap(forbid_empty_values = true)]` with `#[clap(value_parser = NonEmptyStringValueParser::new())]`
1845     ///
1846     /// Builder: replace `arg.forbid_empty_values(true)` with `arg.value_parser(NonEmptyStringValueParser::new())`
1847     #[inline]
1848     #[must_use]
1849     #[cfg_attr(
1850         feature = "deprecated",
1851         deprecated(
1852             since = "3.2.0",
1853             note = "Replaced with `Arg::value_parser(NonEmptyStringValueParser::new())`
1854 
1855 Derive: replace `#[clap(forbid_empty_values = true)]` with `#[clap(value_parser = NonEmptyStringValueParser::new())]`
1856 
1857 Builder: replace `arg.forbid_empty_values(true)` with `arg.value_parser(NonEmptyStringValueParser::new())`
1858 "
1859         )
1860     )]
forbid_empty_values(self, yes: bool) -> Self1861     pub fn forbid_empty_values(self, yes: bool) -> Self {
1862         if yes {
1863             self.setting(ArgSettings::ForbidEmptyValues)
1864         } else {
1865             self.unset_setting(ArgSettings::ForbidEmptyValues)
1866         }
1867     }
1868 
1869     /// Requires that options use the `--option=val` syntax
1870     ///
1871     /// i.e. an equals between the option and associated value.
1872     ///
1873     /// **NOTE:** Setting this requires [`Arg::takes_value`]
1874     ///
1875     /// # Examples
1876     ///
1877     /// Setting `require_equals` requires that the option have an equals sign between
1878     /// it and the associated value.
1879     ///
1880     /// ```rust
1881     /// # use clap::{Command, Arg};
1882     /// let res = Command::new("prog")
1883     ///     .arg(Arg::new("cfg")
1884     ///         .takes_value(true)
1885     ///         .require_equals(true)
1886     ///         .long("config"))
1887     ///     .try_get_matches_from(vec![
1888     ///         "prog", "--config=file.conf"
1889     ///     ]);
1890     ///
1891     /// assert!(res.is_ok());
1892     /// ```
1893     ///
1894     /// Setting `require_equals` and *not* supplying the equals will cause an
1895     /// error.
1896     ///
1897     /// ```rust
1898     /// # use clap::{Command, Arg, ErrorKind};
1899     /// let res = Command::new("prog")
1900     ///     .arg(Arg::new("cfg")
1901     ///         .takes_value(true)
1902     ///         .require_equals(true)
1903     ///         .long("config"))
1904     ///     .try_get_matches_from(vec![
1905     ///         "prog", "--config", "file.conf"
1906     ///     ]);
1907     ///
1908     /// assert!(res.is_err());
1909     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
1910     /// ```
1911     #[inline]
1912     #[must_use]
require_equals(self, yes: bool) -> Self1913     pub fn require_equals(self, yes: bool) -> Self {
1914         if yes {
1915             self.setting(ArgSettings::RequireEquals)
1916         } else {
1917             self.unset_setting(ArgSettings::RequireEquals)
1918         }
1919     }
1920 
1921     /// Specifies that an argument should allow grouping of multiple values via a
1922     /// delimiter.
1923     ///
1924     /// i.e. should `--option=val1,val2,val3` be parsed as three values (`val1`, `val2`,
1925     /// and `val3`) or as a single value (`val1,val2,val3`). Defaults to using `,` (comma) as the
1926     /// value delimiter for all arguments that accept values (options and positional arguments)
1927     ///
1928     /// **NOTE:** When this setting is used, it will default [`Arg::value_delimiter`]
1929     /// to the comma `,`.
1930     ///
1931     /// **NOTE:** Implicitly sets [`Arg::takes_value`]
1932     ///
1933     /// # Examples
1934     ///
1935     /// The following example shows the default behavior.
1936     ///
1937     /// ```rust
1938     /// # use clap::{Command, Arg};
1939     /// let delims = Command::new("prog")
1940     ///     .arg(Arg::new("option")
1941     ///         .long("option")
1942     ///         .use_value_delimiter(true)
1943     ///         .takes_value(true))
1944     ///     .get_matches_from(vec![
1945     ///         "prog", "--option=val1,val2,val3",
1946     ///     ]);
1947     ///
1948     /// assert!(delims.contains_id("option"));
1949     /// assert_eq!(delims.values_of("option").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
1950     /// ```
1951     /// The next example shows the difference when turning delimiters off. This is the default
1952     /// behavior
1953     ///
1954     /// ```rust
1955     /// # use clap::{Command, Arg};
1956     /// let nodelims = Command::new("prog")
1957     ///     .arg(Arg::new("option")
1958     ///         .long("option")
1959     ///         .takes_value(true))
1960     ///     .get_matches_from(vec![
1961     ///         "prog", "--option=val1,val2,val3",
1962     ///     ]);
1963     ///
1964     /// assert!(nodelims.contains_id("option"));
1965     /// assert_eq!(nodelims.value_of("option").unwrap(), "val1,val2,val3");
1966     /// ```
1967     /// [`Arg::value_delimiter`]: Arg::value_delimiter()
1968     #[inline]
1969     #[must_use]
use_value_delimiter(mut self, yes: bool) -> Self1970     pub fn use_value_delimiter(mut self, yes: bool) -> Self {
1971         if yes {
1972             if self.val_delim.is_none() {
1973                 self.val_delim = Some(',');
1974             }
1975             self.takes_value(true)
1976                 .setting(ArgSettings::UseValueDelimiter)
1977         } else {
1978             self.val_delim = None;
1979             self.unset_setting(ArgSettings::UseValueDelimiter)
1980         }
1981     }
1982 
1983     /// Deprecated, replaced with [`Arg::use_value_delimiter`]
1984     ///
1985     /// Derive: replace `#[clap(use_delimiter = true)]` with `#[clap(use_value_delimiter = true)]`
1986     ///
1987     /// Builder: replace `arg.use_delimiter(true)` with `arg.use_value_delimiter(true)`
1988     #[inline]
1989     #[must_use]
1990     #[cfg_attr(
1991         feature = "deprecated",
1992         deprecated(
1993             since = "3.1.0",
1994             note = "Replaced with `Arg::use_value_delimiter`
1995 
1996 Derive: replace `#[clap(use_delimiter = true)]` with `#[clap(use_value_delimiter = true)]`
1997 
1998 Builder: replace `arg.use_delimiter(true)` with `arg.use_value_delimiter(true)`
1999 "
2000         )
2001     )]
use_delimiter(self, yes: bool) -> Self2002     pub fn use_delimiter(self, yes: bool) -> Self {
2003         self.use_value_delimiter(yes)
2004     }
2005 
2006     /// Separator between the arguments values, defaults to `,` (comma).
2007     ///
2008     /// **NOTE:** implicitly sets [`Arg::use_value_delimiter(true)`]
2009     ///
2010     /// **NOTE:** implicitly sets [`Arg::takes_value(true)`]
2011     ///
2012     /// # Examples
2013     ///
2014     /// ```rust
2015     /// # use clap::{Command, Arg};
2016     /// let m = Command::new("prog")
2017     ///     .arg(Arg::new("config")
2018     ///         .short('c')
2019     ///         .long("config")
2020     ///         .value_delimiter(';'))
2021     ///     .get_matches_from(vec![
2022     ///         "prog", "--config=val1;val2;val3"
2023     ///     ]);
2024     ///
2025     /// assert_eq!(m.values_of("config").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"])
2026     /// ```
2027     /// [`Arg::use_value_delimiter(true)`]: Arg::use_value_delimiter()
2028     /// [`Arg::takes_value(true)`]: Arg::takes_value()
2029     #[inline]
2030     #[must_use]
value_delimiter(mut self, d: char) -> Self2031     pub fn value_delimiter(mut self, d: char) -> Self {
2032         self.val_delim = Some(d);
2033         self.takes_value(true).use_value_delimiter(true)
2034     }
2035 
2036     /// Specifies that *multiple values* may only be set using the delimiter.
2037     ///
2038     /// This means if an option is encountered, and no delimiter is found, it is assumed that no
2039     /// additional values for that option follow. This is unlike the default, where it is generally
2040     /// assumed that more values will follow regardless of whether or not a delimiter is used.
2041     ///
2042     /// **NOTE:** The default is `false`.
2043     ///
2044     /// **NOTE:** Setting this requires [`Arg::use_value_delimiter`] and
2045     /// [`Arg::takes_value`]
2046     ///
2047     /// **NOTE:** It's a good idea to inform the user that use of a delimiter is required, either
2048     /// through help text or other means.
2049     ///
2050     /// # Examples
2051     ///
2052     /// These examples demonstrate what happens when `require_delimiter(true)` is used. Notice
2053     /// everything works in this first example, as we use a delimiter, as expected.
2054     ///
2055     /// ```rust
2056     /// # use clap::{Command, Arg};
2057     /// let delims = Command::new("prog")
2058     ///     .arg(Arg::new("opt")
2059     ///         .short('o')
2060     ///         .takes_value(true)
2061     ///         .use_value_delimiter(true)
2062     ///         .require_delimiter(true)
2063     ///         .multiple_values(true))
2064     ///     .get_matches_from(vec![
2065     ///         "prog", "-o", "val1,val2,val3",
2066     ///     ]);
2067     ///
2068     /// assert!(delims.contains_id("opt"));
2069     /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
2070     /// ```
2071     ///
2072     /// In this next example, we will *not* use a delimiter. Notice it's now an error.
2073     ///
2074     /// ```rust
2075     /// # use clap::{Command, Arg, ErrorKind};
2076     /// let res = Command::new("prog")
2077     ///     .arg(Arg::new("opt")
2078     ///         .short('o')
2079     ///         .takes_value(true)
2080     ///         .use_value_delimiter(true)
2081     ///         .require_delimiter(true))
2082     ///     .try_get_matches_from(vec![
2083     ///         "prog", "-o", "val1", "val2", "val3",
2084     ///     ]);
2085     ///
2086     /// assert!(res.is_err());
2087     /// let err = res.unwrap_err();
2088     /// assert_eq!(err.kind(), ErrorKind::UnknownArgument);
2089     /// ```
2090     ///
2091     /// What's happening is `-o` is getting `val1`, and because delimiters are required yet none
2092     /// were present, it stops parsing `-o`. At this point it reaches `val2` and because no
2093     /// positional arguments have been defined, it's an error of an unexpected argument.
2094     ///
2095     /// In this final example, we contrast the above with `clap`'s default behavior where the above
2096     /// is *not* an error.
2097     ///
2098     /// ```rust
2099     /// # use clap::{Command, Arg};
2100     /// let delims = Command::new("prog")
2101     ///     .arg(Arg::new("opt")
2102     ///         .short('o')
2103     ///         .takes_value(true)
2104     ///         .multiple_values(true))
2105     ///     .get_matches_from(vec![
2106     ///         "prog", "-o", "val1", "val2", "val3",
2107     ///     ]);
2108     ///
2109     /// assert!(delims.contains_id("opt"));
2110     /// assert_eq!(delims.values_of("opt").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"]);
2111     /// ```
2112     #[inline]
2113     #[must_use]
require_value_delimiter(self, yes: bool) -> Self2114     pub fn require_value_delimiter(self, yes: bool) -> Self {
2115         if yes {
2116             self.setting(ArgSettings::RequireDelimiter)
2117         } else {
2118             self.unset_setting(ArgSettings::RequireDelimiter)
2119         }
2120     }
2121 
2122     /// Deprecated, replaced with [`Arg::require_value_delimiter`]
2123     ///
2124     /// Derive: replace `#[clap(require_delimiter = true)]` with `#[clap(require_value_delimiter = true)]`
2125     ///
2126     /// Builder: replace `arg.require_delimiter(true)` with `arg.require_value_delimiter(true)`
2127     #[inline]
2128     #[must_use]
2129     #[cfg_attr(
2130         feature = "deprecated",
2131         deprecated(
2132             since = "3.1.0",
2133             note = "Replaced with `Arg::require_value_delimiter`
2134 
2135 Derive: replace `#[clap(require_delimiter = true)]` with `#[clap(require_value_delimiter = true)]`
2136 
2137 Builder: replace `arg.require_delimiter(true)` with `arg.require_value_delimiter(true)`
2138 "
2139         )
2140     )]
require_delimiter(self, yes: bool) -> Self2141     pub fn require_delimiter(self, yes: bool) -> Self {
2142         self.require_value_delimiter(yes)
2143     }
2144 
2145     /// Sentinel to **stop** parsing multiple values of a give argument.
2146     ///
2147     /// By default when
2148     /// one sets [`multiple_values(true)`] on an argument, clap will continue parsing values for that
2149     /// argument until it reaches another valid argument, or one of the other more specific settings
2150     /// for multiple values is used (such as [`min_values`], [`max_values`] or
2151     /// [`number_of_values`]).
2152     ///
2153     /// **NOTE:** This setting only applies to [options] and [positional arguments]
2154     ///
2155     /// **NOTE:** When the terminator is passed in on the command line, it is **not** stored as one
2156     /// of the values
2157     ///
2158     /// # Examples
2159     ///
2160     /// ```rust
2161     /// # use clap::{Command, Arg};
2162     /// Arg::new("vals")
2163     ///     .takes_value(true)
2164     ///     .multiple_values(true)
2165     ///     .value_terminator(";")
2166     /// # ;
2167     /// ```
2168     ///
2169     /// The following example uses two arguments, a sequence of commands, and the location in which
2170     /// to perform them
2171     ///
2172     /// ```rust
2173     /// # use clap::{Command, Arg};
2174     /// let m = Command::new("prog")
2175     ///     .arg(Arg::new("cmds")
2176     ///         .takes_value(true)
2177     ///         .multiple_values(true)
2178     ///         .allow_hyphen_values(true)
2179     ///         .value_terminator(";"))
2180     ///     .arg(Arg::new("location"))
2181     ///     .get_matches_from(vec![
2182     ///         "prog", "find", "-type", "f", "-name", "special", ";", "/home/clap"
2183     ///     ]);
2184     /// let cmds: Vec<_> = m.values_of("cmds").unwrap().collect();
2185     /// assert_eq!(&cmds, &["find", "-type", "f", "-name", "special"]);
2186     /// assert_eq!(m.value_of("location"), Some("/home/clap"));
2187     /// ```
2188     /// [options]: Arg::takes_value()
2189     /// [positional arguments]: Arg::index()
2190     /// [`multiple_values(true)`]: Arg::multiple_values()
2191     /// [`min_values`]: Arg::min_values()
2192     /// [`number_of_values`]: Arg::number_of_values()
2193     /// [`max_values`]: Arg::max_values()
2194     #[inline]
2195     #[must_use]
value_terminator(mut self, term: &'help str) -> Self2196     pub fn value_terminator(mut self, term: &'help str) -> Self {
2197         self.terminator = Some(term);
2198         self.takes_value(true)
2199     }
2200 
2201     /// Consume all following arguments.
2202     ///
2203     /// Do not be parse them individually, but rather pass them in entirety.
2204     ///
2205     /// It is worth noting that setting this requires all values to come after a `--` to indicate
2206     /// they should all be captured. For example:
2207     ///
2208     /// ```text
2209     /// --foo something -- -v -v -v -b -b -b --baz -q -u -x
2210     /// ```
2211     ///
2212     /// Will result in everything after `--` to be considered one raw argument. This behavior
2213     /// may not be exactly what you are expecting and using [`crate::Command::trailing_var_arg`]
2214     /// may be more appropriate.
2215     ///
2216     /// **NOTE:** Implicitly sets [`Arg::takes_value(true)`] [`Arg::multiple_values(true)`],
2217     /// [`Arg::allow_hyphen_values(true)`], and [`Arg::last(true)`] when set to `true`.
2218     ///
2219     /// [`Arg::takes_value(true)`]: Arg::takes_value()
2220     /// [`Arg::multiple_values(true)`]: Arg::multiple_values()
2221     /// [`Arg::allow_hyphen_values(true)`]: Arg::allow_hyphen_values()
2222     /// [`Arg::last(true)`]: Arg::last()
2223     #[inline]
2224     #[must_use]
raw(self, yes: bool) -> Self2225     pub fn raw(self, yes: bool) -> Self {
2226         self.takes_value(yes)
2227             .multiple_values(yes)
2228             .allow_hyphen_values(yes)
2229             .last(yes)
2230     }
2231 
2232     /// Value for the argument when not present.
2233     ///
2234     /// **NOTE:** If the user *does not* use this argument at runtime, [`ArgMatches::occurrences_of`]
2235     /// will return `0` even though the [`ArgMatches::value_of`] will return the default specified.
2236     ///
2237     /// **NOTE:** If the user *does not* use this argument at runtime [`ArgMatches::contains_id`] will
2238     /// still return `true`. If you wish to determine whether the argument was used at runtime or
2239     /// not, consider [`ArgMatches::value_source`][crate::ArgMatches::value_source].
2240     ///
2241     /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value_if`] but slightly
2242     /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg
2243     /// at runtime. `Arg::default_value_if` however only takes effect when the user has not provided
2244     /// a value at runtime **and** these other conditions are met as well. If you have set
2245     /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide this arg
2246     /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value`
2247     /// will be applied.
2248     ///
2249     /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
2250     ///
2251     /// # Examples
2252     ///
2253     /// First we use the default value without providing any value at runtime.
2254     ///
2255     /// ```rust
2256     /// # use clap::{Command, Arg, ValueSource};
2257     /// let m = Command::new("prog")
2258     ///     .arg(Arg::new("opt")
2259     ///         .long("myopt")
2260     ///         .default_value("myval"))
2261     ///     .get_matches_from(vec![
2262     ///         "prog"
2263     ///     ]);
2264     ///
2265     /// assert_eq!(m.value_of("opt"), Some("myval"));
2266     /// assert!(m.contains_id("opt"));
2267     /// assert_eq!(m.value_source("opt"), Some(ValueSource::DefaultValue));
2268     /// ```
2269     ///
2270     /// Next we provide a value at runtime to override the default.
2271     ///
2272     /// ```rust
2273     /// # use clap::{Command, Arg, ValueSource};
2274     /// let m = Command::new("prog")
2275     ///     .arg(Arg::new("opt")
2276     ///         .long("myopt")
2277     ///         .default_value("myval"))
2278     ///     .get_matches_from(vec![
2279     ///         "prog", "--myopt=non_default"
2280     ///     ]);
2281     ///
2282     /// assert_eq!(m.value_of("opt"), Some("non_default"));
2283     /// assert!(m.contains_id("opt"));
2284     /// assert_eq!(m.value_source("opt"), Some(ValueSource::CommandLine));
2285     /// ```
2286     /// [`ArgMatches::occurrences_of`]: crate::ArgMatches::occurrences_of()
2287     /// [`ArgMatches::value_of`]: crate::ArgMatches::value_of()
2288     /// [`Arg::takes_value(true)`]: Arg::takes_value()
2289     /// [`ArgMatches::contains_id`]: crate::ArgMatches::contains_id()
2290     /// [`Arg::default_value_if`]: Arg::default_value_if()
2291     #[inline]
2292     #[must_use]
default_value(self, val: &'help str) -> Self2293     pub fn default_value(self, val: &'help str) -> Self {
2294         self.default_values_os(&[OsStr::new(val)])
2295     }
2296 
2297     /// Value for the argument when not present.
2298     ///
2299     /// See [`Arg::default_value`].
2300     ///
2301     /// [`Arg::default_value`]: Arg::default_value()
2302     /// [`OsStr`]: std::ffi::OsStr
2303     #[inline]
2304     #[must_use]
default_value_os(self, val: &'help OsStr) -> Self2305     pub fn default_value_os(self, val: &'help OsStr) -> Self {
2306         self.default_values_os(&[val])
2307     }
2308 
2309     /// Value for the argument when not present.
2310     ///
2311     /// See [`Arg::default_value`].
2312     ///
2313     /// [`Arg::default_value`]: Arg::default_value()
2314     #[inline]
2315     #[must_use]
default_values(self, vals: &[&'help str]) -> Self2316     pub fn default_values(self, vals: &[&'help str]) -> Self {
2317         let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect();
2318         self.default_values_os(&vals_vec[..])
2319     }
2320 
2321     /// Value for the argument when not present.
2322     ///
2323     /// See [`Arg::default_values`].
2324     ///
2325     /// [`Arg::default_values`]: Arg::default_values()
2326     /// [`OsStr`]: std::ffi::OsStr
2327     #[inline]
2328     #[must_use]
default_values_os(mut self, vals: &[&'help OsStr]) -> Self2329     pub fn default_values_os(mut self, vals: &[&'help OsStr]) -> Self {
2330         self.default_vals = vals.to_vec();
2331         self.takes_value(true)
2332     }
2333 
2334     /// Value for the argument when the flag is present but no value is specified.
2335     ///
2336     /// This configuration option is often used to give the user a shortcut and allow them to
2337     /// efficiently specify an option argument without requiring an explicitly value. The `--color`
2338     /// argument is a common example. By, supplying an default, such as `default_missing_value("always")`,
2339     /// the user can quickly just add `--color` to the command line to produce the desired color output.
2340     ///
2341     /// **NOTE:** using this configuration option requires the use of the `.min_values(0)` and the
2342     /// `.require_equals(true)` configuration option. These are required in order to unambiguously
2343     /// determine what, if any, value was supplied for the argument.
2344     ///
2345     /// # Examples
2346     ///
2347     /// For POSIX style `--color`:
2348     /// ```rust
2349     /// # use clap::{Command, Arg, ValueSource};
2350     /// fn cli() -> Command<'static> {
2351     ///     Command::new("prog")
2352     ///         .arg(Arg::new("color").long("color")
2353     ///             .value_name("WHEN")
2354     ///             .value_parser(["always", "auto", "never"])
2355     ///             .default_value("auto")
2356     ///             .min_values(0)
2357     ///             .require_equals(true)
2358     ///             .default_missing_value("always")
2359     ///             .help("Specify WHEN to colorize output.")
2360     ///         )
2361     /// }
2362     ///
2363     /// // first, we'll provide no arguments
2364     /// let m  = cli().get_matches_from(vec![
2365     ///         "prog"
2366     ///     ]);
2367     /// assert_eq!(m.value_of("color"), Some("auto"));
2368     /// assert_eq!(m.value_source("color"), Some(ValueSource::DefaultValue));
2369     ///
2370     /// // next, we'll provide a runtime value to override the default (as usually done).
2371     /// let m  = cli().get_matches_from(vec![
2372     ///         "prog", "--color=never"
2373     ///     ]);
2374     /// assert_eq!(m.value_of("color"), Some("never"));
2375     /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine));
2376     ///
2377     /// // finally, we will use the shortcut and only provide the argument without a value.
2378     /// let m  = cli().get_matches_from(vec![
2379     ///         "prog", "--color"
2380     ///     ]);
2381     /// assert_eq!(m.value_of("color"), Some("always"));
2382     /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine));
2383     /// ```
2384     ///
2385     /// For bool literals:
2386     /// ```rust
2387     /// # use clap::{Command, Arg, ValueSource, value_parser};
2388     /// fn cli() -> Command<'static> {
2389     ///     Command::new("prog")
2390     ///         .arg(Arg::new("create").long("create")
2391     ///             .value_name("BOOL")
2392     ///             .value_parser(value_parser!(bool))
2393     ///             .min_values(0)
2394     ///             .require_equals(true)
2395     ///             .default_missing_value("true")
2396     ///         )
2397     /// }
2398     ///
2399     /// // first, we'll provide no arguments
2400     /// let m  = cli().get_matches_from(vec![
2401     ///         "prog"
2402     ///     ]);
2403     /// assert_eq!(m.get_one::<bool>("create").copied(), None);
2404     ///
2405     /// // next, we'll provide a runtime value to override the default (as usually done).
2406     /// let m  = cli().get_matches_from(vec![
2407     ///         "prog", "--create=false"
2408     ///     ]);
2409     /// assert_eq!(m.get_one::<bool>("create").copied(), Some(false));
2410     /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine));
2411     ///
2412     /// // finally, we will use the shortcut and only provide the argument without a value.
2413     /// let m  = cli().get_matches_from(vec![
2414     ///         "prog", "--create"
2415     ///     ]);
2416     /// assert_eq!(m.get_one::<bool>("create").copied(), Some(true));
2417     /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine));
2418     /// ```
2419     ///
2420     /// [`ArgMatches::value_of`]: ArgMatches::value_of()
2421     /// [`Arg::takes_value(true)`]: Arg::takes_value()
2422     /// [`Arg::default_value`]: Arg::default_value()
2423     #[inline]
2424     #[must_use]
default_missing_value(self, val: &'help str) -> Self2425     pub fn default_missing_value(self, val: &'help str) -> Self {
2426         self.default_missing_values_os(&[OsStr::new(val)])
2427     }
2428 
2429     /// Value for the argument when the flag is present but no value is specified.
2430     ///
2431     /// See [`Arg::default_missing_value`].
2432     ///
2433     /// [`Arg::default_missing_value`]: Arg::default_missing_value()
2434     /// [`OsStr`]: std::ffi::OsStr
2435     #[inline]
2436     #[must_use]
default_missing_value_os(self, val: &'help OsStr) -> Self2437     pub fn default_missing_value_os(self, val: &'help OsStr) -> Self {
2438         self.default_missing_values_os(&[val])
2439     }
2440 
2441     /// Value for the argument when the flag is present but no value is specified.
2442     ///
2443     /// See [`Arg::default_missing_value`].
2444     ///
2445     /// [`Arg::default_missing_value`]: Arg::default_missing_value()
2446     #[inline]
2447     #[must_use]
default_missing_values(self, vals: &[&'help str]) -> Self2448     pub fn default_missing_values(self, vals: &[&'help str]) -> Self {
2449         let vals_vec: Vec<_> = vals.iter().map(|val| OsStr::new(*val)).collect();
2450         self.default_missing_values_os(&vals_vec[..])
2451     }
2452 
2453     /// Value for the argument when the flag is present but no value is specified.
2454     ///
2455     /// See [`Arg::default_missing_values`].
2456     ///
2457     /// [`Arg::default_missing_values`]: Arg::default_missing_values()
2458     /// [`OsStr`]: std::ffi::OsStr
2459     #[inline]
2460     #[must_use]
default_missing_values_os(mut self, vals: &[&'help OsStr]) -> Self2461     pub fn default_missing_values_os(mut self, vals: &[&'help OsStr]) -> Self {
2462         self.default_missing_vals = vals.to_vec();
2463         self.takes_value(true)
2464     }
2465 
2466     /// Read from `name` environment variable when argument is not present.
2467     ///
2468     /// If it is not present in the environment, then default
2469     /// rules will apply.
2470     ///
2471     /// If user sets the argument in the environment:
2472     /// - When [`Arg::takes_value(true)`] is not set, the flag is considered raised.
2473     /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will
2474     ///   return value of the environment variable.
2475     ///
2476     /// If user doesn't set the argument in the environment:
2477     /// - When [`Arg::takes_value(true)`] is not set, the flag is considered off.
2478     /// - When [`Arg::takes_value(true)`] is set, [`ArgMatches::value_of`] will
2479     ///   return the default specified.
2480     ///
2481     /// # Examples
2482     ///
2483     /// In this example, we show the variable coming from the environment:
2484     ///
2485     /// ```rust
2486     /// # use std::env;
2487     /// # use clap::{Command, Arg};
2488     ///
2489     /// env::set_var("MY_FLAG", "env");
2490     ///
2491     /// let m = Command::new("prog")
2492     ///     .arg(Arg::new("flag")
2493     ///         .long("flag")
2494     ///         .env("MY_FLAG")
2495     ///         .takes_value(true))
2496     ///     .get_matches_from(vec![
2497     ///         "prog"
2498     ///     ]);
2499     ///
2500     /// assert_eq!(m.value_of("flag"), Some("env"));
2501     /// ```
2502     ///
2503     /// In this example, because [`Arg::takes_value(false)`] (by default),
2504     /// `prog` is a flag that accepts an optional, case-insensitive boolean literal.
2505     /// A `false` literal is `n`, `no`, `f`, `false`, `off` or `0`.
2506     /// An absent environment variable will also be considered as `false`.
2507     /// Anything else will considered as `true`.
2508     ///
2509     /// ```rust
2510     /// # use std::env;
2511     /// # use clap::{Command, Arg};
2512     ///
2513     /// env::set_var("TRUE_FLAG", "true");
2514     /// env::set_var("FALSE_FLAG", "0");
2515     ///
2516     /// let m = Command::new("prog")
2517     ///     .arg(Arg::new("true_flag")
2518     ///         .long("true_flag")
2519     ///         .env("TRUE_FLAG"))
2520     ///     .arg(Arg::new("false_flag")
2521     ///         .long("false_flag")
2522     ///         .env("FALSE_FLAG"))
2523     ///     .arg(Arg::new("absent_flag")
2524     ///         .long("absent_flag")
2525     ///         .env("ABSENT_FLAG"))
2526     ///     .get_matches_from(vec![
2527     ///         "prog"
2528     ///     ]);
2529     ///
2530     /// assert!(m.is_present("true_flag"));
2531     /// assert_eq!(m.value_of("true_flag"), None);
2532     /// assert!(!m.is_present("false_flag"));
2533     /// assert!(!m.is_present("absent_flag"));
2534     /// ```
2535     ///
2536     /// In this example, we show the variable coming from an option on the CLI:
2537     ///
2538     /// ```rust
2539     /// # use std::env;
2540     /// # use clap::{Command, Arg};
2541     ///
2542     /// env::set_var("MY_FLAG", "env");
2543     ///
2544     /// let m = Command::new("prog")
2545     ///     .arg(Arg::new("flag")
2546     ///         .long("flag")
2547     ///         .env("MY_FLAG")
2548     ///         .takes_value(true))
2549     ///     .get_matches_from(vec![
2550     ///         "prog", "--flag", "opt"
2551     ///     ]);
2552     ///
2553     /// assert_eq!(m.value_of("flag"), Some("opt"));
2554     /// ```
2555     ///
2556     /// In this example, we show the variable coming from the environment even with the
2557     /// presence of a default:
2558     ///
2559     /// ```rust
2560     /// # use std::env;
2561     /// # use clap::{Command, Arg};
2562     ///
2563     /// env::set_var("MY_FLAG", "env");
2564     ///
2565     /// let m = Command::new("prog")
2566     ///     .arg(Arg::new("flag")
2567     ///         .long("flag")
2568     ///         .env("MY_FLAG")
2569     ///         .takes_value(true)
2570     ///         .default_value("default"))
2571     ///     .get_matches_from(vec![
2572     ///         "prog"
2573     ///     ]);
2574     ///
2575     /// assert_eq!(m.value_of("flag"), Some("env"));
2576     /// ```
2577     ///
2578     /// In this example, we show the use of multiple values in a single environment variable:
2579     ///
2580     /// ```rust
2581     /// # use std::env;
2582     /// # use clap::{Command, Arg};
2583     ///
2584     /// env::set_var("MY_FLAG_MULTI", "env1,env2");
2585     ///
2586     /// let m = Command::new("prog")
2587     ///     .arg(Arg::new("flag")
2588     ///         .long("flag")
2589     ///         .env("MY_FLAG_MULTI")
2590     ///         .takes_value(true)
2591     ///         .multiple_values(true)
2592     ///         .use_value_delimiter(true))
2593     ///     .get_matches_from(vec![
2594     ///         "prog"
2595     ///     ]);
2596     ///
2597     /// assert_eq!(m.values_of("flag").unwrap().collect::<Vec<_>>(), vec!["env1", "env2"]);
2598     /// ```
2599     /// [`ArgMatches::value_of`]: crate::ArgMatches::value_of()
2600     /// [`Arg::takes_value(true)`]: Arg::takes_value()
2601     /// [`Arg::use_value_delimiter(true)`]: Arg::use_value_delimiter()
2602     #[cfg(feature = "env")]
2603     #[inline]
2604     #[must_use]
env(self, name: &'help str) -> Self2605     pub fn env(self, name: &'help str) -> Self {
2606         self.env_os(OsStr::new(name))
2607     }
2608 
2609     /// Read from `name` environment variable when argument is not present.
2610     ///
2611     /// See [`Arg::env`].
2612     #[cfg(feature = "env")]
2613     #[inline]
2614     #[must_use]
env_os(mut self, name: &'help OsStr) -> Self2615     pub fn env_os(mut self, name: &'help OsStr) -> Self {
2616         self.env = Some((name, env::var_os(name)));
2617         self
2618     }
2619 }
2620 
2621 /// # Help
2622 impl<'help> Arg<'help> {
2623     /// Sets the description of the argument for short help (`-h`).
2624     ///
2625     /// Typically, this is a short (one line) description of the arg.
2626     ///
2627     /// If [`Arg::long_help`] is not specified, this message will be displayed for `--help`.
2628     ///
2629     /// **NOTE:** Only `Arg::help` is used in completion script generation in order to be concise
2630     ///
2631     /// # Examples
2632     ///
2633     /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
2634     /// include a newline in the help text and have the following text be properly aligned with all
2635     /// the other help text.
2636     ///
2637     /// Setting `help` displays a short message to the side of the argument when the user passes
2638     /// `-h` or `--help` (by default).
2639     ///
2640     /// ```rust
2641     /// # use clap::{Command, Arg};
2642     /// let m = Command::new("prog")
2643     ///     .arg(Arg::new("cfg")
2644     ///         .long("config")
2645     ///         .help("Some help text describing the --config arg"))
2646     ///     .get_matches_from(vec![
2647     ///         "prog", "--help"
2648     ///     ]);
2649     /// ```
2650     ///
2651     /// The above example displays
2652     ///
2653     /// ```notrust
2654     /// helptest
2655     ///
2656     /// USAGE:
2657     ///    helptest [OPTIONS]
2658     ///
2659     /// OPTIONS:
2660     ///     --config     Some help text describing the --config arg
2661     /// -h, --help       Print help information
2662     /// -V, --version    Print version information
2663     /// ```
2664     /// [`Arg::long_help`]: Arg::long_help()
2665     #[inline]
2666     #[must_use]
help(mut self, h: impl Into<Option<&'help str>>) -> Self2667     pub fn help(mut self, h: impl Into<Option<&'help str>>) -> Self {
2668         self.help = h.into();
2669         self
2670     }
2671 
2672     /// Sets the description of the argument for long help (`--help`).
2673     ///
2674     /// Typically this a more detailed (multi-line) message
2675     /// that describes the arg.
2676     ///
2677     /// If [`Arg::help`] is not specified, this message will be displayed for `-h`.
2678     ///
2679     /// **NOTE:** Only [`Arg::help`] is used in completion script generation in order to be concise
2680     ///
2681     /// # Examples
2682     ///
2683     /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
2684     /// include a newline in the help text and have the following text be properly aligned with all
2685     /// the other help text.
2686     ///
2687     /// Setting `help` displays a short message to the side of the argument when the user passes
2688     /// `-h` or `--help` (by default).
2689     ///
2690     /// ```rust
2691     /// # use clap::{Command, Arg};
2692     /// let m = Command::new("prog")
2693     ///     .arg(Arg::new("cfg")
2694     ///         .long("config")
2695     ///         .long_help(
2696     /// "The config file used by the myprog must be in JSON format
2697     /// with only valid keys and may not contain other nonsense
2698     /// that cannot be read by this program. Obviously I'm going on
2699     /// and on, so I'll stop now."))
2700     ///     .get_matches_from(vec![
2701     ///         "prog", "--help"
2702     ///     ]);
2703     /// ```
2704     ///
2705     /// The above example displays
2706     ///
2707     /// ```text
2708     /// prog
2709     ///
2710     /// USAGE:
2711     ///     prog [OPTIONS]
2712     ///
2713     /// OPTIONS:
2714     ///         --config
2715     ///             The config file used by the myprog must be in JSON format
2716     ///             with only valid keys and may not contain other nonsense
2717     ///             that cannot be read by this program. Obviously I'm going on
2718     ///             and on, so I'll stop now.
2719     ///
2720     ///     -h, --help
2721     ///             Print help information
2722     ///
2723     ///     -V, --version
2724     ///             Print version information
2725     /// ```
2726     /// [`Arg::help`]: Arg::help()
2727     #[inline]
2728     #[must_use]
long_help(mut self, h: impl Into<Option<&'help str>>) -> Self2729     pub fn long_help(mut self, h: impl Into<Option<&'help str>>) -> Self {
2730         self.long_help = h.into();
2731         self
2732     }
2733 
2734     /// Allows custom ordering of args within the help message.
2735     ///
2736     /// Args with a lower value will be displayed first in the help message. This is helpful when
2737     /// one would like to emphasise frequently used args, or prioritize those towards the top of
2738     /// the list. Args with duplicate display orders will be displayed in alphabetical order.
2739     ///
2740     /// **NOTE:** The default is 999 for all arguments.
2741     ///
2742     /// **NOTE:** This setting is ignored for [positional arguments] which are always displayed in
2743     /// [index] order.
2744     ///
2745     /// # Examples
2746     ///
2747     /// ```rust
2748     /// # use clap::{Command, Arg};
2749     /// let m = Command::new("prog")
2750     ///     .arg(Arg::new("a") // Typically args are grouped alphabetically by name.
2751     ///                              // Args without a display_order have a value of 999 and are
2752     ///                              // displayed alphabetically with all other 999 valued args.
2753     ///         .long("long-option")
2754     ///         .short('o')
2755     ///         .takes_value(true)
2756     ///         .help("Some help and text"))
2757     ///     .arg(Arg::new("b")
2758     ///         .long("other-option")
2759     ///         .short('O')
2760     ///         .takes_value(true)
2761     ///         .display_order(1)   // In order to force this arg to appear *first*
2762     ///                             // all we have to do is give it a value lower than 999.
2763     ///                             // Any other args with a value of 1 will be displayed
2764     ///                             // alphabetically with this one...then 2 values, then 3, etc.
2765     ///         .help("I should be first!"))
2766     ///     .get_matches_from(vec![
2767     ///         "prog", "--help"
2768     ///     ]);
2769     /// ```
2770     ///
2771     /// The above example displays the following help message
2772     ///
2773     /// ```text
2774     /// cust-ord
2775     ///
2776     /// USAGE:
2777     ///     cust-ord [OPTIONS]
2778     ///
2779     /// OPTIONS:
2780     ///     -h, --help                Print help information
2781     ///     -V, --version             Print version information
2782     ///     -O, --other-option <b>    I should be first!
2783     ///     -o, --long-option <a>     Some help and text
2784     /// ```
2785     /// [positional arguments]: Arg::index()
2786     /// [index]: Arg::index()
2787     #[inline]
2788     #[must_use]
display_order(mut self, ord: usize) -> Self2789     pub fn display_order(mut self, ord: usize) -> Self {
2790         self.disp_ord.set_explicit(ord);
2791         self
2792     }
2793 
2794     /// Override the [current] help section.
2795     ///
2796     /// [current]: crate::Command::help_heading
2797     #[inline]
2798     #[must_use]
help_heading<O>(mut self, heading: O) -> Self where O: Into<Option<&'help str>>,2799     pub fn help_heading<O>(mut self, heading: O) -> Self
2800     where
2801         O: Into<Option<&'help str>>,
2802     {
2803         self.help_heading = Some(heading.into());
2804         self
2805     }
2806 
2807     /// Render the [help][Arg::help] on the line after the argument.
2808     ///
2809     /// This can be helpful for arguments with very long or complex help messages.
2810     /// This can also be helpful for arguments with very long flag names, or many/long value names.
2811     ///
2812     /// **NOTE:** To apply this setting to all arguments and subcommands, consider using
2813     /// [`crate::Command::next_line_help`]
2814     ///
2815     /// # Examples
2816     ///
2817     /// ```rust
2818     /// # use clap::{Command, Arg};
2819     /// let m = Command::new("prog")
2820     ///     .arg(Arg::new("opt")
2821     ///         .long("long-option-flag")
2822     ///         .short('o')
2823     ///         .takes_value(true)
2824     ///         .next_line_help(true)
2825     ///         .value_names(&["value1", "value2"])
2826     ///         .help("Some really long help and complex\n\
2827     ///                help that makes more sense to be\n\
2828     ///                on a line after the option"))
2829     ///     .get_matches_from(vec![
2830     ///         "prog", "--help"
2831     ///     ]);
2832     /// ```
2833     ///
2834     /// The above example displays the following help message
2835     ///
2836     /// ```text
2837     /// nlh
2838     ///
2839     /// USAGE:
2840     ///     nlh [OPTIONS]
2841     ///
2842     /// OPTIONS:
2843     ///     -h, --help       Print help information
2844     ///     -V, --version    Print version information
2845     ///     -o, --long-option-flag <value1> <value2>
2846     ///         Some really long help and complex
2847     ///         help that makes more sense to be
2848     ///         on a line after the option
2849     /// ```
2850     #[inline]
2851     #[must_use]
next_line_help(self, yes: bool) -> Self2852     pub fn next_line_help(self, yes: bool) -> Self {
2853         if yes {
2854             self.setting(ArgSettings::NextLineHelp)
2855         } else {
2856             self.unset_setting(ArgSettings::NextLineHelp)
2857         }
2858     }
2859 
2860     /// Do not display the argument in help message.
2861     ///
2862     /// **NOTE:** This does **not** hide the argument from usage strings on error
2863     ///
2864     /// # Examples
2865     ///
2866     /// Setting `Hidden` will hide the argument when displaying help text
2867     ///
2868     /// ```rust
2869     /// # use clap::{Command, Arg};
2870     /// let m = Command::new("prog")
2871     ///     .arg(Arg::new("cfg")
2872     ///         .long("config")
2873     ///         .hide(true)
2874     ///         .help("Some help text describing the --config arg"))
2875     ///     .get_matches_from(vec![
2876     ///         "prog", "--help"
2877     ///     ]);
2878     /// ```
2879     ///
2880     /// The above example displays
2881     ///
2882     /// ```text
2883     /// helptest
2884     ///
2885     /// USAGE:
2886     ///    helptest [OPTIONS]
2887     ///
2888     /// OPTIONS:
2889     /// -h, --help       Print help information
2890     /// -V, --version    Print version information
2891     /// ```
2892     #[inline]
2893     #[must_use]
hide(self, yes: bool) -> Self2894     pub fn hide(self, yes: bool) -> Self {
2895         if yes {
2896             self.setting(ArgSettings::Hidden)
2897         } else {
2898             self.unset_setting(ArgSettings::Hidden)
2899         }
2900     }
2901 
2902     /// Do not display the [possible values][crate::builder::ValueParser::possible_values] in the help message.
2903     ///
2904     /// This is useful for args with many values, or ones which are explained elsewhere in the
2905     /// help text.
2906     ///
2907     /// **NOTE:** Setting this requires [`Arg::takes_value`]
2908     ///
2909     /// To set this for all arguments, see
2910     /// [`Command::hide_possible_values`][crate::Command::hide_possible_values].
2911     ///
2912     /// # Examples
2913     ///
2914     /// ```rust
2915     /// # use clap::{Command, Arg};
2916     /// let m = Command::new("prog")
2917     ///     .arg(Arg::new("mode")
2918     ///         .long("mode")
2919     ///         .value_parser(["fast", "slow"])
2920     ///         .takes_value(true)
2921     ///         .hide_possible_values(true));
2922     /// ```
2923     /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of
2924     /// the help text would be omitted.
2925     #[inline]
2926     #[must_use]
hide_possible_values(self, yes: bool) -> Self2927     pub fn hide_possible_values(self, yes: bool) -> Self {
2928         if yes {
2929             self.setting(ArgSettings::HidePossibleValues)
2930         } else {
2931             self.unset_setting(ArgSettings::HidePossibleValues)
2932         }
2933     }
2934 
2935     /// Do not display the default value of the argument in the help message.
2936     ///
2937     /// This is useful when default behavior of an arg is explained elsewhere in the help text.
2938     ///
2939     /// **NOTE:** Setting this requires [`Arg::takes_value`]
2940     ///
2941     /// # Examples
2942     ///
2943     /// ```rust
2944     /// # use clap::{Command, Arg};
2945     /// let m = Command::new("connect")
2946     ///     .arg(Arg::new("host")
2947     ///         .long("host")
2948     ///         .default_value("localhost")
2949     ///         .takes_value(true)
2950     ///         .hide_default_value(true));
2951     ///
2952     /// ```
2953     ///
2954     /// If we were to run the above program with `--help` the `[default: localhost]` portion of
2955     /// the help text would be omitted.
2956     #[inline]
2957     #[must_use]
hide_default_value(self, yes: bool) -> Self2958     pub fn hide_default_value(self, yes: bool) -> Self {
2959         if yes {
2960             self.setting(ArgSettings::HideDefaultValue)
2961         } else {
2962             self.unset_setting(ArgSettings::HideDefaultValue)
2963         }
2964     }
2965 
2966     /// Do not display in help the environment variable name.
2967     ///
2968     /// This is useful when the variable option is explained elsewhere in the help text.
2969     ///
2970     /// # Examples
2971     ///
2972     /// ```rust
2973     /// # use clap::{Command, Arg};
2974     /// let m = Command::new("prog")
2975     ///     .arg(Arg::new("mode")
2976     ///         .long("mode")
2977     ///         .env("MODE")
2978     ///         .takes_value(true)
2979     ///         .hide_env(true));
2980     /// ```
2981     ///
2982     /// If we were to run the above program with `--help` the `[env: MODE]` portion of the help
2983     /// text would be omitted.
2984     #[cfg(feature = "env")]
2985     #[inline]
2986     #[must_use]
hide_env(self, yes: bool) -> Self2987     pub fn hide_env(self, yes: bool) -> Self {
2988         if yes {
2989             self.setting(ArgSettings::HideEnv)
2990         } else {
2991             self.unset_setting(ArgSettings::HideEnv)
2992         }
2993     }
2994 
2995     /// Do not display in help any values inside the associated ENV variables for the argument.
2996     ///
2997     /// This is useful when ENV vars contain sensitive values.
2998     ///
2999     /// # Examples
3000     ///
3001     /// ```rust
3002     /// # use clap::{Command, Arg};
3003     /// let m = Command::new("connect")
3004     ///     .arg(Arg::new("host")
3005     ///         .long("host")
3006     ///         .env("CONNECT")
3007     ///         .takes_value(true)
3008     ///         .hide_env_values(true));
3009     ///
3010     /// ```
3011     ///
3012     /// If we were to run the above program with `$ CONNECT=super_secret connect --help` the
3013     /// `[default: CONNECT=super_secret]` portion of the help text would be omitted.
3014     #[cfg(feature = "env")]
3015     #[inline]
3016     #[must_use]
hide_env_values(self, yes: bool) -> Self3017     pub fn hide_env_values(self, yes: bool) -> Self {
3018         if yes {
3019             self.setting(ArgSettings::HideEnvValues)
3020         } else {
3021             self.unset_setting(ArgSettings::HideEnvValues)
3022         }
3023     }
3024 
3025     /// Hides an argument from short help (`-h`).
3026     ///
3027     /// **NOTE:** This does **not** hide the argument from usage strings on error
3028     ///
3029     /// **NOTE:** Setting this option will cause next-line-help output style to be used
3030     /// when long help (`--help`) is called.
3031     ///
3032     /// # Examples
3033     ///
3034     /// ```rust
3035     /// # use clap::{Command, Arg};
3036     /// Arg::new("debug")
3037     ///     .hide_short_help(true);
3038     /// ```
3039     ///
3040     /// Setting `hide_short_help(true)` will hide the argument when displaying short help text
3041     ///
3042     /// ```rust
3043     /// # use clap::{Command, Arg};
3044     /// let m = Command::new("prog")
3045     ///     .arg(Arg::new("cfg")
3046     ///         .long("config")
3047     ///         .hide_short_help(true)
3048     ///         .help("Some help text describing the --config arg"))
3049     ///     .get_matches_from(vec![
3050     ///         "prog", "-h"
3051     ///     ]);
3052     /// ```
3053     ///
3054     /// The above example displays
3055     ///
3056     /// ```text
3057     /// helptest
3058     ///
3059     /// USAGE:
3060     ///    helptest [OPTIONS]
3061     ///
3062     /// OPTIONS:
3063     /// -h, --help       Print help information
3064     /// -V, --version    Print version information
3065     /// ```
3066     ///
3067     /// However, when --help is called
3068     ///
3069     /// ```rust
3070     /// # use clap::{Command, Arg};
3071     /// let m = Command::new("prog")
3072     ///     .arg(Arg::new("cfg")
3073     ///         .long("config")
3074     ///         .hide_short_help(true)
3075     ///         .help("Some help text describing the --config arg"))
3076     ///     .get_matches_from(vec![
3077     ///         "prog", "--help"
3078     ///     ]);
3079     /// ```
3080     ///
3081     /// Then the following would be displayed
3082     ///
3083     /// ```text
3084     /// helptest
3085     ///
3086     /// USAGE:
3087     ///    helptest [OPTIONS]
3088     ///
3089     /// OPTIONS:
3090     ///     --config     Some help text describing the --config arg
3091     /// -h, --help       Print help information
3092     /// -V, --version    Print version information
3093     /// ```
3094     #[inline]
3095     #[must_use]
hide_short_help(self, yes: bool) -> Self3096     pub fn hide_short_help(self, yes: bool) -> Self {
3097         if yes {
3098             self.setting(ArgSettings::HiddenShortHelp)
3099         } else {
3100             self.unset_setting(ArgSettings::HiddenShortHelp)
3101         }
3102     }
3103 
3104     /// Hides an argument from long help (`--help`).
3105     ///
3106     /// **NOTE:** This does **not** hide the argument from usage strings on error
3107     ///
3108     /// **NOTE:** Setting this option will cause next-line-help output style to be used
3109     /// when long help (`--help`) is called.
3110     ///
3111     /// # Examples
3112     ///
3113     /// Setting `hide_long_help(true)` will hide the argument when displaying long help text
3114     ///
3115     /// ```rust
3116     /// # use clap::{Command, Arg};
3117     /// let m = Command::new("prog")
3118     ///     .arg(Arg::new("cfg")
3119     ///         .long("config")
3120     ///         .hide_long_help(true)
3121     ///         .help("Some help text describing the --config arg"))
3122     ///     .get_matches_from(vec![
3123     ///         "prog", "--help"
3124     ///     ]);
3125     /// ```
3126     ///
3127     /// The above example displays
3128     ///
3129     /// ```text
3130     /// helptest
3131     ///
3132     /// USAGE:
3133     ///    helptest [OPTIONS]
3134     ///
3135     /// OPTIONS:
3136     /// -h, --help       Print help information
3137     /// -V, --version    Print version information
3138     /// ```
3139     ///
3140     /// However, when -h is called
3141     ///
3142     /// ```rust
3143     /// # use clap::{Command, Arg};
3144     /// let m = Command::new("prog")
3145     ///     .arg(Arg::new("cfg")
3146     ///         .long("config")
3147     ///         .hide_long_help(true)
3148     ///         .help("Some help text describing the --config arg"))
3149     ///     .get_matches_from(vec![
3150     ///         "prog", "-h"
3151     ///     ]);
3152     /// ```
3153     ///
3154     /// Then the following would be displayed
3155     ///
3156     /// ```text
3157     /// helptest
3158     ///
3159     /// USAGE:
3160     ///    helptest [OPTIONS]
3161     ///
3162     /// OPTIONS:
3163     ///     --config     Some help text describing the --config arg
3164     /// -h, --help       Print help information
3165     /// -V, --version    Print version information
3166     /// ```
3167     #[inline]
3168     #[must_use]
hide_long_help(self, yes: bool) -> Self3169     pub fn hide_long_help(self, yes: bool) -> Self {
3170         if yes {
3171             self.setting(ArgSettings::HiddenLongHelp)
3172         } else {
3173             self.unset_setting(ArgSettings::HiddenLongHelp)
3174         }
3175     }
3176 }
3177 
3178 /// # Advanced Argument Relations
3179 impl<'help> Arg<'help> {
3180     /// The name of the [`ArgGroup`] the argument belongs to.
3181     ///
3182     /// # Examples
3183     ///
3184     /// ```rust
3185     /// # use clap::{Command, Arg};
3186     /// Arg::new("debug")
3187     ///     .long("debug")
3188     ///     .group("mode")
3189     /// # ;
3190     /// ```
3191     ///
3192     /// Multiple arguments can be a member of a single group and then the group checked as if it
3193     /// was one of said arguments.
3194     ///
3195     /// ```rust
3196     /// # use clap::{Command, Arg};
3197     /// let m = Command::new("prog")
3198     ///     .arg(Arg::new("debug")
3199     ///         .long("debug")
3200     ///         .group("mode"))
3201     ///     .arg(Arg::new("verbose")
3202     ///         .long("verbose")
3203     ///         .group("mode"))
3204     ///     .get_matches_from(vec![
3205     ///         "prog", "--debug"
3206     ///     ]);
3207     /// assert!(m.contains_id("mode"));
3208     /// ```
3209     ///
3210     /// [`ArgGroup`]: crate::ArgGroup
3211     #[must_use]
group<T: Key>(mut self, group_id: T) -> Self3212     pub fn group<T: Key>(mut self, group_id: T) -> Self {
3213         self.groups.push(group_id.into());
3214         self
3215     }
3216 
3217     /// The names of [`ArgGroup`]'s the argument belongs to.
3218     ///
3219     /// # Examples
3220     ///
3221     /// ```rust
3222     /// # use clap::{Command, Arg};
3223     /// Arg::new("debug")
3224     ///     .long("debug")
3225     ///     .groups(&["mode", "verbosity"])
3226     /// # ;
3227     /// ```
3228     ///
3229     /// Arguments can be members of multiple groups and then the group checked as if it
3230     /// was one of said arguments.
3231     ///
3232     /// ```rust
3233     /// # use clap::{Command, Arg};
3234     /// let m = Command::new("prog")
3235     ///     .arg(Arg::new("debug")
3236     ///         .long("debug")
3237     ///         .groups(&["mode", "verbosity"]))
3238     ///     .arg(Arg::new("verbose")
3239     ///         .long("verbose")
3240     ///         .groups(&["mode", "verbosity"]))
3241     ///     .get_matches_from(vec![
3242     ///         "prog", "--debug"
3243     ///     ]);
3244     /// assert!(m.contains_id("mode"));
3245     /// assert!(m.contains_id("verbosity"));
3246     /// ```
3247     ///
3248     /// [`ArgGroup`]: crate::ArgGroup
3249     #[must_use]
groups<T: Key>(mut self, group_ids: &[T]) -> Self3250     pub fn groups<T: Key>(mut self, group_ids: &[T]) -> Self {
3251         self.groups.extend(group_ids.iter().map(Id::from));
3252         self
3253     }
3254 
3255     /// Specifies the value of the argument if `arg` has been used at runtime.
3256     ///
3257     /// If `val` is set to `None`, `arg` only needs to be present. If `val` is set to `"some-val"`
3258     /// then `arg` must be present at runtime **and** have the value `val`.
3259     ///
3260     /// If `default` is set to `None`, `default_value` will be removed.
3261     ///
3262     /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value`] but slightly
3263     /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg
3264     /// at runtime. This setting however only takes effect when the user has not provided a value at
3265     /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value`
3266     /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were
3267     /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied.
3268     ///
3269     /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
3270     ///
3271     /// # Examples
3272     ///
3273     /// First we use the default value only if another arg is present at runtime.
3274     ///
3275     /// ```rust
3276     /// # use clap::{Command, Arg};
3277     /// let m = Command::new("prog")
3278     ///     .arg(Arg::new("flag")
3279     ///         .long("flag"))
3280     ///     .arg(Arg::new("other")
3281     ///         .long("other")
3282     ///         .default_value_if("flag", None, Some("default")))
3283     ///     .get_matches_from(vec![
3284     ///         "prog", "--flag"
3285     ///     ]);
3286     ///
3287     /// assert_eq!(m.value_of("other"), Some("default"));
3288     /// ```
3289     ///
3290     /// Next we run the same test, but without providing `--flag`.
3291     ///
3292     /// ```rust
3293     /// # use clap::{Command, Arg};
3294     /// let m = Command::new("prog")
3295     ///     .arg(Arg::new("flag")
3296     ///         .long("flag"))
3297     ///     .arg(Arg::new("other")
3298     ///         .long("other")
3299     ///         .default_value_if("flag", None, Some("default")))
3300     ///     .get_matches_from(vec![
3301     ///         "prog"
3302     ///     ]);
3303     ///
3304     /// assert_eq!(m.value_of("other"), None);
3305     /// ```
3306     ///
3307     /// Now lets only use the default value if `--opt` contains the value `special`.
3308     ///
3309     /// ```rust
3310     /// # use clap::{Command, Arg};
3311     /// let m = Command::new("prog")
3312     ///     .arg(Arg::new("opt")
3313     ///         .takes_value(true)
3314     ///         .long("opt"))
3315     ///     .arg(Arg::new("other")
3316     ///         .long("other")
3317     ///         .default_value_if("opt", Some("special"), Some("default")))
3318     ///     .get_matches_from(vec![
3319     ///         "prog", "--opt", "special"
3320     ///     ]);
3321     ///
3322     /// assert_eq!(m.value_of("other"), Some("default"));
3323     /// ```
3324     ///
3325     /// We can run the same test and provide any value *other than* `special` and we won't get a
3326     /// default value.
3327     ///
3328     /// ```rust
3329     /// # use clap::{Command, Arg};
3330     /// let m = Command::new("prog")
3331     ///     .arg(Arg::new("opt")
3332     ///         .takes_value(true)
3333     ///         .long("opt"))
3334     ///     .arg(Arg::new("other")
3335     ///         .long("other")
3336     ///         .default_value_if("opt", Some("special"), Some("default")))
3337     ///     .get_matches_from(vec![
3338     ///         "prog", "--opt", "hahaha"
3339     ///     ]);
3340     ///
3341     /// assert_eq!(m.value_of("other"), None);
3342     /// ```
3343     ///
3344     /// If we want to unset the default value for an Arg based on the presence or
3345     /// value of some other Arg.
3346     ///
3347     /// ```rust
3348     /// # use clap::{Command, Arg};
3349     /// let m = Command::new("prog")
3350     ///     .arg(Arg::new("flag")
3351     ///         .long("flag"))
3352     ///     .arg(Arg::new("other")
3353     ///         .long("other")
3354     ///         .default_value("default")
3355     ///         .default_value_if("flag", None, None))
3356     ///     .get_matches_from(vec![
3357     ///         "prog", "--flag"
3358     ///     ]);
3359     ///
3360     /// assert_eq!(m.value_of("other"), None);
3361     /// ```
3362     /// [`Arg::takes_value(true)`]: Arg::takes_value()
3363     /// [`Arg::default_value`]: Arg::default_value()
3364     #[must_use]
default_value_if<T: Key>( self, arg_id: T, val: Option<&'help str>, default: Option<&'help str>, ) -> Self3365     pub fn default_value_if<T: Key>(
3366         self,
3367         arg_id: T,
3368         val: Option<&'help str>,
3369         default: Option<&'help str>,
3370     ) -> Self {
3371         self.default_value_if_os(arg_id, val.map(OsStr::new), default.map(OsStr::new))
3372     }
3373 
3374     /// Provides a conditional default value in the exact same manner as [`Arg::default_value_if`]
3375     /// only using [`OsStr`]s instead.
3376     ///
3377     /// [`Arg::default_value_if`]: Arg::default_value_if()
3378     /// [`OsStr`]: std::ffi::OsStr
3379     #[must_use]
default_value_if_os<T: Key>( mut self, arg_id: T, val: Option<&'help OsStr>, default: Option<&'help OsStr>, ) -> Self3380     pub fn default_value_if_os<T: Key>(
3381         mut self,
3382         arg_id: T,
3383         val: Option<&'help OsStr>,
3384         default: Option<&'help OsStr>,
3385     ) -> Self {
3386         self.default_vals_ifs
3387             .push((arg_id.into(), val.into(), default));
3388         self.takes_value(true)
3389     }
3390 
3391     /// Specifies multiple values and conditions in the same manner as [`Arg::default_value_if`].
3392     ///
3393     /// The method takes a slice of tuples in the `(arg, Option<val>, default)` format.
3394     ///
3395     /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first
3396     /// if multiple conditions are true, the first one found will be applied and the ultimate value.
3397     ///
3398     /// # Examples
3399     ///
3400     /// First we use the default value only if another arg is present at runtime.
3401     ///
3402     /// ```rust
3403     /// # use clap::{Command, Arg};
3404     /// let m = Command::new("prog")
3405     ///     .arg(Arg::new("flag")
3406     ///         .long("flag"))
3407     ///     .arg(Arg::new("opt")
3408     ///         .long("opt")
3409     ///         .takes_value(true))
3410     ///     .arg(Arg::new("other")
3411     ///         .long("other")
3412     ///         .default_value_ifs(&[
3413     ///             ("flag", None, Some("default")),
3414     ///             ("opt", Some("channal"), Some("chan")),
3415     ///         ]))
3416     ///     .get_matches_from(vec![
3417     ///         "prog", "--opt", "channal"
3418     ///     ]);
3419     ///
3420     /// assert_eq!(m.value_of("other"), Some("chan"));
3421     /// ```
3422     ///
3423     /// Next we run the same test, but without providing `--flag`.
3424     ///
3425     /// ```rust
3426     /// # use clap::{Command, Arg};
3427     /// let m = Command::new("prog")
3428     ///     .arg(Arg::new("flag")
3429     ///         .long("flag"))
3430     ///     .arg(Arg::new("other")
3431     ///         .long("other")
3432     ///         .default_value_ifs(&[
3433     ///             ("flag", None, Some("default")),
3434     ///             ("opt", Some("channal"), Some("chan")),
3435     ///         ]))
3436     ///     .get_matches_from(vec![
3437     ///         "prog"
3438     ///     ]);
3439     ///
3440     /// assert_eq!(m.value_of("other"), None);
3441     /// ```
3442     ///
3443     /// We can also see that these values are applied in order, and if more than one condition is
3444     /// true, only the first evaluated "wins"
3445     ///
3446     /// ```rust
3447     /// # use clap::{Command, Arg};
3448     /// let m = Command::new("prog")
3449     ///     .arg(Arg::new("flag")
3450     ///         .long("flag"))
3451     ///     .arg(Arg::new("opt")
3452     ///         .long("opt")
3453     ///         .takes_value(true))
3454     ///     .arg(Arg::new("other")
3455     ///         .long("other")
3456     ///         .default_value_ifs(&[
3457     ///             ("flag", None, Some("default")),
3458     ///             ("opt", Some("channal"), Some("chan")),
3459     ///         ]))
3460     ///     .get_matches_from(vec![
3461     ///         "prog", "--opt", "channal", "--flag"
3462     ///     ]);
3463     ///
3464     /// assert_eq!(m.value_of("other"), Some("default"));
3465     /// ```
3466     /// [`Arg::takes_value(true)`]: Arg::takes_value()
3467     /// [`Arg::default_value_if`]: Arg::default_value_if()
3468     #[must_use]
default_value_ifs<T: Key>( mut self, ifs: &[(T, Option<&'help str>, Option<&'help str>)], ) -> Self3469     pub fn default_value_ifs<T: Key>(
3470         mut self,
3471         ifs: &[(T, Option<&'help str>, Option<&'help str>)],
3472     ) -> Self {
3473         for (arg, val, default) in ifs {
3474             self = self.default_value_if_os(arg, val.map(OsStr::new), default.map(OsStr::new));
3475         }
3476         self
3477     }
3478 
3479     /// Provides multiple conditional default values in the exact same manner as
3480     /// [`Arg::default_value_ifs`] only using [`OsStr`]s instead.
3481     ///
3482     /// [`Arg::default_value_ifs`]: Arg::default_value_ifs()
3483     /// [`OsStr`]: std::ffi::OsStr
3484     #[must_use]
default_value_ifs_os<T: Key>( mut self, ifs: &[(T, Option<&'help OsStr>, Option<&'help OsStr>)], ) -> Self3485     pub fn default_value_ifs_os<T: Key>(
3486         mut self,
3487         ifs: &[(T, Option<&'help OsStr>, Option<&'help OsStr>)],
3488     ) -> Self {
3489         for (arg, val, default) in ifs {
3490             self = self.default_value_if_os(arg, *val, *default);
3491         }
3492         self
3493     }
3494 
3495     /// Set this arg as [required] as long as the specified argument is not present at runtime.
3496     ///
3497     /// **Pro Tip:** Using `Arg::required_unless_present` implies [`Arg::required`] and is therefore not
3498     /// mandatory to also set.
3499     ///
3500     /// # Examples
3501     ///
3502     /// ```rust
3503     /// # use clap::Arg;
3504     /// Arg::new("config")
3505     ///     .required_unless_present("debug")
3506     /// # ;
3507     /// ```
3508     ///
3509     /// In the following example, the required argument is *not* provided,
3510     /// but it's not an error because the `unless` arg has been supplied.
3511     ///
3512     /// ```rust
3513     /// # use clap::{Command, Arg};
3514     /// let res = Command::new("prog")
3515     ///     .arg(Arg::new("cfg")
3516     ///         .required_unless_present("dbg")
3517     ///         .takes_value(true)
3518     ///         .long("config"))
3519     ///     .arg(Arg::new("dbg")
3520     ///         .long("debug"))
3521     ///     .try_get_matches_from(vec![
3522     ///         "prog", "--debug"
3523     ///     ]);
3524     ///
3525     /// assert!(res.is_ok());
3526     /// ```
3527     ///
3528     /// Setting `Arg::required_unless_present(name)` and *not* supplying `name` or this arg is an error.
3529     ///
3530     /// ```rust
3531     /// # use clap::{Command, Arg, ErrorKind};
3532     /// let res = Command::new("prog")
3533     ///     .arg(Arg::new("cfg")
3534     ///         .required_unless_present("dbg")
3535     ///         .takes_value(true)
3536     ///         .long("config"))
3537     ///     .arg(Arg::new("dbg")
3538     ///         .long("debug"))
3539     ///     .try_get_matches_from(vec![
3540     ///         "prog"
3541     ///     ]);
3542     ///
3543     /// assert!(res.is_err());
3544     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3545     /// ```
3546     /// [required]: Arg::required()
3547     #[must_use]
required_unless_present<T: Key>(mut self, arg_id: T) -> Self3548     pub fn required_unless_present<T: Key>(mut self, arg_id: T) -> Self {
3549         self.r_unless.push(arg_id.into());
3550         self
3551     }
3552 
3553     /// Sets this arg as [required] unless *all* of the specified arguments are present at runtime.
3554     ///
3555     /// In other words, parsing will succeed only if user either
3556     /// * supplies the `self` arg.
3557     /// * supplies *all* of the `names` arguments.
3558     ///
3559     /// **NOTE:** If you wish for this argument to only be required unless *any of* these args are
3560     /// present see [`Arg::required_unless_present_any`]
3561     ///
3562     /// # Examples
3563     ///
3564     /// ```rust
3565     /// # use clap::Arg;
3566     /// Arg::new("config")
3567     ///     .required_unless_present_all(&["cfg", "dbg"])
3568     /// # ;
3569     /// ```
3570     ///
3571     /// In the following example, the required argument is *not* provided, but it's not an error
3572     /// because *all* of the `names` args have been supplied.
3573     ///
3574     /// ```rust
3575     /// # use clap::{Command, Arg};
3576     /// let res = Command::new("prog")
3577     ///     .arg(Arg::new("cfg")
3578     ///         .required_unless_present_all(&["dbg", "infile"])
3579     ///         .takes_value(true)
3580     ///         .long("config"))
3581     ///     .arg(Arg::new("dbg")
3582     ///         .long("debug"))
3583     ///     .arg(Arg::new("infile")
3584     ///         .short('i')
3585     ///         .takes_value(true))
3586     ///     .try_get_matches_from(vec![
3587     ///         "prog", "--debug", "-i", "file"
3588     ///     ]);
3589     ///
3590     /// assert!(res.is_ok());
3591     /// ```
3592     ///
3593     /// Setting [`Arg::required_unless_present_all(names)`] and *not* supplying
3594     /// either *all* of `unless` args or the `self` arg is an error.
3595     ///
3596     /// ```rust
3597     /// # use clap::{Command, Arg, ErrorKind};
3598     /// let res = Command::new("prog")
3599     ///     .arg(Arg::new("cfg")
3600     ///         .required_unless_present_all(&["dbg", "infile"])
3601     ///         .takes_value(true)
3602     ///         .long("config"))
3603     ///     .arg(Arg::new("dbg")
3604     ///         .long("debug"))
3605     ///     .arg(Arg::new("infile")
3606     ///         .short('i')
3607     ///         .takes_value(true))
3608     ///     .try_get_matches_from(vec![
3609     ///         "prog"
3610     ///     ]);
3611     ///
3612     /// assert!(res.is_err());
3613     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3614     /// ```
3615     /// [required]: Arg::required()
3616     /// [`Arg::required_unless_present_any`]: Arg::required_unless_present_any()
3617     /// [`Arg::required_unless_present_all(names)`]: Arg::required_unless_present_all()
3618     #[must_use]
required_unless_present_all<T, I>(mut self, names: I) -> Self where I: IntoIterator<Item = T>, T: Key,3619     pub fn required_unless_present_all<T, I>(mut self, names: I) -> Self
3620     where
3621         I: IntoIterator<Item = T>,
3622         T: Key,
3623     {
3624         self.r_unless_all.extend(names.into_iter().map(Id::from));
3625         self
3626     }
3627 
3628     /// Sets this arg as [required] unless *any* of the specified arguments are present at runtime.
3629     ///
3630     /// In other words, parsing will succeed only if user either
3631     /// * supplies the `self` arg.
3632     /// * supplies *one or more* of the `unless` arguments.
3633     ///
3634     /// **NOTE:** If you wish for this argument to be required unless *all of* these args are
3635     /// present see [`Arg::required_unless_present_all`]
3636     ///
3637     /// # Examples
3638     ///
3639     /// ```rust
3640     /// # use clap::Arg;
3641     /// Arg::new("config")
3642     ///     .required_unless_present_any(&["cfg", "dbg"])
3643     /// # ;
3644     /// ```
3645     ///
3646     /// Setting [`Arg::required_unless_present_any(names)`] requires that the argument be used at runtime
3647     /// *unless* *at least one of* the args in `names` are present. In the following example, the
3648     /// required argument is *not* provided, but it's not an error because one the `unless` args
3649     /// have been supplied.
3650     ///
3651     /// ```rust
3652     /// # use clap::{Command, Arg};
3653     /// let res = Command::new("prog")
3654     ///     .arg(Arg::new("cfg")
3655     ///         .required_unless_present_any(&["dbg", "infile"])
3656     ///         .takes_value(true)
3657     ///         .long("config"))
3658     ///     .arg(Arg::new("dbg")
3659     ///         .long("debug"))
3660     ///     .arg(Arg::new("infile")
3661     ///         .short('i')
3662     ///         .takes_value(true))
3663     ///     .try_get_matches_from(vec![
3664     ///         "prog", "--debug"
3665     ///     ]);
3666     ///
3667     /// assert!(res.is_ok());
3668     /// ```
3669     ///
3670     /// Setting [`Arg::required_unless_present_any(names)`] and *not* supplying *at least one of* `names`
3671     /// or this arg is an error.
3672     ///
3673     /// ```rust
3674     /// # use clap::{Command, Arg, ErrorKind};
3675     /// let res = Command::new("prog")
3676     ///     .arg(Arg::new("cfg")
3677     ///         .required_unless_present_any(&["dbg", "infile"])
3678     ///         .takes_value(true)
3679     ///         .long("config"))
3680     ///     .arg(Arg::new("dbg")
3681     ///         .long("debug"))
3682     ///     .arg(Arg::new("infile")
3683     ///         .short('i')
3684     ///         .takes_value(true))
3685     ///     .try_get_matches_from(vec![
3686     ///         "prog"
3687     ///     ]);
3688     ///
3689     /// assert!(res.is_err());
3690     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3691     /// ```
3692     /// [required]: Arg::required()
3693     /// [`Arg::required_unless_present_any(names)`]: Arg::required_unless_present_any()
3694     /// [`Arg::required_unless_present_all`]: Arg::required_unless_present_all()
3695     #[must_use]
required_unless_present_any<T, I>(mut self, names: I) -> Self where I: IntoIterator<Item = T>, T: Key,3696     pub fn required_unless_present_any<T, I>(mut self, names: I) -> Self
3697     where
3698         I: IntoIterator<Item = T>,
3699         T: Key,
3700     {
3701         self.r_unless.extend(names.into_iter().map(Id::from));
3702         self
3703     }
3704 
3705     /// This argument is [required] only if the specified `arg` is present at runtime and its value
3706     /// equals `val`.
3707     ///
3708     /// # Examples
3709     ///
3710     /// ```rust
3711     /// # use clap::Arg;
3712     /// Arg::new("config")
3713     ///     .required_if_eq("other_arg", "value")
3714     /// # ;
3715     /// ```
3716     ///
3717     /// ```rust
3718     /// # use clap::{Command, Arg, ErrorKind};
3719     /// let res = Command::new("prog")
3720     ///     .arg(Arg::new("cfg")
3721     ///         .takes_value(true)
3722     ///         .required_if_eq("other", "special")
3723     ///         .long("config"))
3724     ///     .arg(Arg::new("other")
3725     ///         .long("other")
3726     ///         .takes_value(true))
3727     ///     .try_get_matches_from(vec![
3728     ///         "prog", "--other", "not-special"
3729     ///     ]);
3730     ///
3731     /// assert!(res.is_ok()); // We didn't use --other=special, so "cfg" wasn't required
3732     ///
3733     /// let res = Command::new("prog")
3734     ///     .arg(Arg::new("cfg")
3735     ///         .takes_value(true)
3736     ///         .required_if_eq("other", "special")
3737     ///         .long("config"))
3738     ///     .arg(Arg::new("other")
3739     ///         .long("other")
3740     ///         .takes_value(true))
3741     ///     .try_get_matches_from(vec![
3742     ///         "prog", "--other", "special"
3743     ///     ]);
3744     ///
3745     /// // We did use --other=special so "cfg" had become required but was missing.
3746     /// assert!(res.is_err());
3747     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3748     ///
3749     /// let res = Command::new("prog")
3750     ///     .arg(Arg::new("cfg")
3751     ///         .takes_value(true)
3752     ///         .required_if_eq("other", "special")
3753     ///         .long("config"))
3754     ///     .arg(Arg::new("other")
3755     ///         .long("other")
3756     ///         .takes_value(true))
3757     ///     .try_get_matches_from(vec![
3758     ///         "prog", "--other", "SPECIAL"
3759     ///     ]);
3760     ///
3761     /// // By default, the comparison is case-sensitive, so "cfg" wasn't required
3762     /// assert!(res.is_ok());
3763     ///
3764     /// let res = Command::new("prog")
3765     ///     .arg(Arg::new("cfg")
3766     ///         .takes_value(true)
3767     ///         .required_if_eq("other", "special")
3768     ///         .long("config"))
3769     ///     .arg(Arg::new("other")
3770     ///         .long("other")
3771     ///         .ignore_case(true)
3772     ///         .takes_value(true))
3773     ///     .try_get_matches_from(vec![
3774     ///         "prog", "--other", "SPECIAL"
3775     ///     ]);
3776     ///
3777     /// // However, case-insensitive comparisons can be enabled.  This typically occurs when using Arg::possible_values().
3778     /// assert!(res.is_err());
3779     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3780     /// ```
3781     /// [`Arg::requires(name)`]: Arg::requires()
3782     /// [Conflicting]: Arg::conflicts_with()
3783     /// [required]: Arg::required()
3784     #[must_use]
required_if_eq<T: Key>(mut self, arg_id: T, val: &'help str) -> Self3785     pub fn required_if_eq<T: Key>(mut self, arg_id: T, val: &'help str) -> Self {
3786         self.r_ifs.push((arg_id.into(), val));
3787         self
3788     }
3789 
3790     /// Specify this argument is [required] based on multiple conditions.
3791     ///
3792     /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become
3793     /// valid if one of the specified `arg`'s value equals its corresponding `val`.
3794     ///
3795     /// # Examples
3796     ///
3797     /// ```rust
3798     /// # use clap::Arg;
3799     /// Arg::new("config")
3800     ///     .required_if_eq_any(&[
3801     ///         ("extra", "val"),
3802     ///         ("option", "spec")
3803     ///     ])
3804     /// # ;
3805     /// ```
3806     ///
3807     /// Setting `Arg::required_if_eq_any(&[(arg, val)])` makes this arg required if any of the `arg`s
3808     /// are used at runtime and it's corresponding value is equal to `val`. If the `arg`'s value is
3809     /// anything other than `val`, this argument isn't required.
3810     ///
3811     /// ```rust
3812     /// # use clap::{Command, Arg};
3813     /// let res = Command::new("prog")
3814     ///     .arg(Arg::new("cfg")
3815     ///         .required_if_eq_any(&[
3816     ///             ("extra", "val"),
3817     ///             ("option", "spec")
3818     ///         ])
3819     ///         .takes_value(true)
3820     ///         .long("config"))
3821     ///     .arg(Arg::new("extra")
3822     ///         .takes_value(true)
3823     ///         .long("extra"))
3824     ///     .arg(Arg::new("option")
3825     ///         .takes_value(true)
3826     ///         .long("option"))
3827     ///     .try_get_matches_from(vec![
3828     ///         "prog", "--option", "other"
3829     ///     ]);
3830     ///
3831     /// assert!(res.is_ok()); // We didn't use --option=spec, or --extra=val so "cfg" isn't required
3832     /// ```
3833     ///
3834     /// Setting `Arg::required_if_eq_any(&[(arg, val)])` and having any of the `arg`s used with its
3835     /// value of `val` but *not* using this arg is an error.
3836     ///
3837     /// ```rust
3838     /// # use clap::{Command, Arg, ErrorKind};
3839     /// let res = Command::new("prog")
3840     ///     .arg(Arg::new("cfg")
3841     ///         .required_if_eq_any(&[
3842     ///             ("extra", "val"),
3843     ///             ("option", "spec")
3844     ///         ])
3845     ///         .takes_value(true)
3846     ///         .long("config"))
3847     ///     .arg(Arg::new("extra")
3848     ///         .takes_value(true)
3849     ///         .long("extra"))
3850     ///     .arg(Arg::new("option")
3851     ///         .takes_value(true)
3852     ///         .long("option"))
3853     ///     .try_get_matches_from(vec![
3854     ///         "prog", "--option", "spec"
3855     ///     ]);
3856     ///
3857     /// assert!(res.is_err());
3858     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3859     /// ```
3860     /// [`Arg::requires(name)`]: Arg::requires()
3861     /// [Conflicting]: Arg::conflicts_with()
3862     /// [required]: Arg::required()
3863     #[must_use]
required_if_eq_any<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self3864     pub fn required_if_eq_any<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
3865         self.r_ifs
3866             .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val)));
3867         self
3868     }
3869 
3870     /// Specify this argument is [required] based on multiple conditions.
3871     ///
3872     /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become
3873     /// valid if every one of the specified `arg`'s value equals its corresponding `val`.
3874     ///
3875     /// # Examples
3876     ///
3877     /// ```rust
3878     /// # use clap::Arg;
3879     /// Arg::new("config")
3880     ///     .required_if_eq_all(&[
3881     ///         ("extra", "val"),
3882     ///         ("option", "spec")
3883     ///     ])
3884     /// # ;
3885     /// ```
3886     ///
3887     /// Setting `Arg::required_if_eq_all(&[(arg, val)])` makes this arg required if all of the `arg`s
3888     /// are used at runtime and every value is equal to its corresponding `val`. If the `arg`'s value is
3889     /// anything other than `val`, this argument isn't required.
3890     ///
3891     /// ```rust
3892     /// # use clap::{Command, Arg};
3893     /// let res = Command::new("prog")
3894     ///     .arg(Arg::new("cfg")
3895     ///         .required_if_eq_all(&[
3896     ///             ("extra", "val"),
3897     ///             ("option", "spec")
3898     ///         ])
3899     ///         .takes_value(true)
3900     ///         .long("config"))
3901     ///     .arg(Arg::new("extra")
3902     ///         .takes_value(true)
3903     ///         .long("extra"))
3904     ///     .arg(Arg::new("option")
3905     ///         .takes_value(true)
3906     ///         .long("option"))
3907     ///     .try_get_matches_from(vec![
3908     ///         "prog", "--option", "spec"
3909     ///     ]);
3910     ///
3911     /// assert!(res.is_ok()); // We didn't use --option=spec --extra=val so "cfg" isn't required
3912     /// ```
3913     ///
3914     /// Setting `Arg::required_if_eq_all(&[(arg, val)])` and having all of the `arg`s used with its
3915     /// value of `val` but *not* using this arg is an error.
3916     ///
3917     /// ```rust
3918     /// # use clap::{Command, Arg, ErrorKind};
3919     /// let res = Command::new("prog")
3920     ///     .arg(Arg::new("cfg")
3921     ///         .required_if_eq_all(&[
3922     ///             ("extra", "val"),
3923     ///             ("option", "spec")
3924     ///         ])
3925     ///         .takes_value(true)
3926     ///         .long("config"))
3927     ///     .arg(Arg::new("extra")
3928     ///         .takes_value(true)
3929     ///         .long("extra"))
3930     ///     .arg(Arg::new("option")
3931     ///         .takes_value(true)
3932     ///         .long("option"))
3933     ///     .try_get_matches_from(vec![
3934     ///         "prog", "--extra", "val", "--option", "spec"
3935     ///     ]);
3936     ///
3937     /// assert!(res.is_err());
3938     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3939     /// ```
3940     /// [required]: Arg::required()
3941     #[must_use]
required_if_eq_all<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self3942     pub fn required_if_eq_all<T: Key>(mut self, ifs: &[(T, &'help str)]) -> Self {
3943         self.r_ifs_all
3944             .extend(ifs.iter().map(|(id, val)| (Id::from_ref(id), *val)));
3945         self
3946     }
3947 
3948     /// Require another argument if this arg was present at runtime and its value equals to `val`.
3949     ///
3950     /// This method takes `value, another_arg` pair. At runtime, clap will check
3951     /// if this arg (`self`) is present and its value equals to `val`.
3952     /// If it does, `another_arg` will be marked as required.
3953     ///
3954     /// # Examples
3955     ///
3956     /// ```rust
3957     /// # use clap::Arg;
3958     /// Arg::new("config")
3959     ///     .requires_if("val", "arg")
3960     /// # ;
3961     /// ```
3962     ///
3963     /// Setting `Arg::requires_if(val, arg)` requires that the `arg` be used at runtime if the
3964     /// defining argument's value is equal to `val`. If the defining argument is anything other than
3965     /// `val`, the other argument isn't required.
3966     ///
3967     /// ```rust
3968     /// # use clap::{Command, Arg};
3969     /// let res = Command::new("prog")
3970     ///     .arg(Arg::new("cfg")
3971     ///         .takes_value(true)
3972     ///         .requires_if("my.cfg", "other")
3973     ///         .long("config"))
3974     ///     .arg(Arg::new("other"))
3975     ///     .try_get_matches_from(vec![
3976     ///         "prog", "--config", "some.cfg"
3977     ///     ]);
3978     ///
3979     /// assert!(res.is_ok()); // We didn't use --config=my.cfg, so other wasn't required
3980     /// ```
3981     ///
3982     /// Setting `Arg::requires_if(val, arg)` and setting the value to `val` but *not* supplying
3983     /// `arg` is an error.
3984     ///
3985     /// ```rust
3986     /// # use clap::{Command, Arg, ErrorKind};
3987     /// let res = Command::new("prog")
3988     ///     .arg(Arg::new("cfg")
3989     ///         .takes_value(true)
3990     ///         .requires_if("my.cfg", "input")
3991     ///         .long("config"))
3992     ///     .arg(Arg::new("input"))
3993     ///     .try_get_matches_from(vec![
3994     ///         "prog", "--config", "my.cfg"
3995     ///     ]);
3996     ///
3997     /// assert!(res.is_err());
3998     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3999     /// ```
4000     /// [`Arg::requires(name)`]: Arg::requires()
4001     /// [Conflicting]: Arg::conflicts_with()
4002     /// [override]: Arg::overrides_with()
4003     #[must_use]
requires_if<T: Key>(mut self, val: &'help str, arg_id: T) -> Self4004     pub fn requires_if<T: Key>(mut self, val: &'help str, arg_id: T) -> Self {
4005         self.requires
4006             .push((ArgPredicate::Equals(OsStr::new(val)), arg_id.into()));
4007         self
4008     }
4009 
4010     /// Allows multiple conditional requirements.
4011     ///
4012     /// The requirement will only become valid if this arg's value equals `val`.
4013     ///
4014     /// # Examples
4015     ///
4016     /// ```rust
4017     /// # use clap::Arg;
4018     /// Arg::new("config")
4019     ///     .requires_ifs(&[
4020     ///         ("val", "arg"),
4021     ///         ("other_val", "arg2"),
4022     ///     ])
4023     /// # ;
4024     /// ```
4025     ///
4026     /// Setting `Arg::requires_ifs(&["val", "arg"])` requires that the `arg` be used at runtime if the
4027     /// defining argument's value is equal to `val`. If the defining argument's value is anything other
4028     /// than `val`, `arg` isn't required.
4029     ///
4030     /// ```rust
4031     /// # use clap::{Command, Arg, ErrorKind};
4032     /// let res = Command::new("prog")
4033     ///     .arg(Arg::new("cfg")
4034     ///         .takes_value(true)
4035     ///         .requires_ifs(&[
4036     ///             ("special.conf", "opt"),
4037     ///             ("other.conf", "other"),
4038     ///         ])
4039     ///         .long("config"))
4040     ///     .arg(Arg::new("opt")
4041     ///         .long("option")
4042     ///         .takes_value(true))
4043     ///     .arg(Arg::new("other"))
4044     ///     .try_get_matches_from(vec![
4045     ///         "prog", "--config", "special.conf"
4046     ///     ]);
4047     ///
4048     /// assert!(res.is_err()); // We  used --config=special.conf so --option <val> is required
4049     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
4050     /// ```
4051     /// [`Arg::requires(name)`]: Arg::requires()
4052     /// [Conflicting]: Arg::conflicts_with()
4053     /// [override]: Arg::overrides_with()
4054     #[must_use]
requires_ifs<T: Key>(mut self, ifs: &[(&'help str, T)]) -> Self4055     pub fn requires_ifs<T: Key>(mut self, ifs: &[(&'help str, T)]) -> Self {
4056         self.requires.extend(
4057             ifs.iter()
4058                 .map(|(val, arg)| (ArgPredicate::Equals(OsStr::new(*val)), Id::from(arg))),
4059         );
4060         self
4061     }
4062 
4063     /// Require these arguments names when this one is presen
4064     ///
4065     /// i.e. when using this argument, the following arguments *must* be present.
4066     ///
4067     /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required
4068     /// by default.
4069     ///
4070     /// # Examples
4071     ///
4072     /// ```rust
4073     /// # use clap::Arg;
4074     /// Arg::new("config")
4075     ///     .requires_all(&["input", "output"])
4076     /// # ;
4077     /// ```
4078     ///
4079     /// Setting `Arg::requires_all(&[arg, arg2])` requires that all the arguments be used at
4080     /// runtime if the defining argument is used. If the defining argument isn't used, the other
4081     /// argument isn't required
4082     ///
4083     /// ```rust
4084     /// # use clap::{Command, Arg};
4085     /// let res = Command::new("prog")
4086     ///     .arg(Arg::new("cfg")
4087     ///         .takes_value(true)
4088     ///         .requires("input")
4089     ///         .long("config"))
4090     ///     .arg(Arg::new("input"))
4091     ///     .arg(Arg::new("output"))
4092     ///     .try_get_matches_from(vec![
4093     ///         "prog"
4094     ///     ]);
4095     ///
4096     /// assert!(res.is_ok()); // We didn't use cfg, so input and output weren't required
4097     /// ```
4098     ///
4099     /// Setting `Arg::requires_all(&[arg, arg2])` and *not* supplying all the arguments is an
4100     /// error.
4101     ///
4102     /// ```rust
4103     /// # use clap::{Command, Arg, ErrorKind};
4104     /// let res = Command::new("prog")
4105     ///     .arg(Arg::new("cfg")
4106     ///         .takes_value(true)
4107     ///         .requires_all(&["input", "output"])
4108     ///         .long("config"))
4109     ///     .arg(Arg::new("input"))
4110     ///     .arg(Arg::new("output"))
4111     ///     .try_get_matches_from(vec![
4112     ///         "prog", "--config", "file.conf", "in.txt"
4113     ///     ]);
4114     ///
4115     /// assert!(res.is_err());
4116     /// // We didn't use output
4117     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
4118     /// ```
4119     /// [Conflicting]: Arg::conflicts_with()
4120     /// [override]: Arg::overrides_with()
4121     #[must_use]
requires_all<T: Key>(mut self, names: &[T]) -> Self4122     pub fn requires_all<T: Key>(mut self, names: &[T]) -> Self {
4123         self.requires
4124             .extend(names.iter().map(|s| (ArgPredicate::IsPresent, s.into())));
4125         self
4126     }
4127 
4128     /// This argument is mutually exclusive with the specified argument.
4129     ///
4130     /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules
4131     /// only need to be set for one of the two arguments, they do not need to be set for each.
4132     ///
4133     /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
4134     /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not
4135     /// need to also do B.conflicts_with(A))
4136     ///
4137     /// **NOTE:** [`Arg::conflicts_with_all(names)`] allows specifying an argument which conflicts with more than one argument.
4138     ///
4139     /// **NOTE** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
4140     ///
4141     /// # Examples
4142     ///
4143     /// ```rust
4144     /// # use clap::Arg;
4145     /// Arg::new("config")
4146     ///     .conflicts_with("debug")
4147     /// # ;
4148     /// ```
4149     ///
4150     /// Setting conflicting argument, and having both arguments present at runtime is an error.
4151     ///
4152     /// ```rust
4153     /// # use clap::{Command, Arg, ErrorKind};
4154     /// let res = Command::new("prog")
4155     ///     .arg(Arg::new("cfg")
4156     ///         .takes_value(true)
4157     ///         .conflicts_with("debug")
4158     ///         .long("config"))
4159     ///     .arg(Arg::new("debug")
4160     ///         .long("debug"))
4161     ///     .try_get_matches_from(vec![
4162     ///         "prog", "--debug", "--config", "file.conf"
4163     ///     ]);
4164     ///
4165     /// assert!(res.is_err());
4166     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict);
4167     /// ```
4168     ///
4169     /// [`Arg::conflicts_with_all(names)`]: Arg::conflicts_with_all()
4170     /// [`Arg::exclusive(true)`]: Arg::exclusive()
4171     #[must_use]
conflicts_with<T: Key>(mut self, arg_id: T) -> Self4172     pub fn conflicts_with<T: Key>(mut self, arg_id: T) -> Self {
4173         self.blacklist.push(arg_id.into());
4174         self
4175     }
4176 
4177     /// This argument is mutually exclusive with the specified arguments.
4178     ///
4179     /// See [`Arg::conflicts_with`].
4180     ///
4181     /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules
4182     /// only need to be set for one of the two arguments, they do not need to be set for each.
4183     ///
4184     /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
4185     /// (i.e. if A conflicts with B, defining A.conflicts_with(B) is sufficient. You do not need
4186     /// need to also do B.conflicts_with(A))
4187     ///
4188     /// **NOTE:** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
4189     ///
4190     /// # Examples
4191     ///
4192     /// ```rust
4193     /// # use clap::Arg;
4194     /// Arg::new("config")
4195     ///     .conflicts_with_all(&["debug", "input"])
4196     /// # ;
4197     /// ```
4198     ///
4199     /// Setting conflicting argument, and having any of the arguments present at runtime with a
4200     /// conflicting argument is an error.
4201     ///
4202     /// ```rust
4203     /// # use clap::{Command, Arg, ErrorKind};
4204     /// let res = Command::new("prog")
4205     ///     .arg(Arg::new("cfg")
4206     ///         .takes_value(true)
4207     ///         .conflicts_with_all(&["debug", "input"])
4208     ///         .long("config"))
4209     ///     .arg(Arg::new("debug")
4210     ///         .long("debug"))
4211     ///     .arg(Arg::new("input"))
4212     ///     .try_get_matches_from(vec![
4213     ///         "prog", "--config", "file.conf", "file.txt"
4214     ///     ]);
4215     ///
4216     /// assert!(res.is_err());
4217     /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict);
4218     /// ```
4219     /// [`Arg::conflicts_with`]: Arg::conflicts_with()
4220     /// [`Arg::exclusive(true)`]: Arg::exclusive()
4221     #[must_use]
conflicts_with_all(mut self, names: &[&str]) -> Self4222     pub fn conflicts_with_all(mut self, names: &[&str]) -> Self {
4223         self.blacklist.extend(names.iter().copied().map(Id::from));
4224         self
4225     }
4226 
4227     /// Sets an overridable argument.
4228     ///
4229     /// i.e. this argument and the following argument
4230     /// will override each other in POSIX style (whichever argument was specified at runtime
4231     /// **last** "wins")
4232     ///
4233     /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any
4234     /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed
4235     ///
4236     /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with`].
4237     ///
4238     /// **WARNING:** Positional arguments and options which accept
4239     /// [`Arg::multiple_occurrences`] cannot override themselves (or we
4240     /// would never be able to advance to the next positional). If a positional
4241     /// argument or option with one of the [`Arg::multiple_occurrences`]
4242     /// settings lists itself as an override, it is simply ignored.
4243     ///
4244     /// # Examples
4245     ///
4246     /// ```rust
4247     /// # use clap::{Command, arg};
4248     /// let m = Command::new("prog")
4249     ///     .arg(arg!(-f --flag "some flag")
4250     ///         .conflicts_with("debug"))
4251     ///     .arg(arg!(-d --debug "other flag"))
4252     ///     .arg(arg!(-c --color "third flag")
4253     ///         .overrides_with("flag"))
4254     ///     .get_matches_from(vec![
4255     ///         "prog", "-f", "-d", "-c"]);
4256     ///             //    ^~~~~~~~~~~~^~~~~ flag is overridden by color
4257     ///
4258     /// assert!(m.is_present("color"));
4259     /// assert!(m.is_present("debug")); // even though flag conflicts with debug, it's as if flag
4260     ///                                 // was never used because it was overridden with color
4261     /// assert!(!m.is_present("flag"));
4262     /// ```
4263     /// Care must be taken when using this setting, and having an arg override with itself. This
4264     /// is common practice when supporting things like shell aliases, config files, etc.
4265     /// However, when combined with multiple values, it can get dicy.
4266     /// Here is how clap handles such situations:
4267     ///
4268     /// When a flag overrides itself, it's as if the flag was only ever used once (essentially
4269     /// preventing a "Unexpected multiple usage" error):
4270     ///
4271     /// ```rust
4272     /// # use clap::{Command, arg};
4273     /// let m = Command::new("posix")
4274     ///             .arg(arg!(--flag  "some flag").overrides_with("flag"))
4275     ///             .get_matches_from(vec!["posix", "--flag", "--flag"]);
4276     /// assert!(m.is_present("flag"));
4277     /// ```
4278     ///
4279     /// Making an arg [`Arg::multiple_occurrences`] and override itself
4280     /// is essentially meaningless. Therefore clap ignores an override of self
4281     /// if it's a flag and it already accepts multiple occurrences.
4282     ///
4283     /// ```
4284     /// # use clap::{Command, arg};
4285     /// let m = Command::new("posix")
4286     ///             .arg(arg!(--flag ...  "some flag").overrides_with("flag"))
4287     ///             .get_matches_from(vec!["", "--flag", "--flag", "--flag", "--flag"]);
4288     /// assert!(m.is_present("flag"));
4289     /// ```
4290     ///
4291     /// Now notice with options (which *do not* set
4292     /// [`Arg::multiple_occurrences`]), it's as if only the last
4293     /// occurrence happened.
4294     ///
4295     /// ```
4296     /// # use clap::{Command, arg};
4297     /// let m = Command::new("posix")
4298     ///             .arg(arg!(--opt <val> "some option").overrides_with("opt"))
4299     ///             .get_matches_from(vec!["", "--opt=some", "--opt=other"]);
4300     /// assert!(m.is_present("opt"));
4301     /// assert_eq!(m.value_of("opt"), Some("other"));
4302     /// ```
4303     ///
4304     /// This will also work when [`Arg::multiple_values`] is enabled:
4305     ///
4306     /// ```
4307     /// # use clap::{Command, Arg};
4308     /// let m = Command::new("posix")
4309     ///             .arg(
4310     ///                 Arg::new("opt")
4311     ///                     .long("opt")
4312     ///                     .takes_value(true)
4313     ///                     .multiple_values(true)
4314     ///                     .overrides_with("opt")
4315     ///             )
4316     ///             .get_matches_from(vec!["", "--opt", "1", "2", "--opt", "3", "4", "5"]);
4317     /// assert!(m.is_present("opt"));
4318     /// assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["3", "4", "5"]);
4319     /// ```
4320     ///
4321     /// Just like flags, options with [`Arg::multiple_occurrences`] set
4322     /// will ignore the "override self" setting.
4323     ///
4324     /// ```
4325     /// # use clap::{Command, arg};
4326     /// let m = Command::new("posix")
4327     ///             .arg(arg!(--opt <val> ... "some option")
4328     ///                 .multiple_values(true)
4329     ///                 .overrides_with("opt"))
4330     ///             .get_matches_from(vec!["", "--opt", "first", "over", "--opt", "other", "val"]);
4331     /// assert!(m.is_present("opt"));
4332     /// assert_eq!(m.values_of("opt").unwrap().collect::<Vec<_>>(), &["first", "over", "other", "val"]);
4333     /// ```
4334     #[must_use]
overrides_with<T: Key>(mut self, arg_id: T) -> Self4335     pub fn overrides_with<T: Key>(mut self, arg_id: T) -> Self {
4336         self.overrides.push(arg_id.into());
4337         self
4338     }
4339 
4340     /// Sets multiple mutually overridable arguments by name.
4341     ///
4342     /// i.e. this argument and the following argument will override each other in POSIX style
4343     /// (whichever argument was specified at runtime **last** "wins")
4344     ///
4345     /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any
4346     /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed
4347     ///
4348     /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with_all`].
4349     ///
4350     /// # Examples
4351     ///
4352     /// ```rust
4353     /// # use clap::{Command, arg};
4354     /// let m = Command::new("prog")
4355     ///     .arg(arg!(-f --flag "some flag")
4356     ///         .conflicts_with("color"))
4357     ///     .arg(arg!(-d --debug "other flag"))
4358     ///     .arg(arg!(-c --color "third flag")
4359     ///         .overrides_with_all(&["flag", "debug"]))
4360     ///     .get_matches_from(vec![
4361     ///         "prog", "-f", "-d", "-c"]);
4362     ///             //    ^~~~~~^~~~~~~~~ flag and debug are overridden by color
4363     ///
4364     /// assert!(m.is_present("color")); // even though flag conflicts with color, it's as if flag
4365     ///                                 // and debug were never used because they were overridden
4366     ///                                 // with color
4367     /// assert!(!m.is_present("debug"));
4368     /// assert!(!m.is_present("flag"));
4369     /// ```
4370     #[must_use]
overrides_with_all<T: Key>(mut self, names: &[T]) -> Self4371     pub fn overrides_with_all<T: Key>(mut self, names: &[T]) -> Self {
4372         self.overrides.extend(names.iter().map(Id::from));
4373         self
4374     }
4375 }
4376 
4377 /// # Reflection
4378 impl<'help> Arg<'help> {
4379     /// Get the name of the argument
4380     #[inline]
get_id(&self) -> &'help str4381     pub fn get_id(&self) -> &'help str {
4382         self.name
4383     }
4384 
4385     /// Deprecated, replaced with [`Arg::get_id`]
4386     #[cfg_attr(
4387         feature = "deprecated",
4388         deprecated(since = "3.1.0", note = "Replaced with `Arg::get_id`")
4389     )]
get_name(&self) -> &'help str4390     pub fn get_name(&self) -> &'help str {
4391         self.get_id()
4392     }
4393 
4394     /// Get the help specified for this argument, if any
4395     #[inline]
get_help(&self) -> Option<&'help str>4396     pub fn get_help(&self) -> Option<&'help str> {
4397         self.help
4398     }
4399 
4400     /// Get the long help specified for this argument, if any
4401     ///
4402     /// # Examples
4403     ///
4404     /// ```rust
4405     /// # use clap::Arg;
4406     /// let arg = Arg::new("foo").long_help("long help");
4407     /// assert_eq!(Some("long help"), arg.get_long_help());
4408     /// ```
4409     ///
4410     #[inline]
get_long_help(&self) -> Option<&'help str>4411     pub fn get_long_help(&self) -> Option<&'help str> {
4412         self.long_help
4413     }
4414 
4415     /// Get the help heading specified for this argument, if any
4416     #[inline]
get_help_heading(&self) -> Option<&'help str>4417     pub fn get_help_heading(&self) -> Option<&'help str> {
4418         self.help_heading.unwrap_or_default()
4419     }
4420 
4421     /// Get the short option name for this argument, if any
4422     #[inline]
get_short(&self) -> Option<char>4423     pub fn get_short(&self) -> Option<char> {
4424         self.short
4425     }
4426 
4427     /// Get visible short aliases for this argument, if any
4428     #[inline]
get_visible_short_aliases(&self) -> Option<Vec<char>>4429     pub fn get_visible_short_aliases(&self) -> Option<Vec<char>> {
4430         if self.short_aliases.is_empty() {
4431             None
4432         } else {
4433             Some(
4434                 self.short_aliases
4435                     .iter()
4436                     .filter_map(|(c, v)| if *v { Some(c) } else { None })
4437                     .copied()
4438                     .collect(),
4439             )
4440         }
4441     }
4442 
4443     /// Get *all* short aliases for this argument, if any, both visible and hidden.
4444     #[inline]
get_all_short_aliases(&self) -> Option<Vec<char>>4445     pub fn get_all_short_aliases(&self) -> Option<Vec<char>> {
4446         if self.short_aliases.is_empty() {
4447             None
4448         } else {
4449             Some(self.short_aliases.iter().map(|(s, _)| s).copied().collect())
4450         }
4451     }
4452 
4453     /// Get the short option name and its visible aliases, if any
4454     #[inline]
get_short_and_visible_aliases(&self) -> Option<Vec<char>>4455     pub fn get_short_and_visible_aliases(&self) -> Option<Vec<char>> {
4456         let mut shorts = match self.short {
4457             Some(short) => vec![short],
4458             None => return None,
4459         };
4460         if let Some(aliases) = self.get_visible_short_aliases() {
4461             shorts.extend(aliases);
4462         }
4463         Some(shorts)
4464     }
4465 
4466     /// Get the long option name for this argument, if any
4467     #[inline]
get_long(&self) -> Option<&'help str>4468     pub fn get_long(&self) -> Option<&'help str> {
4469         self.long
4470     }
4471 
4472     /// Get visible aliases for this argument, if any
4473     #[inline]
get_visible_aliases(&self) -> Option<Vec<&'help str>>4474     pub fn get_visible_aliases(&self) -> Option<Vec<&'help str>> {
4475         if self.aliases.is_empty() {
4476             None
4477         } else {
4478             Some(
4479                 self.aliases
4480                     .iter()
4481                     .filter_map(|(s, v)| if *v { Some(s) } else { None })
4482                     .copied()
4483                     .collect(),
4484             )
4485         }
4486     }
4487 
4488     /// Get *all* aliases for this argument, if any, both visible and hidden.
4489     #[inline]
get_all_aliases(&self) -> Option<Vec<&'help str>>4490     pub fn get_all_aliases(&self) -> Option<Vec<&'help str>> {
4491         if self.aliases.is_empty() {
4492             None
4493         } else {
4494             Some(self.aliases.iter().map(|(s, _)| s).copied().collect())
4495         }
4496     }
4497 
4498     /// Get the long option name and its visible aliases, if any
4499     #[inline]
get_long_and_visible_aliases(&self) -> Option<Vec<&'help str>>4500     pub fn get_long_and_visible_aliases(&self) -> Option<Vec<&'help str>> {
4501         let mut longs = match self.long {
4502             Some(long) => vec![long],
4503             None => return None,
4504         };
4505         if let Some(aliases) = self.get_visible_aliases() {
4506             longs.extend(aliases);
4507         }
4508         Some(longs)
4509     }
4510 
4511     /// Deprecated, replaced with [`Arg::get_value_parser().possible_values()`]
4512     #[cfg_attr(
4513         feature = "deprecated",
4514         deprecated(
4515             since = "3.2.0",
4516             note = "Replaced with `Arg::get_value_parser().possible_values()`"
4517         )
4518     )]
get_possible_values(&self) -> Option<&[PossibleValue<'help>]>4519     pub fn get_possible_values(&self) -> Option<&[PossibleValue<'help>]> {
4520         if self.possible_vals.is_empty() {
4521             None
4522         } else {
4523             Some(&self.possible_vals)
4524         }
4525     }
4526 
get_possible_values2(&self) -> Vec<PossibleValue<'help>>4527     pub(crate) fn get_possible_values2(&self) -> Vec<PossibleValue<'help>> {
4528         #![allow(deprecated)]
4529         if !self.is_takes_value_set() {
4530             vec![]
4531         } else if let Some(pvs) = self.get_possible_values() {
4532             // Check old first in case the user explicitly set possible values and the derive inferred
4533             // a `ValueParser` with some.
4534             pvs.to_vec()
4535         } else {
4536             self.get_value_parser()
4537                 .possible_values()
4538                 .map(|pvs| pvs.collect())
4539                 .unwrap_or_default()
4540         }
4541     }
4542 
4543     /// Get the names of values for this argument.
4544     #[inline]
get_value_names(&self) -> Option<&[&'help str]>4545     pub fn get_value_names(&self) -> Option<&[&'help str]> {
4546         if self.val_names.is_empty() {
4547             None
4548         } else {
4549             Some(&self.val_names)
4550         }
4551     }
4552 
4553     /// Get the number of values for this argument.
4554     #[inline]
get_num_vals(&self) -> Option<usize>4555     pub fn get_num_vals(&self) -> Option<usize> {
4556         self.num_vals
4557     }
4558 
4559     /// Get the delimiter between multiple values
4560     #[inline]
get_value_delimiter(&self) -> Option<char>4561     pub fn get_value_delimiter(&self) -> Option<char> {
4562         self.val_delim
4563     }
4564 
4565     /// Get the index of this argument, if any
4566     #[inline]
get_index(&self) -> Option<usize>4567     pub fn get_index(&self) -> Option<usize> {
4568         self.index
4569     }
4570 
4571     /// Get the value hint of this argument
get_value_hint(&self) -> ValueHint4572     pub fn get_value_hint(&self) -> ValueHint {
4573         self.value_hint.unwrap_or_else(|| {
4574             if self.is_takes_value_set() {
4575                 let type_id = self.get_value_parser().type_id();
4576                 if type_id == crate::parser::AnyValueId::of::<std::path::PathBuf>() {
4577                     ValueHint::AnyPath
4578                 } else {
4579                     ValueHint::default()
4580                 }
4581             } else {
4582                 ValueHint::default()
4583             }
4584         })
4585     }
4586 
4587     /// Deprecated, replaced with [`Arg::is_global_set`]
4588     #[cfg_attr(
4589         feature = "deprecated",
4590         deprecated(since = "3.1.0", note = "Replaced with `Arg::is_global_set`")
4591     )]
get_global(&self) -> bool4592     pub fn get_global(&self) -> bool {
4593         self.is_global_set()
4594     }
4595 
4596     /// Get the environment variable name specified for this argument, if any
4597     ///
4598     /// # Examples
4599     ///
4600     /// ```rust
4601     /// # use std::ffi::OsStr;
4602     /// # use clap::Arg;
4603     /// let arg = Arg::new("foo").env("ENVIRONMENT");
4604     /// assert_eq!(Some(OsStr::new("ENVIRONMENT")), arg.get_env());
4605     /// ```
4606     #[cfg(feature = "env")]
get_env(&self) -> Option<&OsStr>4607     pub fn get_env(&self) -> Option<&OsStr> {
4608         self.env.as_ref().map(|x| x.0)
4609     }
4610 
4611     /// Get the default values specified for this argument, if any
4612     ///
4613     /// # Examples
4614     ///
4615     /// ```rust
4616     /// # use clap::Arg;
4617     /// let arg = Arg::new("foo").default_value("default value");
4618     /// assert_eq!(&["default value"], arg.get_default_values());
4619     /// ```
get_default_values(&self) -> &[&OsStr]4620     pub fn get_default_values(&self) -> &[&OsStr] {
4621         &self.default_vals
4622     }
4623 
4624     /// Checks whether this argument is a positional or not.
4625     ///
4626     /// # Examples
4627     ///
4628     /// ```
4629     /// # use clap::Arg;
4630     /// let arg = Arg::new("foo");
4631     /// assert_eq!(true, arg.is_positional());
4632     ///
4633     /// let arg = Arg::new("foo").long("foo");
4634     /// assert_eq!(false, arg.is_positional());
4635     /// ```
is_positional(&self) -> bool4636     pub fn is_positional(&self) -> bool {
4637         self.long.is_none() && self.short.is_none()
4638     }
4639 
4640     /// Reports whether [`Arg::required`] is set
is_required_set(&self) -> bool4641     pub fn is_required_set(&self) -> bool {
4642         self.is_set(ArgSettings::Required)
4643     }
4644 
4645     /// Report whether [`Arg::multiple_values`] is set
is_multiple_values_set(&self) -> bool4646     pub fn is_multiple_values_set(&self) -> bool {
4647         self.is_set(ArgSettings::MultipleValues)
4648     }
4649 
4650     /// [`Arg::multiple_occurrences`] is going away  ([Issue #3772](https://github.com/clap-rs/clap/issues/3772))
4651     #[cfg_attr(
4652         feature = "deprecated",
4653         deprecated(since = "3.2.0", note = "`multiple_occurrences` away (Issue #3772)")
4654     )]
is_multiple_occurrences_set(&self) -> bool4655     pub fn is_multiple_occurrences_set(&self) -> bool {
4656         self.is_set(ArgSettings::MultipleOccurrences)
4657     }
4658 
4659     /// Report whether [`Arg::is_takes_value_set`] is set
is_takes_value_set(&self) -> bool4660     pub fn is_takes_value_set(&self) -> bool {
4661         self.is_set(ArgSettings::TakesValue)
4662     }
4663 
4664     /// Report whether [`Arg::allow_hyphen_values`] is set
is_allow_hyphen_values_set(&self) -> bool4665     pub fn is_allow_hyphen_values_set(&self) -> bool {
4666         self.is_set(ArgSettings::AllowHyphenValues)
4667     }
4668 
4669     /// Deprecated, replaced with [`Arg::get_value_parser()`]
4670     #[cfg_attr(
4671         feature = "deprecated",
4672         deprecated(since = "3.2.0", note = "Replaced with `Arg::get_value_parser()`")
4673     )]
is_forbid_empty_values_set(&self) -> bool4674     pub fn is_forbid_empty_values_set(&self) -> bool {
4675         self.is_set(ArgSettings::ForbidEmptyValues)
4676     }
4677 
4678     /// Deprecated, replaced with [`Arg::get_value_parser()`
4679     #[cfg_attr(
4680         feature = "deprecated",
4681         deprecated(since = "3.2.0", note = "Replaced with `Arg::get_value_parser()`")
4682     )]
is_allow_invalid_utf8_set(&self) -> bool4683     pub fn is_allow_invalid_utf8_set(&self) -> bool {
4684         self.is_set(ArgSettings::AllowInvalidUtf8)
4685     }
4686 
4687     /// Behavior when parsing the argument
get_action(&self) -> &super::ArgAction4688     pub fn get_action(&self) -> &super::ArgAction {
4689         const DEFAULT: super::ArgAction = super::ArgAction::StoreValue;
4690         self.action.as_ref().unwrap_or(&DEFAULT)
4691     }
4692 
4693     /// Configured parser for argument values
4694     ///
4695     /// # Example
4696     ///
4697     /// ```rust
4698     /// let cmd = clap::Command::new("raw")
4699     ///     .arg(
4700     ///         clap::Arg::new("port")
4701     ///             .value_parser(clap::value_parser!(usize))
4702     ///     );
4703     /// let value_parser = cmd.get_arguments()
4704     ///     .find(|a| a.get_id() == "port").unwrap()
4705     ///     .get_value_parser();
4706     /// println!("{:?}", value_parser);
4707     /// ```
get_value_parser(&self) -> &super::ValueParser4708     pub fn get_value_parser(&self) -> &super::ValueParser {
4709         if let Some(value_parser) = self.value_parser.as_ref() {
4710             value_parser
4711         } else if self.is_allow_invalid_utf8_set() {
4712             static DEFAULT: super::ValueParser = super::ValueParser::os_string();
4713             &DEFAULT
4714         } else {
4715             static DEFAULT: super::ValueParser = super::ValueParser::string();
4716             &DEFAULT
4717         }
4718     }
4719 
4720     /// Report whether [`Arg::global`] is set
is_global_set(&self) -> bool4721     pub fn is_global_set(&self) -> bool {
4722         self.is_set(ArgSettings::Global)
4723     }
4724 
4725     /// Report whether [`Arg::next_line_help`] is set
is_next_line_help_set(&self) -> bool4726     pub fn is_next_line_help_set(&self) -> bool {
4727         self.is_set(ArgSettings::NextLineHelp)
4728     }
4729 
4730     /// Report whether [`Arg::hide`] is set
is_hide_set(&self) -> bool4731     pub fn is_hide_set(&self) -> bool {
4732         self.is_set(ArgSettings::Hidden)
4733     }
4734 
4735     /// Report whether [`Arg::hide_default_value`] is set
is_hide_default_value_set(&self) -> bool4736     pub fn is_hide_default_value_set(&self) -> bool {
4737         self.is_set(ArgSettings::HideDefaultValue)
4738     }
4739 
4740     /// Report whether [`Arg::hide_possible_values`] is set
is_hide_possible_values_set(&self) -> bool4741     pub fn is_hide_possible_values_set(&self) -> bool {
4742         self.is_set(ArgSettings::HidePossibleValues)
4743     }
4744 
4745     /// Report whether [`Arg::hide_env`] is set
4746     #[cfg(feature = "env")]
is_hide_env_set(&self) -> bool4747     pub fn is_hide_env_set(&self) -> bool {
4748         self.is_set(ArgSettings::HideEnv)
4749     }
4750 
4751     /// Report whether [`Arg::hide_env_values`] is set
4752     #[cfg(feature = "env")]
is_hide_env_values_set(&self) -> bool4753     pub fn is_hide_env_values_set(&self) -> bool {
4754         self.is_set(ArgSettings::HideEnvValues)
4755     }
4756 
4757     /// Report whether [`Arg::hide_short_help`] is set
is_hide_short_help_set(&self) -> bool4758     pub fn is_hide_short_help_set(&self) -> bool {
4759         self.is_set(ArgSettings::HiddenShortHelp)
4760     }
4761 
4762     /// Report whether [`Arg::hide_long_help`] is set
is_hide_long_help_set(&self) -> bool4763     pub fn is_hide_long_help_set(&self) -> bool {
4764         self.is_set(ArgSettings::HiddenLongHelp)
4765     }
4766 
4767     /// Report whether [`Arg::use_value_delimiter`] is set
is_use_value_delimiter_set(&self) -> bool4768     pub fn is_use_value_delimiter_set(&self) -> bool {
4769         self.is_set(ArgSettings::UseValueDelimiter)
4770     }
4771 
4772     /// Report whether [`Arg::require_value_delimiter`] is set
is_require_value_delimiter_set(&self) -> bool4773     pub fn is_require_value_delimiter_set(&self) -> bool {
4774         self.is_set(ArgSettings::RequireDelimiter)
4775     }
4776 
4777     /// Report whether [`Arg::require_equals`] is set
is_require_equals_set(&self) -> bool4778     pub fn is_require_equals_set(&self) -> bool {
4779         self.is_set(ArgSettings::RequireEquals)
4780     }
4781 
4782     /// Reports whether [`Arg::exclusive`] is set
is_exclusive_set(&self) -> bool4783     pub fn is_exclusive_set(&self) -> bool {
4784         self.is_set(ArgSettings::Exclusive)
4785     }
4786 
4787     /// Reports whether [`Arg::last`] is set
is_last_set(&self) -> bool4788     pub fn is_last_set(&self) -> bool {
4789         self.is_set(ArgSettings::Last)
4790     }
4791 
4792     /// Reports whether [`Arg::ignore_case`] is set
is_ignore_case_set(&self) -> bool4793     pub fn is_ignore_case_set(&self) -> bool {
4794         self.is_set(ArgSettings::IgnoreCase)
4795     }
4796 }
4797 
4798 /// # Deprecated
4799 impl<'help> Arg<'help> {
4800     /// Deprecated, replaced with [`Arg::new`]
4801     #[cfg_attr(
4802         feature = "deprecated",
4803         deprecated(since = "3.0.0", note = "Replaced with `Arg::new`")
4804     )]
4805     #[doc(hidden)]
with_name<S: Into<&'help str>>(n: S) -> Self4806     pub fn with_name<S: Into<&'help str>>(n: S) -> Self {
4807         Self::new(n)
4808     }
4809 
4810     /// Deprecated in [Issue #3087](https://github.com/clap-rs/clap/issues/3087), maybe [`clap::Parser`][crate::Parser] would fit your use case?
4811     #[cfg(feature = "yaml")]
4812     #[cfg_attr(
4813         feature = "deprecated",
4814         deprecated(
4815             since = "3.0.0",
4816             note = "Deprecated in Issue #3087, maybe clap::Parser would fit your use case?"
4817         )
4818     )]
4819     #[doc(hidden)]
from_yaml(y: &'help Yaml) -> Self4820     pub fn from_yaml(y: &'help Yaml) -> Self {
4821         #![allow(deprecated)]
4822         let yaml_file_hash = y.as_hash().expect("YAML file must be a hash");
4823         // We WANT this to panic on error...so expect() is good.
4824         let (name_yaml, yaml) = yaml_file_hash
4825             .iter()
4826             .next()
4827             .expect("There must be one arg in the YAML file");
4828         let name_str = name_yaml.as_str().expect("Arg name must be a string");
4829         let mut a = Arg::new(name_str);
4830 
4831         for (k, v) in yaml.as_hash().expect("Arg must be a hash") {
4832             a = match k.as_str().expect("Arg fields must be strings") {
4833                 "short" => yaml_to_char!(a, v, short),
4834                 "long" => yaml_to_str!(a, v, long),
4835                 "aliases" => yaml_vec_or_str!(a, v, alias),
4836                 "help" => yaml_to_str!(a, v, help),
4837                 "long_help" => yaml_to_str!(a, v, long_help),
4838                 "required" => yaml_to_bool!(a, v, required),
4839                 "required_if" => yaml_tuple2!(a, v, required_if_eq),
4840                 "required_ifs" => yaml_tuple2!(a, v, required_if_eq),
4841                 "takes_value" => yaml_to_bool!(a, v, takes_value),
4842                 "index" => yaml_to_usize!(a, v, index),
4843                 "global" => yaml_to_bool!(a, v, global),
4844                 "multiple" => yaml_to_bool!(a, v, multiple),
4845                 "hidden" => yaml_to_bool!(a, v, hide),
4846                 "next_line_help" => yaml_to_bool!(a, v, next_line_help),
4847                 "group" => yaml_to_str!(a, v, group),
4848                 "number_of_values" => yaml_to_usize!(a, v, number_of_values),
4849                 "max_values" => yaml_to_usize!(a, v, max_values),
4850                 "min_values" => yaml_to_usize!(a, v, min_values),
4851                 "value_name" => yaml_to_str!(a, v, value_name),
4852                 "use_delimiter" => yaml_to_bool!(a, v, use_delimiter),
4853                 "allow_hyphen_values" => yaml_to_bool!(a, v, allow_hyphen_values),
4854                 "last" => yaml_to_bool!(a, v, last),
4855                 "require_delimiter" => yaml_to_bool!(a, v, require_delimiter),
4856                 "value_delimiter" => yaml_to_char!(a, v, value_delimiter),
4857                 "required_unless" => yaml_to_str!(a, v, required_unless_present),
4858                 "display_order" => yaml_to_usize!(a, v, display_order),
4859                 "default_value" => yaml_to_str!(a, v, default_value),
4860                 "default_value_if" => yaml_tuple3!(a, v, default_value_if),
4861                 "default_value_ifs" => yaml_tuple3!(a, v, default_value_if),
4862                 #[cfg(feature = "env")]
4863                 "env" => yaml_to_str!(a, v, env),
4864                 "value_names" => yaml_vec_or_str!(a, v, value_name),
4865                 "groups" => yaml_vec_or_str!(a, v, group),
4866                 "requires" => yaml_vec_or_str!(a, v, requires),
4867                 "requires_if" => yaml_tuple2!(a, v, requires_if),
4868                 "requires_ifs" => yaml_tuple2!(a, v, requires_if),
4869                 "conflicts_with" => yaml_vec_or_str!(a, v, conflicts_with),
4870                 "overrides_with" => yaml_to_str!(a, v, overrides_with),
4871                 "possible_values" => yaml_vec_or_str!(a, v, possible_value),
4872                 "case_insensitive" => yaml_to_bool!(a, v, ignore_case),
4873                 "required_unless_one" => yaml_vec!(a, v, required_unless_present_any),
4874                 "required_unless_all" => yaml_vec!(a, v, required_unless_present_all),
4875                 s => {
4876                     panic!(
4877                         "Unknown setting '{}' in YAML file for arg '{}'",
4878                         s, name_str
4879                     )
4880                 }
4881             }
4882         }
4883 
4884         a
4885     }
4886 
4887     /// Deprecated in [Issue #3086](https://github.com/clap-rs/clap/issues/3086), see [`arg!`][crate::arg!].
4888     #[cfg_attr(
4889         feature = "deprecated",
4890         deprecated(since = "3.0.0", note = "Deprecated in Issue #3086, see `clap::arg!")
4891     )]
4892     #[doc(hidden)]
from_usage(u: &'help str) -> Self4893     pub fn from_usage(u: &'help str) -> Self {
4894         UsageParser::from_usage(u).parse()
4895     }
4896 
4897     /// Deprecated, replaced with [`Arg::required_unless_present`]
4898     #[cfg_attr(
4899         feature = "deprecated",
4900         deprecated(since = "3.0.0", note = "Replaced with `Arg::required_unless_present`")
4901     )]
4902     #[doc(hidden)]
4903     #[must_use]
required_unless<T: Key>(self, arg_id: T) -> Self4904     pub fn required_unless<T: Key>(self, arg_id: T) -> Self {
4905         self.required_unless_present(arg_id)
4906     }
4907 
4908     /// Deprecated, replaced with [`Arg::required_unless_present_all`]
4909     #[cfg_attr(
4910         feature = "deprecated",
4911         deprecated(
4912             since = "3.0.0",
4913             note = "Replaced with `Arg::required_unless_present_all`"
4914         )
4915     )]
4916     #[doc(hidden)]
4917     #[must_use]
required_unless_all<T, I>(self, names: I) -> Self where I: IntoIterator<Item = T>, T: Key,4918     pub fn required_unless_all<T, I>(self, names: I) -> Self
4919     where
4920         I: IntoIterator<Item = T>,
4921         T: Key,
4922     {
4923         self.required_unless_present_all(names)
4924     }
4925 
4926     /// Deprecated, replaced with [`Arg::required_unless_present_any`]
4927     #[cfg_attr(
4928         feature = "deprecated",
4929         deprecated(
4930             since = "3.0.0",
4931             note = "Replaced with `Arg::required_unless_present_any`"
4932         )
4933     )]
4934     #[doc(hidden)]
4935     #[must_use]
required_unless_one<T, I>(self, names: I) -> Self where I: IntoIterator<Item = T>, T: Key,4936     pub fn required_unless_one<T, I>(self, names: I) -> Self
4937     where
4938         I: IntoIterator<Item = T>,
4939         T: Key,
4940     {
4941         self.required_unless_present_any(names)
4942     }
4943 
4944     /// Deprecated, replaced with [`Arg::required_if_eq`]
4945     #[cfg_attr(
4946         feature = "deprecated",
4947         deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq`")
4948     )]
4949     #[doc(hidden)]
4950     #[must_use]
required_if<T: Key>(self, arg_id: T, val: &'help str) -> Self4951     pub fn required_if<T: Key>(self, arg_id: T, val: &'help str) -> Self {
4952         self.required_if_eq(arg_id, val)
4953     }
4954 
4955     /// Deprecated, replaced with [`Arg::required_if_eq_any`]
4956     #[cfg_attr(
4957         feature = "deprecated",
4958         deprecated(since = "3.0.0", note = "Replaced with `Arg::required_if_eq_any`")
4959     )]
4960     #[doc(hidden)]
4961     #[must_use]
required_ifs<T: Key>(self, ifs: &[(T, &'help str)]) -> Self4962     pub fn required_ifs<T: Key>(self, ifs: &[(T, &'help str)]) -> Self {
4963         self.required_if_eq_any(ifs)
4964     }
4965 
4966     /// Deprecated, replaced with [`Arg::hide`]
4967     #[cfg_attr(
4968         feature = "deprecated",
4969         deprecated(since = "3.0.0", note = "Replaced with `Arg::hide`")
4970     )]
4971     #[doc(hidden)]
4972     #[inline]
4973     #[must_use]
hidden(self, yes: bool) -> Self4974     pub fn hidden(self, yes: bool) -> Self {
4975         self.hide(yes)
4976     }
4977 
4978     /// Deprecated, replaced with [`Arg::ignore_case`]
4979     #[cfg_attr(
4980         feature = "deprecated",
4981         deprecated(since = "3.0.0", note = "Replaced with `Arg::ignore_case`")
4982     )]
4983     #[doc(hidden)]
4984     #[inline]
4985     #[must_use]
case_insensitive(self, yes: bool) -> Self4986     pub fn case_insensitive(self, yes: bool) -> Self {
4987         self.ignore_case(yes)
4988     }
4989 
4990     /// Deprecated, replaced with [`Arg::forbid_empty_values`]
4991     #[cfg_attr(
4992         feature = "deprecated",
4993         deprecated(since = "3.0.0", note = "Replaced with `Arg::forbid_empty_values`")
4994     )]
4995     #[doc(hidden)]
4996     #[must_use]
empty_values(self, yes: bool) -> Self4997     pub fn empty_values(self, yes: bool) -> Self {
4998         self.forbid_empty_values(!yes)
4999     }
5000 
5001     /// Deprecated, replaced with [`Arg::multiple_occurrences`] (most likely what you want) and
5002     /// [`Arg::multiple_values`]
5003     #[cfg_attr(
5004         feature = "deprecated",
5005         deprecated(
5006             since = "3.0.0",
5007             note = "Split into `Arg::multiple_occurrences` (most likely what you want)  and `Arg::multiple_values`"
5008         )
5009     )]
5010     #[doc(hidden)]
5011     #[must_use]
multiple(self, yes: bool) -> Self5012     pub fn multiple(self, yes: bool) -> Self {
5013         self.multiple_occurrences(yes).multiple_values(yes)
5014     }
5015 
5016     /// Deprecated, replaced with [`Arg::hide_short_help`]
5017     #[cfg_attr(
5018         feature = "deprecated",
5019         deprecated(since = "3.0.0", note = "Replaced with `Arg::hide_short_help`")
5020     )]
5021     #[doc(hidden)]
5022     #[inline]
5023     #[must_use]
hidden_short_help(self, yes: bool) -> Self5024     pub fn hidden_short_help(self, yes: bool) -> Self {
5025         self.hide_short_help(yes)
5026     }
5027 
5028     /// Deprecated, replaced with [`Arg::hide_long_help`]
5029     #[cfg_attr(
5030         feature = "deprecated",
5031         deprecated(since = "3.0.0", note = "Replaced with `Arg::hide_long_help`")
5032     )]
5033     #[doc(hidden)]
5034     #[inline]
5035     #[must_use]
hidden_long_help(self, yes: bool) -> Self5036     pub fn hidden_long_help(self, yes: bool) -> Self {
5037         self.hide_long_help(yes)
5038     }
5039 
5040     /// Deprecated, replaced with [`Arg::setting`]
5041     #[cfg_attr(
5042         feature = "deprecated",
5043         deprecated(since = "3.0.0", note = "Replaced with `Arg::setting`")
5044     )]
5045     #[doc(hidden)]
5046     #[must_use]
set(self, s: ArgSettings) -> Self5047     pub fn set(self, s: ArgSettings) -> Self {
5048         self.setting(s)
5049     }
5050 
5051     /// Deprecated, replaced with [`Arg::unset_setting`]
5052     #[cfg_attr(
5053         feature = "deprecated",
5054         deprecated(since = "3.0.0", note = "Replaced with `Arg::unset_setting`")
5055     )]
5056     #[doc(hidden)]
5057     #[must_use]
unset(self, s: ArgSettings) -> Self5058     pub fn unset(self, s: ArgSettings) -> Self {
5059         self.unset_setting(s)
5060     }
5061 }
5062 
5063 /// # Internally used only
5064 impl<'help> Arg<'help> {
_build(&mut self)5065     pub(crate) fn _build(&mut self) {
5066         if self.is_positional() {
5067             self.settings.set(ArgSettings::TakesValue);
5068         }
5069         if let Some(action) = self.action.as_ref() {
5070             if let Some(default_value) = action.default_value() {
5071                 if self.default_vals.is_empty() {
5072                     self.default_vals = vec![default_value];
5073                 }
5074             }
5075             if action.takes_values() {
5076                 self.settings.set(ArgSettings::TakesValue);
5077             } else {
5078                 self.settings.unset(ArgSettings::TakesValue);
5079             }
5080             match action {
5081                 ArgAction::StoreValue
5082                 | ArgAction::IncOccurrence
5083                 | ArgAction::Help
5084                 | ArgAction::Version => {}
5085                 ArgAction::Set
5086                 | ArgAction::Append
5087                 | ArgAction::SetTrue
5088                 | ArgAction::SetFalse
5089                 | ArgAction::Count => {
5090                     if !self.is_positional() {
5091                         self.settings.set(ArgSettings::MultipleOccurrences);
5092                     }
5093                 }
5094             }
5095         }
5096 
5097         if self.value_parser.is_none() {
5098             if let Some(default) = self.action.as_ref().and_then(|a| a.default_value_parser()) {
5099                 self.value_parser = Some(default);
5100             } else if self.is_allow_invalid_utf8_set() {
5101                 self.value_parser = Some(super::ValueParser::os_string());
5102             } else {
5103                 self.value_parser = Some(super::ValueParser::string());
5104             }
5105         }
5106 
5107         if (self.is_use_value_delimiter_set() || self.is_require_value_delimiter_set())
5108             && self.val_delim.is_none()
5109         {
5110             self.val_delim = Some(',');
5111         }
5112 
5113         let val_names_len = self.val_names.len();
5114 
5115         if val_names_len > 1 {
5116             self.settings.set(ArgSettings::MultipleValues);
5117 
5118             if self.num_vals.is_none() {
5119                 self.num_vals = Some(val_names_len);
5120             }
5121         }
5122 
5123         let self_id = self.id.clone();
5124         if self.is_positional() || self.is_multiple_occurrences_set() {
5125             // Remove self-overrides where they don't make sense.
5126             //
5127             // We can evaluate switching this to a debug assert at a later time (though it will
5128             // require changing propagation of `AllArgsOverrideSelf`).  Being conservative for now
5129             // due to where we are at in the release.
5130             self.overrides.retain(|e| *e != self_id);
5131         }
5132     }
5133 
generated(mut self) -> Self5134     pub(crate) fn generated(mut self) -> Self {
5135         self.provider = ArgProvider::Generated;
5136         self
5137     }
5138 
longest_filter(&self) -> bool5139     pub(crate) fn longest_filter(&self) -> bool {
5140         self.is_takes_value_set() || self.long.is_some() || self.short.is_none()
5141     }
5142 
5143     // Used for positionals when printing
multiple_str(&self) -> &str5144     pub(crate) fn multiple_str(&self) -> &str {
5145         let mult_vals = self.val_names.len() > 1;
5146         if (self.is_multiple_values_set() || self.is_multiple_occurrences_set()) && !mult_vals {
5147             "..."
5148         } else {
5149             ""
5150         }
5151     }
5152 
5153     // Used for positionals when printing
name_no_brackets(&self) -> Cow<str>5154     pub(crate) fn name_no_brackets(&self) -> Cow<str> {
5155         debug!("Arg::name_no_brackets:{}", self.name);
5156         let delim = if self.is_require_value_delimiter_set() {
5157             self.val_delim.expect(INTERNAL_ERROR_MSG)
5158         } else {
5159             ' '
5160         }
5161         .to_string();
5162         if !self.val_names.is_empty() {
5163             debug!("Arg::name_no_brackets: val_names={:#?}", self.val_names);
5164 
5165             if self.val_names.len() > 1 {
5166                 Cow::Owned(
5167                     self.val_names
5168                         .iter()
5169                         .map(|n| format!("<{}>", n))
5170                         .collect::<Vec<_>>()
5171                         .join(&*delim),
5172                 )
5173             } else {
5174                 Cow::Borrowed(self.val_names.get(0).expect(INTERNAL_ERROR_MSG))
5175             }
5176         } else {
5177             debug!("Arg::name_no_brackets: just name");
5178             Cow::Borrowed(self.name)
5179         }
5180     }
5181 
5182     /// Either multiple values or occurrences
is_multiple(&self) -> bool5183     pub(crate) fn is_multiple(&self) -> bool {
5184         self.is_multiple_values_set() | self.is_multiple_occurrences_set()
5185     }
5186 
get_display_order(&self) -> usize5187     pub(crate) fn get_display_order(&self) -> usize {
5188         self.disp_ord.get_explicit()
5189     }
5190 }
5191 
5192 impl<'help> From<&'_ Arg<'help>> for Arg<'help> {
from(a: &Arg<'help>) -> Self5193     fn from(a: &Arg<'help>) -> Self {
5194         a.clone()
5195     }
5196 }
5197 
5198 impl<'help> PartialEq for Arg<'help> {
eq(&self, other: &Arg<'help>) -> bool5199     fn eq(&self, other: &Arg<'help>) -> bool {
5200         self.name == other.name
5201     }
5202 }
5203 
5204 impl<'help> PartialOrd for Arg<'help> {
partial_cmp(&self, other: &Self) -> Option<Ordering>5205     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
5206         Some(self.cmp(other))
5207     }
5208 }
5209 
5210 impl<'help> Ord for Arg<'help> {
cmp(&self, other: &Arg) -> Ordering5211     fn cmp(&self, other: &Arg) -> Ordering {
5212         self.name.cmp(other.name)
5213     }
5214 }
5215 
5216 impl<'help> Eq for Arg<'help> {}
5217 
5218 impl<'help> Display for Arg<'help> {
fmt(&self, f: &mut Formatter) -> fmt::Result5219     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
5220         // Write the name such --long or -l
5221         if let Some(l) = self.long {
5222             write!(f, "--{}", l)?;
5223         } else if let Some(s) = self.short {
5224             write!(f, "-{}", s)?;
5225         }
5226         let mut need_closing_bracket = false;
5227         if !self.is_positional() && self.is_takes_value_set() {
5228             let is_optional_val = self.min_vals == Some(0);
5229             let sep = if self.is_require_equals_set() {
5230                 if is_optional_val {
5231                     need_closing_bracket = true;
5232                     "[="
5233                 } else {
5234                     "="
5235                 }
5236             } else if is_optional_val {
5237                 need_closing_bracket = true;
5238                 " ["
5239             } else {
5240                 " "
5241             };
5242             f.write_str(sep)?;
5243         }
5244         if self.is_takes_value_set() || self.is_positional() {
5245             display_arg_val(self, |s, _| f.write_str(s))?;
5246         }
5247         if need_closing_bracket {
5248             f.write_str("]")?;
5249         }
5250 
5251         Ok(())
5252     }
5253 }
5254 
5255 impl<'help> fmt::Debug for Arg<'help> {
fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error>5256     fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
5257         let mut ds = f.debug_struct("Arg");
5258 
5259         #[allow(unused_mut)]
5260         let mut ds = ds
5261             .field("id", &self.id)
5262             .field("provider", &self.provider)
5263             .field("name", &self.name)
5264             .field("help", &self.help)
5265             .field("long_help", &self.long_help)
5266             .field("action", &self.action)
5267             .field("value_parser", &self.value_parser)
5268             .field("blacklist", &self.blacklist)
5269             .field("settings", &self.settings)
5270             .field("overrides", &self.overrides)
5271             .field("groups", &self.groups)
5272             .field("requires", &self.requires)
5273             .field("r_ifs", &self.r_ifs)
5274             .field("r_unless", &self.r_unless)
5275             .field("short", &self.short)
5276             .field("long", &self.long)
5277             .field("aliases", &self.aliases)
5278             .field("short_aliases", &self.short_aliases)
5279             .field("disp_ord", &self.disp_ord)
5280             .field("possible_vals", &self.possible_vals)
5281             .field("val_names", &self.val_names)
5282             .field("num_vals", &self.num_vals)
5283             .field("max_vals", &self.max_vals)
5284             .field("min_vals", &self.min_vals)
5285             .field(
5286                 "validator",
5287                 &self.validator.as_ref().map_or("None", |_| "Some(FnMut)"),
5288             )
5289             .field(
5290                 "validator_os",
5291                 &self.validator_os.as_ref().map_or("None", |_| "Some(FnMut)"),
5292             )
5293             .field("val_delim", &self.val_delim)
5294             .field("default_vals", &self.default_vals)
5295             .field("default_vals_ifs", &self.default_vals_ifs)
5296             .field("terminator", &self.terminator)
5297             .field("index", &self.index)
5298             .field("help_heading", &self.help_heading)
5299             .field("value_hint", &self.value_hint)
5300             .field("default_missing_vals", &self.default_missing_vals);
5301 
5302         #[cfg(feature = "env")]
5303         {
5304             ds = ds.field("env", &self.env);
5305         }
5306 
5307         ds.finish()
5308     }
5309 }
5310 
5311 type Validator<'a> = dyn FnMut(&str) -> Result<(), Box<dyn Error + Send + Sync>> + Send + 'a;
5312 type ValidatorOs<'a> = dyn FnMut(&OsStr) -> Result<(), Box<dyn Error + Send + Sync>> + Send + 'a;
5313 
5314 #[derive(Debug, Clone, Eq, PartialEq)]
5315 pub(crate) enum ArgProvider {
5316     Generated,
5317     GeneratedMutated,
5318     User,
5319 }
5320 
5321 impl Default for ArgProvider {
default() -> Self5322     fn default() -> Self {
5323         ArgProvider::User
5324     }
5325 }
5326 
5327 /// Write the values such as <name1> <name2>
display_arg_val<F, T, E>(arg: &Arg, mut write: F) -> Result<(), E> where F: FnMut(&str, bool) -> Result<T, E>,5328 pub(crate) fn display_arg_val<F, T, E>(arg: &Arg, mut write: F) -> Result<(), E>
5329 where
5330     F: FnMut(&str, bool) -> Result<T, E>,
5331 {
5332     let mult_val = arg.is_multiple_values_set();
5333     let mult_occ = arg.is_multiple_occurrences_set();
5334     let delim = if arg.is_require_value_delimiter_set() {
5335         arg.val_delim.expect(INTERNAL_ERROR_MSG)
5336     } else {
5337         ' '
5338     }
5339     .to_string();
5340     if !arg.val_names.is_empty() {
5341         // If have val_name.
5342         match (arg.val_names.len(), arg.num_vals) {
5343             (1, Some(num_vals)) => {
5344                 // If single value name with multiple num_of_vals, display all
5345                 // the values with the single value name.
5346                 let arg_name = format!("<{}>", arg.val_names.get(0).unwrap());
5347                 for n in 1..=num_vals {
5348                     write(&arg_name, true)?;
5349                     if n != num_vals {
5350                         write(&delim, false)?;
5351                     }
5352                 }
5353             }
5354             (num_val_names, _) => {
5355                 // If multiple value names, display them sequentially(ignore num of vals).
5356                 let mut it = arg.val_names.iter().peekable();
5357                 while let Some(val) = it.next() {
5358                     write(&format!("<{}>", val), true)?;
5359                     if it.peek().is_some() {
5360                         write(&delim, false)?;
5361                     }
5362                 }
5363                 if (num_val_names == 1 && mult_val)
5364                     || (arg.is_positional() && mult_occ)
5365                     || num_val_names < arg.num_vals.unwrap_or(0)
5366                 {
5367                     write("...", true)?;
5368                 }
5369             }
5370         }
5371     } else if let Some(num_vals) = arg.num_vals {
5372         // If number_of_values is specified, display the value multiple times.
5373         let arg_name = format!("<{}>", arg.name);
5374         for n in 1..=num_vals {
5375             write(&arg_name, true)?;
5376             if n != num_vals {
5377                 write(&delim, false)?;
5378             }
5379         }
5380     } else if arg.is_positional() {
5381         // Value of positional argument with no num_vals and val_names.
5382         write(&format!("<{}>", arg.name), true)?;
5383 
5384         if mult_val || mult_occ {
5385             write("...", true)?;
5386         }
5387     } else {
5388         // value of flag argument with no num_vals and val_names.
5389         write(&format!("<{}>", arg.name), true)?;
5390         if mult_val {
5391             write("...", true)?;
5392         }
5393     }
5394     Ok(())
5395 }
5396 
5397 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
5398 pub(crate) enum DisplayOrder {
5399     None,
5400     Implicit(usize),
5401     Explicit(usize),
5402 }
5403 
5404 impl DisplayOrder {
set_explicit(&mut self, explicit: usize)5405     pub(crate) fn set_explicit(&mut self, explicit: usize) {
5406         *self = Self::Explicit(explicit)
5407     }
5408 
set_implicit(&mut self, implicit: usize)5409     pub(crate) fn set_implicit(&mut self, implicit: usize) {
5410         *self = (*self).max(Self::Implicit(implicit))
5411     }
5412 
make_explicit(&mut self)5413     pub(crate) fn make_explicit(&mut self) {
5414         match *self {
5415             Self::None | Self::Explicit(_) => {}
5416             Self::Implicit(disp) => self.set_explicit(disp),
5417         }
5418     }
5419 
get_explicit(self) -> usize5420     pub(crate) fn get_explicit(self) -> usize {
5421         match self {
5422             Self::None | Self::Implicit(_) => 999,
5423             Self::Explicit(disp) => disp,
5424         }
5425     }
5426 }
5427 
5428 impl Default for DisplayOrder {
default() -> Self5429     fn default() -> Self {
5430         Self::None
5431     }
5432 }
5433 
5434 // Flags
5435 #[cfg(test)]
5436 mod test {
5437     use super::Arg;
5438 
5439     #[test]
flag_display()5440     fn flag_display() {
5441         let mut f = Arg::new("flg").multiple_occurrences(true);
5442         f.long = Some("flag");
5443 
5444         assert_eq!(f.to_string(), "--flag");
5445 
5446         let mut f2 = Arg::new("flg");
5447         f2.short = Some('f');
5448 
5449         assert_eq!(f2.to_string(), "-f");
5450     }
5451 
5452     #[test]
flag_display_single_alias()5453     fn flag_display_single_alias() {
5454         let mut f = Arg::new("flg");
5455         f.long = Some("flag");
5456         f.aliases = vec![("als", true)];
5457 
5458         assert_eq!(f.to_string(), "--flag")
5459     }
5460 
5461     #[test]
flag_display_multiple_aliases()5462     fn flag_display_multiple_aliases() {
5463         let mut f = Arg::new("flg");
5464         f.short = Some('f');
5465         f.aliases = vec![
5466             ("alias_not_visible", false),
5467             ("f2", true),
5468             ("f3", true),
5469             ("f4", true),
5470         ];
5471         assert_eq!(f.to_string(), "-f");
5472     }
5473 
5474     #[test]
flag_display_single_short_alias()5475     fn flag_display_single_short_alias() {
5476         let mut f = Arg::new("flg");
5477         f.short = Some('a');
5478         f.short_aliases = vec![('b', true)];
5479 
5480         assert_eq!(f.to_string(), "-a")
5481     }
5482 
5483     #[test]
flag_display_multiple_short_aliases()5484     fn flag_display_multiple_short_aliases() {
5485         let mut f = Arg::new("flg");
5486         f.short = Some('a');
5487         f.short_aliases = vec![('b', false), ('c', true), ('d', true), ('e', true)];
5488         assert_eq!(f.to_string(), "-a");
5489     }
5490 
5491     // Options
5492 
5493     #[test]
option_display_multiple_occurrences()5494     fn option_display_multiple_occurrences() {
5495         let o = Arg::new("opt")
5496             .long("option")
5497             .takes_value(true)
5498             .multiple_occurrences(true);
5499 
5500         assert_eq!(o.to_string(), "--option <opt>");
5501     }
5502 
5503     #[test]
option_display_multiple_values()5504     fn option_display_multiple_values() {
5505         let o = Arg::new("opt")
5506             .long("option")
5507             .takes_value(true)
5508             .multiple_values(true);
5509 
5510         assert_eq!(o.to_string(), "--option <opt>...");
5511     }
5512 
5513     #[test]
option_display2()5514     fn option_display2() {
5515         let o2 = Arg::new("opt").short('o').value_names(&["file", "name"]);
5516 
5517         assert_eq!(o2.to_string(), "-o <file> <name>");
5518     }
5519 
5520     #[test]
option_display3()5521     fn option_display3() {
5522         let o2 = Arg::new("opt")
5523             .short('o')
5524             .takes_value(true)
5525             .multiple_values(true)
5526             .value_names(&["file", "name"]);
5527 
5528         assert_eq!(o2.to_string(), "-o <file> <name>");
5529     }
5530 
5531     #[test]
option_display_single_alias()5532     fn option_display_single_alias() {
5533         let o = Arg::new("opt")
5534             .takes_value(true)
5535             .long("option")
5536             .visible_alias("als");
5537 
5538         assert_eq!(o.to_string(), "--option <opt>");
5539     }
5540 
5541     #[test]
option_display_multiple_aliases()5542     fn option_display_multiple_aliases() {
5543         let o = Arg::new("opt")
5544             .long("option")
5545             .takes_value(true)
5546             .visible_aliases(&["als2", "als3", "als4"])
5547             .alias("als_not_visible");
5548 
5549         assert_eq!(o.to_string(), "--option <opt>");
5550     }
5551 
5552     #[test]
option_display_single_short_alias()5553     fn option_display_single_short_alias() {
5554         let o = Arg::new("opt")
5555             .takes_value(true)
5556             .short('a')
5557             .visible_short_alias('b');
5558 
5559         assert_eq!(o.to_string(), "-a <opt>");
5560     }
5561 
5562     #[test]
option_display_multiple_short_aliases()5563     fn option_display_multiple_short_aliases() {
5564         let o = Arg::new("opt")
5565             .short('a')
5566             .takes_value(true)
5567             .visible_short_aliases(&['b', 'c', 'd'])
5568             .short_alias('e');
5569 
5570         assert_eq!(o.to_string(), "-a <opt>");
5571     }
5572 
5573     // Positionals
5574 
5575     #[test]
positional_display_multiple_values()5576     fn positional_display_multiple_values() {
5577         let p = Arg::new("pos")
5578             .index(1)
5579             .takes_value(true)
5580             .multiple_values(true);
5581 
5582         assert_eq!(p.to_string(), "<pos>...");
5583     }
5584 
5585     #[test]
positional_display_multiple_occurrences()5586     fn positional_display_multiple_occurrences() {
5587         let p = Arg::new("pos")
5588             .index(1)
5589             .takes_value(true)
5590             .multiple_occurrences(true);
5591 
5592         assert_eq!(p.to_string(), "<pos>...");
5593     }
5594 
5595     #[test]
positional_display_required()5596     fn positional_display_required() {
5597         let p2 = Arg::new("pos").index(1).required(true);
5598 
5599         assert_eq!(p2.to_string(), "<pos>");
5600     }
5601 
5602     #[test]
positional_display_val_names()5603     fn positional_display_val_names() {
5604         let p2 = Arg::new("pos").index(1).value_names(&["file1", "file2"]);
5605 
5606         assert_eq!(p2.to_string(), "<file1> <file2>");
5607     }
5608 
5609     #[test]
positional_display_val_names_req()5610     fn positional_display_val_names_req() {
5611         let p2 = Arg::new("pos")
5612             .index(1)
5613             .required(true)
5614             .value_names(&["file1", "file2"]);
5615 
5616         assert_eq!(p2.to_string(), "<file1> <file2>");
5617     }
5618 }
5619