clap_builder/builder/
arg.rs

1// Std
2#[cfg(feature = "env")]
3use std::env;
4#[cfg(feature = "env")]
5use std::ffi::OsString;
6use std::{
7    cmp::{Ord, Ordering},
8    fmt::{self, Display, Formatter},
9    str,
10};
11
12// Internal
13use super::{ArgFlags, ArgSettings};
14#[cfg(feature = "unstable-ext")]
15use crate::builder::ext::Extension;
16use crate::builder::ext::Extensions;
17use crate::builder::ArgPredicate;
18use crate::builder::IntoResettable;
19use crate::builder::OsStr;
20use crate::builder::PossibleValue;
21use crate::builder::Str;
22use crate::builder::StyledStr;
23use crate::builder::Styles;
24use crate::builder::ValueRange;
25use crate::util::AnyValueId;
26use crate::ArgAction;
27use crate::Id;
28use crate::ValueHint;
29use crate::INTERNAL_ERROR_MSG;
30
31/// The abstract representation of a command line argument. Used to set all the options and
32/// relationships that define a valid argument for the program.
33///
34/// There are two methods for constructing [`Arg`]s, using the builder pattern and setting options
35/// manually, or using a usage string which is far less verbose but has fewer options. You can also
36/// use a combination of the two methods to achieve the best of both worlds.
37///
38/// - [Basic API][crate::Arg#basic-api]
39/// - [Value Handling][crate::Arg#value-handling]
40/// - [Help][crate::Arg#help-1]
41/// - [Advanced Argument Relations][crate::Arg#advanced-argument-relations]
42/// - [Reflection][crate::Arg#reflection]
43///
44/// # Examples
45///
46/// ```rust
47/// # use clap_builder as clap;
48/// # use clap::{Arg, arg, ArgAction};
49/// // Using the traditional builder pattern and setting each option manually
50/// let cfg = Arg::new("config")
51///       .short('c')
52///       .long("config")
53///       .action(ArgAction::Set)
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#[derive(Default, Clone)]
60pub struct Arg {
61    pub(crate) id: Id,
62    pub(crate) help: Option<StyledStr>,
63    pub(crate) long_help: Option<StyledStr>,
64    pub(crate) action: Option<ArgAction>,
65    pub(crate) value_parser: Option<super::ValueParser>,
66    pub(crate) blacklist: Vec<Id>,
67    pub(crate) settings: ArgFlags,
68    pub(crate) overrides: Vec<Id>,
69    pub(crate) groups: Vec<Id>,
70    pub(crate) requires: Vec<(ArgPredicate, Id)>,
71    pub(crate) r_ifs: Vec<(Id, OsStr)>,
72    pub(crate) r_ifs_all: Vec<(Id, OsStr)>,
73    pub(crate) r_unless: Vec<Id>,
74    pub(crate) r_unless_all: Vec<Id>,
75    pub(crate) short: Option<char>,
76    pub(crate) long: Option<Str>,
77    pub(crate) aliases: Vec<(Str, bool)>, // (name, visible)
78    pub(crate) short_aliases: Vec<(char, bool)>, // (name, visible)
79    pub(crate) disp_ord: Option<usize>,
80    pub(crate) val_names: Vec<Str>,
81    pub(crate) num_vals: Option<ValueRange>,
82    pub(crate) val_delim: Option<char>,
83    pub(crate) default_vals: Vec<OsStr>,
84    pub(crate) default_vals_ifs: Vec<(Id, ArgPredicate, Option<OsStr>)>,
85    pub(crate) default_missing_vals: Vec<OsStr>,
86    #[cfg(feature = "env")]
87    pub(crate) env: Option<(OsStr, Option<OsString>)>,
88    pub(crate) terminator: Option<Str>,
89    pub(crate) index: Option<usize>,
90    pub(crate) help_heading: Option<Option<Str>>,
91    pub(crate) ext: Extensions,
92}
93
94/// # Basic API
95impl Arg {
96    /// Create a new [`Arg`] with a unique name.
97    ///
98    /// The name is used to check whether or not the argument was used at
99    /// runtime, get values, set relationships with other args, etc..
100    ///
101    /// **NOTE:** In the case of arguments that take values (i.e. [`Arg::action(ArgAction::Set)`])
102    /// and positional arguments (i.e. those without a preceding `-` or `--`) the name will also
103    /// be displayed when the user prints the usage/help information of the program.
104    ///
105    /// # Examples
106    ///
107    /// ```rust
108    /// # use clap_builder as clap;
109    /// # use clap::{Command, Arg};
110    /// Arg::new("config")
111    /// # ;
112    /// ```
113    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
114    pub fn new(id: impl Into<Id>) -> Self {
115        Arg::default().id(id)
116    }
117
118    /// Set the identifier used for referencing this argument in the clap API.
119    ///
120    /// See [`Arg::new`] for more details.
121    #[must_use]
122    pub fn id(mut self, id: impl Into<Id>) -> Self {
123        self.id = id.into();
124        self
125    }
126
127    /// Sets the short version of the argument without the preceding `-`.
128    ///
129    /// By default `V` and `h` are used by the auto-generated `version` and `help` arguments,
130    /// respectively. You will need to disable the auto-generated flags
131    /// ([`disable_help_flag`][crate::Command::disable_help_flag],
132    /// [`disable_version_flag`][crate::Command::disable_version_flag]) and define your own.
133    ///
134    /// # Examples
135    ///
136    /// When calling `short`, use a single valid UTF-8 character which will allow using the
137    /// argument via a single hyphen (`-`) such as `-c`:
138    ///
139    /// ```rust
140    /// # use clap_builder as clap;
141    /// # use clap::{Command, Arg,  ArgAction};
142    /// let m = Command::new("prog")
143    ///     .arg(Arg::new("config")
144    ///         .short('c')
145    ///         .action(ArgAction::Set))
146    ///     .get_matches_from(vec![
147    ///         "prog", "-c", "file.toml"
148    ///     ]);
149    ///
150    /// assert_eq!(m.get_one::<String>("config").map(String::as_str), Some("file.toml"));
151    /// ```
152    ///
153    /// To use `-h` for your own flag and still have help:
154    /// ```rust
155    /// # use clap_builder as clap;
156    /// # use clap::{Command, Arg,  ArgAction};
157    /// let m = Command::new("prog")
158    ///     .disable_help_flag(true)
159    ///     .arg(Arg::new("host")
160    ///         .short('h')
161    ///         .long("host"))
162    ///     .arg(Arg::new("help")
163    ///         .long("help")
164    ///         .global(true)
165    ///         .action(ArgAction::Help))
166    ///     .get_matches_from(vec![
167    ///         "prog", "-h", "wikipedia.org"
168    ///     ]);
169    ///
170    /// assert_eq!(m.get_one::<String>("host").map(String::as_str), Some("wikipedia.org"));
171    /// ```
172    #[inline]
173    #[must_use]
174    pub fn short(mut self, s: impl IntoResettable<char>) -> Self {
175        if let Some(s) = s.into_resettable().into_option() {
176            debug_assert!(s != '-', "short option name cannot be `-`");
177            self.short = Some(s);
178        } else {
179            self.short = None;
180        }
181        self
182    }
183
184    /// Sets the long version of the argument without the preceding `--`.
185    ///
186    /// By default `version` and `help` are used by the auto-generated `version` and `help`
187    /// arguments, respectively. You may use the word `version` or `help` for the long form of your
188    /// own arguments, in which case `clap` simply will not assign those to the auto-generated
189    /// `version` or `help` arguments.
190    ///
191    /// **NOTE:** Any leading `-` characters will be stripped
192    ///
193    /// # Examples
194    ///
195    /// To set `long` use a word containing valid UTF-8. If you supply a double leading
196    /// `--` such as `--config` they will be stripped. Hyphens in the middle of the word, however,
197    /// will *not* be stripped (i.e. `config-file` is allowed).
198    ///
199    /// Setting `long` allows using the argument via a double hyphen (`--`) such as `--config`
200    ///
201    /// ```rust
202    /// # use clap_builder as clap;
203    /// # use clap::{Command, Arg, ArgAction};
204    /// let m = Command::new("prog")
205    ///     .arg(Arg::new("cfg")
206    ///         .long("config")
207    ///         .action(ArgAction::Set))
208    ///     .get_matches_from(vec![
209    ///         "prog", "--config", "file.toml"
210    ///     ]);
211    ///
212    /// assert_eq!(m.get_one::<String>("cfg").map(String::as_str), Some("file.toml"));
213    /// ```
214    #[inline]
215    #[must_use]
216    pub fn long(mut self, l: impl IntoResettable<Str>) -> Self {
217        self.long = l.into_resettable().into_option();
218        self
219    }
220
221    /// Add an alias, which functions as a hidden long flag.
222    ///
223    /// This is more efficient, and easier than creating multiple hidden arguments as one only
224    /// needs to check for the existence of this command, and not all variants.
225    ///
226    /// # Examples
227    ///
228    /// ```rust
229    /// # use clap_builder as clap;
230    /// # use clap::{Command, Arg, ArgAction};
231    /// let m = Command::new("prog")
232    ///             .arg(Arg::new("test")
233    ///             .long("test")
234    ///             .alias("alias")
235    ///             .action(ArgAction::Set))
236    ///        .get_matches_from(vec![
237    ///             "prog", "--alias", "cool"
238    ///         ]);
239    /// assert_eq!(m.get_one::<String>("test").unwrap(), "cool");
240    /// ```
241    #[must_use]
242    pub fn alias(mut self, name: impl IntoResettable<Str>) -> Self {
243        if let Some(name) = name.into_resettable().into_option() {
244            self.aliases.push((name, false));
245        } else {
246            self.aliases.clear();
247        }
248        self
249    }
250
251    /// Add an alias, which functions as a hidden short flag.
252    ///
253    /// This is more efficient, and easier than creating multiple hidden arguments as one only
254    /// needs to check for the existence of this command, and not all variants.
255    ///
256    /// # Examples
257    ///
258    /// ```rust
259    /// # use clap_builder as clap;
260    /// # use clap::{Command, Arg, ArgAction};
261    /// let m = Command::new("prog")
262    ///             .arg(Arg::new("test")
263    ///             .short('t')
264    ///             .short_alias('e')
265    ///             .action(ArgAction::Set))
266    ///        .get_matches_from(vec![
267    ///             "prog", "-e", "cool"
268    ///         ]);
269    /// assert_eq!(m.get_one::<String>("test").unwrap(), "cool");
270    /// ```
271    #[must_use]
272    pub fn short_alias(mut self, name: impl IntoResettable<char>) -> Self {
273        if let Some(name) = name.into_resettable().into_option() {
274            debug_assert!(name != '-', "short alias name cannot be `-`");
275            self.short_aliases.push((name, false));
276        } else {
277            self.short_aliases.clear();
278        }
279        self
280    }
281
282    /// Add aliases, which function as hidden long flags.
283    ///
284    /// This is more efficient, and easier than creating multiple hidden subcommands as one only
285    /// needs to check for the existence of this command, and not all variants.
286    ///
287    /// # Examples
288    ///
289    /// ```rust
290    /// # use clap_builder as clap;
291    /// # use clap::{Command, Arg, ArgAction};
292    /// let m = Command::new("prog")
293    ///             .arg(Arg::new("test")
294    ///                     .long("test")
295    ///                     .aliases(["do-stuff", "do-tests", "tests"])
296    ///                     .action(ArgAction::SetTrue)
297    ///                     .help("the file to add")
298    ///                     .required(false))
299    ///             .get_matches_from(vec![
300    ///                 "prog", "--do-tests"
301    ///             ]);
302    /// assert_eq!(m.get_flag("test"), true);
303    /// ```
304    #[must_use]
305    pub fn aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
306        self.aliases
307            .extend(names.into_iter().map(|x| (x.into(), 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_builder as clap;
320    /// # use clap::{Command, Arg, ArgAction};
321    /// let m = Command::new("prog")
322    ///             .arg(Arg::new("test")
323    ///                     .short('t')
324    ///                     .short_aliases(['e', 's'])
325    ///                     .action(ArgAction::SetTrue)
326    ///                     .help("the file to add")
327    ///                     .required(false))
328    ///             .get_matches_from(vec![
329    ///                 "prog", "-s"
330    ///             ]);
331    /// assert_eq!(m.get_flag("test"), true);
332    /// ```
333    #[must_use]
334    pub fn short_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
335        for s in names {
336            debug_assert!(s != '-', "short alias name cannot be `-`");
337            self.short_aliases.push((s, false));
338        }
339        self
340    }
341
342    /// Add an alias, which functions as a visible long flag.
343    ///
344    /// Like [`Arg::alias`], except that they are visible inside the help message.
345    ///
346    /// # Examples
347    ///
348    /// ```rust
349    /// # use clap_builder as clap;
350    /// # use clap::{Command, Arg, ArgAction};
351    /// let m = Command::new("prog")
352    ///             .arg(Arg::new("test")
353    ///                 .visible_alias("something-awesome")
354    ///                 .long("test")
355    ///                 .action(ArgAction::Set))
356    ///        .get_matches_from(vec![
357    ///             "prog", "--something-awesome", "coffee"
358    ///         ]);
359    /// assert_eq!(m.get_one::<String>("test").unwrap(), "coffee");
360    /// ```
361    /// [`Command::alias`]: Arg::alias()
362    #[must_use]
363    pub fn visible_alias(mut self, name: impl IntoResettable<Str>) -> Self {
364        if let Some(name) = name.into_resettable().into_option() {
365            self.aliases.push((name, true));
366        } else {
367            self.aliases.clear();
368        }
369        self
370    }
371
372    /// Add an alias, which functions as a visible short flag.
373    ///
374    /// Like [`Arg::short_alias`], except that they are visible inside the help message.
375    ///
376    /// # Examples
377    ///
378    /// ```rust
379    /// # use clap_builder as clap;
380    /// # use clap::{Command, Arg, ArgAction};
381    /// let m = Command::new("prog")
382    ///             .arg(Arg::new("test")
383    ///                 .long("test")
384    ///                 .visible_short_alias('t')
385    ///                 .action(ArgAction::Set))
386    ///        .get_matches_from(vec![
387    ///             "prog", "-t", "coffee"
388    ///         ]);
389    /// assert_eq!(m.get_one::<String>("test").unwrap(), "coffee");
390    /// ```
391    #[must_use]
392    pub fn visible_short_alias(mut self, name: impl IntoResettable<char>) -> Self {
393        if let Some(name) = name.into_resettable().into_option() {
394            debug_assert!(name != '-', "short alias name cannot be `-`");
395            self.short_aliases.push((name, true));
396        } else {
397            self.short_aliases.clear();
398        }
399        self
400    }
401
402    /// Add aliases, which function as visible long flags.
403    ///
404    /// Like [`Arg::aliases`], except that they are visible inside the help message.
405    ///
406    /// # Examples
407    ///
408    /// ```rust
409    /// # use clap_builder as clap;
410    /// # use clap::{Command, Arg, ArgAction};
411    /// let m = Command::new("prog")
412    ///             .arg(Arg::new("test")
413    ///                 .long("test")
414    ///                 .action(ArgAction::SetTrue)
415    ///                 .visible_aliases(["something", "awesome", "cool"]))
416    ///        .get_matches_from(vec![
417    ///             "prog", "--awesome"
418    ///         ]);
419    /// assert_eq!(m.get_flag("test"), true);
420    /// ```
421    /// [`Command::aliases`]: Arg::aliases()
422    #[must_use]
423    pub fn visible_aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
424        self.aliases
425            .extend(names.into_iter().map(|n| (n.into(), true)));
426        self
427    }
428
429    /// Add aliases, which function as visible short flags.
430    ///
431    /// Like [`Arg::short_aliases`], except that they are visible inside the help message.
432    ///
433    /// # Examples
434    ///
435    /// ```rust
436    /// # use clap_builder as clap;
437    /// # use clap::{Command, Arg, ArgAction};
438    /// let m = Command::new("prog")
439    ///             .arg(Arg::new("test")
440    ///                 .long("test")
441    ///                 .action(ArgAction::SetTrue)
442    ///                 .visible_short_aliases(['t', 'e']))
443    ///        .get_matches_from(vec![
444    ///             "prog", "-t"
445    ///         ]);
446    /// assert_eq!(m.get_flag("test"), true);
447    /// ```
448    #[must_use]
449    pub fn visible_short_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
450        for n in names {
451            debug_assert!(n != '-', "short alias name cannot be `-`");
452            self.short_aliases.push((n, true));
453        }
454        self
455    }
456
457    /// Specifies the index of a positional argument **starting at** 1.
458    ///
459    /// **NOTE:** The index refers to position according to **other positional argument**. It does
460    /// not define position in the argument list as a whole.
461    ///
462    /// **NOTE:** You can optionally leave off the `index` method, and the index will be
463    /// assigned in order of evaluation. Utilizing the `index` method allows for setting
464    /// indexes out of order
465    ///
466    /// **NOTE:** This is only meant to be used for positional arguments and shouldn't to be used
467    /// with [`Arg::short`] or [`Arg::long`].
468    ///
469    /// **NOTE:** When utilized with [`Arg::num_args(1..)`], only the **last** positional argument
470    /// may be defined as having a variable number of arguments (i.e. with the highest index)
471    ///
472    /// # Panics
473    ///
474    /// [`Command`] will [`panic!`] if indexes are skipped (such as defining `index(1)` and `index(3)`
475    /// but not `index(2)`, or a positional argument is defined as multiple and is not the highest
476    /// index (debug builds)
477    ///
478    /// # Examples
479    ///
480    /// ```rust
481    /// # use clap_builder as clap;
482    /// # use clap::{Command, Arg};
483    /// Arg::new("config")
484    ///     .index(1)
485    /// # ;
486    /// ```
487    ///
488    /// ```rust
489    /// # use clap_builder as clap;
490    /// # use clap::{Command, Arg, ArgAction};
491    /// let m = Command::new("prog")
492    ///     .arg(Arg::new("mode")
493    ///         .index(1))
494    ///     .arg(Arg::new("debug")
495    ///         .long("debug")
496    ///         .action(ArgAction::SetTrue))
497    ///     .get_matches_from(vec![
498    ///         "prog", "--debug", "fast"
499    ///     ]);
500    ///
501    /// assert!(m.contains_id("mode"));
502    /// assert_eq!(m.get_one::<String>("mode").unwrap(), "fast"); // notice index(1) means "first positional"
503    ///                                                           // *not* first argument
504    /// ```
505    /// [`Arg::short`]: Arg::short()
506    /// [`Arg::long`]: Arg::long()
507    /// [`Arg::num_args(true)`]: Arg::num_args()
508    /// [`Command`]: crate::Command
509    #[inline]
510    #[must_use]
511    pub fn index(mut self, idx: impl IntoResettable<usize>) -> Self {
512        self.index = idx.into_resettable().into_option();
513        self
514    }
515
516    /// This is a "var arg" and everything that follows should be captured by it, as if the user had
517    /// used a `--`.
518    ///
519    /// **NOTE:** To start the trailing "var arg" on unknown flags (and not just a positional
520    /// value), set [`allow_hyphen_values`][Arg::allow_hyphen_values].  Either way, users still
521    /// have the option to explicitly escape ambiguous arguments with `--`.
522    ///
523    /// **NOTE:** [`Arg::value_delimiter`] still applies if set.
524    ///
525    /// **NOTE:** Setting this requires [`Arg::num_args(..)`].
526    ///
527    /// # Examples
528    ///
529    /// ```rust
530    /// # use clap_builder as clap;
531    /// # use clap::{Command, arg};
532    /// let m = Command::new("myprog")
533    ///     .arg(arg!(<cmd> ... "commands to run").trailing_var_arg(true))
534    ///     .get_matches_from(vec!["myprog", "arg1", "-r", "val1"]);
535    ///
536    /// let trail: Vec<_> = m.get_many::<String>("cmd").unwrap().collect();
537    /// assert_eq!(trail, ["arg1", "-r", "val1"]);
538    /// ```
539    /// [`Arg::num_args(..)`]: crate::Arg::num_args()
540    pub fn trailing_var_arg(self, yes: bool) -> Self {
541        if yes {
542            self.setting(ArgSettings::TrailingVarArg)
543        } else {
544            self.unset_setting(ArgSettings::TrailingVarArg)
545        }
546    }
547
548    /// This arg is the last, or final, positional argument (i.e. has the highest
549    /// index) and is *only* able to be accessed via the `--` syntax (i.e. `$ prog args --
550    /// last_arg`).
551    ///
552    /// Even, if no other arguments are left to parse, if the user omits the `--` syntax
553    /// they will receive an [`UnknownArgument`] error. Setting an argument to `.last(true)` also
554    /// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
555    /// the `--` syntax is otherwise not possible.
556    ///
557    /// **NOTE:** This will change the usage string to look like `$ prog [OPTIONS] [-- <ARG>]` if
558    /// `ARG` is marked as `.last(true)`.
559    ///
560    /// **NOTE:** This setting will imply [`crate::Command::dont_collapse_args_in_usage`] because failing
561    /// to set this can make the usage string very confusing.
562    ///
563    /// **NOTE**: This setting only applies to positional arguments, and has no effect on OPTIONS
564    ///
565    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
566    ///
567    /// **CAUTION:** Using this setting *and* having child subcommands is not
568    /// recommended with the exception of *also* using
569    /// [`crate::Command::args_conflicts_with_subcommands`]
570    /// (or [`crate::Command::subcommand_negates_reqs`] if the argument marked `Last` is also
571    /// marked [`Arg::required`])
572    ///
573    /// # Examples
574    ///
575    /// ```rust
576    /// # use clap_builder as clap;
577    /// # use clap::{Arg, ArgAction};
578    /// Arg::new("args")
579    ///     .action(ArgAction::Set)
580    ///     .last(true)
581    /// # ;
582    /// ```
583    ///
584    /// Setting `last` ensures the arg has the highest [index] of all positional args
585    /// and requires that the `--` syntax be used to access it early.
586    ///
587    /// ```rust
588    /// # use clap_builder as clap;
589    /// # use clap::{Command, Arg, ArgAction};
590    /// let res = Command::new("prog")
591    ///     .arg(Arg::new("first"))
592    ///     .arg(Arg::new("second"))
593    ///     .arg(Arg::new("third")
594    ///         .action(ArgAction::Set)
595    ///         .last(true))
596    ///     .try_get_matches_from(vec![
597    ///         "prog", "one", "--", "three"
598    ///     ]);
599    ///
600    /// assert!(res.is_ok());
601    /// let m = res.unwrap();
602    /// assert_eq!(m.get_one::<String>("third").unwrap(), "three");
603    /// assert_eq!(m.get_one::<String>("second"), None);
604    /// ```
605    ///
606    /// Even if the positional argument marked `Last` is the only argument left to parse,
607    /// failing to use the `--` syntax results in an error.
608    ///
609    /// ```rust
610    /// # use clap_builder as clap;
611    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
612    /// let res = Command::new("prog")
613    ///     .arg(Arg::new("first"))
614    ///     .arg(Arg::new("second"))
615    ///     .arg(Arg::new("third")
616    ///         .action(ArgAction::Set)
617    ///         .last(true))
618    ///     .try_get_matches_from(vec![
619    ///         "prog", "one", "two", "three"
620    ///     ]);
621    ///
622    /// assert!(res.is_err());
623    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
624    /// ```
625    /// [index]: Arg::index()
626    /// [`UnknownArgument`]: crate::error::ErrorKind::UnknownArgument
627    #[inline]
628    #[must_use]
629    pub fn last(self, yes: bool) -> Self {
630        if yes {
631            self.setting(ArgSettings::Last)
632        } else {
633            self.unset_setting(ArgSettings::Last)
634        }
635    }
636
637    /// Specifies that the argument must be present.
638    ///
639    /// Required by default means it is required, when no other conflicting rules or overrides have
640    /// been evaluated. Conflicting rules take precedence over being required.
641    ///
642    /// **Pro tip:** Flags (i.e. not positional, or arguments that take values) shouldn't be
643    /// required by default. This is because if a flag were to be required, it should simply be
644    /// implied. No additional information is required from user. Flags by their very nature are
645    /// simply boolean on/off switches. The only time a user *should* be required to use a flag
646    /// is if the operation is destructive in nature, and the user is essentially proving to you,
647    /// "Yes, I know what I'm doing."
648    ///
649    /// # Examples
650    ///
651    /// ```rust
652    /// # use clap_builder as clap;
653    /// # use clap::Arg;
654    /// Arg::new("config")
655    ///     .required(true)
656    /// # ;
657    /// ```
658    ///
659    /// Setting required requires that the argument be used at runtime.
660    ///
661    /// ```rust
662    /// # use clap_builder as clap;
663    /// # use clap::{Command, Arg, ArgAction};
664    /// let res = Command::new("prog")
665    ///     .arg(Arg::new("cfg")
666    ///         .required(true)
667    ///         .action(ArgAction::Set)
668    ///         .long("config"))
669    ///     .try_get_matches_from(vec![
670    ///         "prog", "--config", "file.conf",
671    ///     ]);
672    ///
673    /// assert!(res.is_ok());
674    /// ```
675    ///
676    /// Setting required and then *not* supplying that argument at runtime is an error.
677    ///
678    /// ```rust
679    /// # use clap_builder as clap;
680    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
681    /// let res = Command::new("prog")
682    ///     .arg(Arg::new("cfg")
683    ///         .required(true)
684    ///         .action(ArgAction::Set)
685    ///         .long("config"))
686    ///     .try_get_matches_from(vec![
687    ///         "prog"
688    ///     ]);
689    ///
690    /// assert!(res.is_err());
691    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
692    /// ```
693    #[inline]
694    #[must_use]
695    pub fn required(self, yes: bool) -> Self {
696        if yes {
697            self.setting(ArgSettings::Required)
698        } else {
699            self.unset_setting(ArgSettings::Required)
700        }
701    }
702
703    /// Sets an argument that is required when this one is present
704    ///
705    /// i.e. when using this argument, the following argument *must* be present.
706    ///
707    /// **NOTE:** [Conflicting] rules and [override] rules take precedence over being required
708    ///
709    /// # Examples
710    ///
711    /// ```rust
712    /// # use clap_builder as clap;
713    /// # use clap::Arg;
714    /// Arg::new("config")
715    ///     .requires("input")
716    /// # ;
717    /// ```
718    ///
719    /// Setting [`Arg::requires(name)`] requires that the argument be used at runtime if the
720    /// defining argument is used. If the defining argument isn't used, the other argument isn't
721    /// required
722    ///
723    /// ```rust
724    /// # use clap_builder as clap;
725    /// # use clap::{Command, Arg, ArgAction};
726    /// let res = Command::new("prog")
727    ///     .arg(Arg::new("cfg")
728    ///         .action(ArgAction::Set)
729    ///         .requires("input")
730    ///         .long("config"))
731    ///     .arg(Arg::new("input"))
732    ///     .try_get_matches_from(vec![
733    ///         "prog"
734    ///     ]);
735    ///
736    /// assert!(res.is_ok()); // We didn't use cfg, so input wasn't required
737    /// ```
738    ///
739    /// Setting [`Arg::requires(name)`] and *not* supplying that argument is an error.
740    ///
741    /// ```rust
742    /// # use clap_builder as clap;
743    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
744    /// let res = Command::new("prog")
745    ///     .arg(Arg::new("cfg")
746    ///         .action(ArgAction::Set)
747    ///         .requires("input")
748    ///         .long("config"))
749    ///     .arg(Arg::new("input"))
750    ///     .try_get_matches_from(vec![
751    ///         "prog", "--config", "file.conf"
752    ///     ]);
753    ///
754    /// assert!(res.is_err());
755    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
756    /// ```
757    /// [`Arg::requires(name)`]: Arg::requires()
758    /// [Conflicting]: Arg::conflicts_with()
759    /// [override]: Arg::overrides_with()
760    #[must_use]
761    pub fn requires(mut self, arg_id: impl IntoResettable<Id>) -> Self {
762        if let Some(arg_id) = arg_id.into_resettable().into_option() {
763            self.requires.push((ArgPredicate::IsPresent, arg_id));
764        } else {
765            self.requires.clear();
766        }
767        self
768    }
769
770    /// This argument must be passed alone; it conflicts with all other arguments.
771    ///
772    /// # Examples
773    ///
774    /// ```rust
775    /// # use clap_builder as clap;
776    /// # use clap::Arg;
777    /// Arg::new("config")
778    ///     .exclusive(true)
779    /// # ;
780    /// ```
781    ///
782    /// Setting an exclusive argument and having any other arguments present at runtime
783    /// is an error.
784    ///
785    /// ```rust
786    /// # use clap_builder as clap;
787    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
788    /// let res = Command::new("prog")
789    ///     .arg(Arg::new("exclusive")
790    ///         .action(ArgAction::Set)
791    ///         .exclusive(true)
792    ///         .long("exclusive"))
793    ///     .arg(Arg::new("debug")
794    ///         .long("debug"))
795    ///     .arg(Arg::new("input"))
796    ///     .try_get_matches_from(vec![
797    ///         "prog", "--exclusive", "file.conf", "file.txt"
798    ///     ]);
799    ///
800    /// assert!(res.is_err());
801    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict);
802    /// ```
803    #[inline]
804    #[must_use]
805    pub fn exclusive(self, yes: bool) -> Self {
806        if yes {
807            self.setting(ArgSettings::Exclusive)
808        } else {
809            self.unset_setting(ArgSettings::Exclusive)
810        }
811    }
812
813    /// Specifies that an argument can be matched to all child [`Subcommand`]s.
814    ///
815    /// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however
816    /// their values once a user uses them will be propagated back up to parents. In effect, this
817    /// means one should *define* all global arguments at the top level, however it doesn't matter
818    /// where the user *uses* the global argument.
819    ///
820    /// # Examples
821    ///
822    /// Assume an application with two subcommands, and you'd like to define a
823    /// `--verbose` flag that can be called on any of the subcommands and parent, but you don't
824    /// want to clutter the source with three duplicate [`Arg`] definitions.
825    ///
826    /// ```rust
827    /// # use clap_builder as clap;
828    /// # use clap::{Command, Arg, ArgAction};
829    /// let m = Command::new("prog")
830    ///     .arg(Arg::new("verb")
831    ///         .long("verbose")
832    ///         .short('v')
833    ///         .action(ArgAction::SetTrue)
834    ///         .global(true))
835    ///     .subcommand(Command::new("test"))
836    ///     .subcommand(Command::new("do-stuff"))
837    ///     .get_matches_from(vec![
838    ///         "prog", "do-stuff", "--verbose"
839    ///     ]);
840    ///
841    /// assert_eq!(m.subcommand_name(), Some("do-stuff"));
842    /// let sub_m = m.subcommand_matches("do-stuff").unwrap();
843    /// assert_eq!(sub_m.get_flag("verb"), true);
844    /// ```
845    ///
846    /// [`Subcommand`]: crate::Subcommand
847    #[inline]
848    #[must_use]
849    pub fn global(self, yes: bool) -> Self {
850        if yes {
851            self.setting(ArgSettings::Global)
852        } else {
853            self.unset_setting(ArgSettings::Global)
854        }
855    }
856
857    #[inline]
858    pub(crate) fn is_set(&self, s: ArgSettings) -> bool {
859        self.settings.is_set(s)
860    }
861
862    #[inline]
863    #[must_use]
864    pub(crate) fn setting(mut self, setting: ArgSettings) -> Self {
865        self.settings.set(setting);
866        self
867    }
868
869    #[inline]
870    #[must_use]
871    pub(crate) fn unset_setting(mut self, setting: ArgSettings) -> Self {
872        self.settings.unset(setting);
873        self
874    }
875
876    /// Extend [`Arg`] with [`ArgExt`] data
877    #[cfg(feature = "unstable-ext")]
878    #[allow(clippy::should_implement_trait)]
879    pub fn add<T: ArgExt + Extension>(mut self, tagged: T) -> Self {
880        self.ext.set(tagged);
881        self
882    }
883}
884
885/// # Value Handling
886impl Arg {
887    /// Specify how to react to an argument when parsing it.
888    ///
889    /// [`ArgAction`] controls things like
890    /// - Overwriting previous values with new ones
891    /// - Appending new values to all previous ones
892    /// - Counting how many times a flag occurs
893    ///
894    /// The default action is `ArgAction::Set`
895    ///
896    /// # Examples
897    ///
898    /// ```rust
899    /// # use clap_builder as clap;
900    /// # use clap::Command;
901    /// # use clap::Arg;
902    /// let cmd = Command::new("mycmd")
903    ///     .arg(
904    ///         Arg::new("flag")
905    ///             .long("flag")
906    ///             .action(clap::ArgAction::Append)
907    ///     );
908    ///
909    /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "value"]).unwrap();
910    /// assert!(matches.contains_id("flag"));
911    /// assert_eq!(
912    ///     matches.get_many::<String>("flag").unwrap_or_default().map(|v| v.as_str()).collect::<Vec<_>>(),
913    ///     vec!["value"]
914    /// );
915    /// ```
916    #[inline]
917    #[must_use]
918    pub fn action(mut self, action: impl IntoResettable<ArgAction>) -> Self {
919        self.action = action.into_resettable().into_option();
920        self
921    }
922
923    /// Specify the typed behavior of the argument.
924    ///
925    /// This allows parsing and validating a value before storing it into
926    /// [`ArgMatches`][crate::ArgMatches] as the given type.
927    ///
928    /// Possible value parsers include:
929    /// - [`value_parser!(T)`][crate::value_parser!] for auto-selecting a value parser for a given type
930    ///   - Or [range expressions like `0..=1`][std::ops::RangeBounds] as a shorthand for [`RangedI64ValueParser`][crate::builder::RangedI64ValueParser]
931    /// - `Fn(&str) -> Result<T, E>`
932    /// - `[&str]` and [`PossibleValuesParser`][crate::builder::PossibleValuesParser] for static enumerated values
933    /// - [`BoolishValueParser`][crate::builder::BoolishValueParser], and [`FalseyValueParser`][crate::builder::FalseyValueParser] for alternative `bool` implementations
934    /// - [`NonEmptyStringValueParser`][crate::builder::NonEmptyStringValueParser] for basic validation for strings
935    /// - or any other [`TypedValueParser`][crate::builder::TypedValueParser] implementation
936    ///
937    /// The default value is [`ValueParser::string`][crate::builder::ValueParser::string].
938    ///
939    /// ```rust
940    /// # use clap_builder as clap;
941    /// # use clap::ArgAction;
942    /// let mut cmd = clap::Command::new("raw")
943    ///     .arg(
944    ///         clap::Arg::new("color")
945    ///             .long("color")
946    ///             .value_parser(["always", "auto", "never"])
947    ///             .default_value("auto")
948    ///     )
949    ///     .arg(
950    ///         clap::Arg::new("hostname")
951    ///             .long("hostname")
952    ///             .value_parser(clap::builder::NonEmptyStringValueParser::new())
953    ///             .action(ArgAction::Set)
954    ///             .required(true)
955    ///     )
956    ///     .arg(
957    ///         clap::Arg::new("port")
958    ///             .long("port")
959    ///             .value_parser(clap::value_parser!(u16).range(3000..))
960    ///             .action(ArgAction::Set)
961    ///             .required(true)
962    ///     );
963    ///
964    /// let m = cmd.try_get_matches_from_mut(
965    ///     ["cmd", "--hostname", "rust-lang.org", "--port", "3001"]
966    /// ).unwrap();
967    ///
968    /// let color: &String = m.get_one("color")
969    ///     .expect("default");
970    /// assert_eq!(color, "auto");
971    ///
972    /// let hostname: &String = m.get_one("hostname")
973    ///     .expect("required");
974    /// assert_eq!(hostname, "rust-lang.org");
975    ///
976    /// let port: u16 = *m.get_one("port")
977    ///     .expect("required");
978    /// assert_eq!(port, 3001);
979    /// ```
980    pub fn value_parser(mut self, parser: impl IntoResettable<super::ValueParser>) -> Self {
981        self.value_parser = parser.into_resettable().into_option();
982        self
983    }
984
985    /// Specifies the number of arguments parsed per occurrence
986    ///
987    /// For example, if you had a `-f <file>` argument where you wanted exactly 3 'files' you would
988    /// set `.num_args(3)`, and this argument wouldn't be satisfied unless the user
989    /// provided 3 and only 3 values.
990    ///
991    /// Users may specify values for arguments in any of the following methods
992    ///
993    /// - Using a space such as `-o value` or `--option value`
994    /// - Using an equals and no space such as `-o=value` or `--option=value`
995    /// - Use a short and no space such as `-ovalue`
996    ///
997    /// **WARNING:**
998    ///
999    /// Setting a variable number of values (e.g. `1..=10`) for an argument without
1000    /// other details can be dangerous in some circumstances. Because multiple values are
1001    /// allowed, `--option val1 val2 val3` is perfectly valid. Be careful when designing a CLI
1002    /// where **positional arguments** or **subcommands** are *also* expected as `clap` will continue
1003    /// parsing *values* until one of the following happens:
1004    ///
1005    /// - It reaches the maximum number of values
1006    /// - It reaches a specific number of values
1007    /// - It finds another flag or option (i.e. something that starts with a `-`)
1008    /// - It reaches the [`Arg::value_terminator`] if set
1009    ///
1010    /// Alternatively,
1011    /// - Use a delimiter between values with [`Arg::value_delimiter`]
1012    /// - Require a flag occurrence per value with [`ArgAction::Append`]
1013    /// - Require positional arguments to appear after `--` with [`Arg::last`]
1014    ///
1015    /// # Examples
1016    ///
1017    /// Option:
1018    /// ```rust
1019    /// # use clap_builder as clap;
1020    /// # use clap::{Command, Arg};
1021    /// let m = Command::new("prog")
1022    ///     .arg(Arg::new("mode")
1023    ///         .long("mode")
1024    ///         .num_args(1))
1025    ///     .get_matches_from(vec![
1026    ///         "prog", "--mode", "fast"
1027    ///     ]);
1028    ///
1029    /// assert_eq!(m.get_one::<String>("mode").unwrap(), "fast");
1030    /// ```
1031    ///
1032    /// Flag/option hybrid (see also [`default_missing_value`][Arg::default_missing_value])
1033    /// ```rust
1034    /// # use clap_builder as clap;
1035    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
1036    /// let cmd = Command::new("prog")
1037    ///     .arg(Arg::new("mode")
1038    ///         .long("mode")
1039    ///         .default_missing_value("slow")
1040    ///         .default_value("plaid")
1041    ///         .num_args(0..=1));
1042    ///
1043    /// let m = cmd.clone()
1044    ///     .get_matches_from(vec![
1045    ///         "prog", "--mode", "fast"
1046    ///     ]);
1047    /// assert_eq!(m.get_one::<String>("mode").unwrap(), "fast");
1048    ///
1049    /// let m = cmd.clone()
1050    ///     .get_matches_from(vec![
1051    ///         "prog", "--mode",
1052    ///     ]);
1053    /// assert_eq!(m.get_one::<String>("mode").unwrap(), "slow");
1054    ///
1055    /// let m = cmd.clone()
1056    ///     .get_matches_from(vec![
1057    ///         "prog",
1058    ///     ]);
1059    /// assert_eq!(m.get_one::<String>("mode").unwrap(), "plaid");
1060    /// ```
1061    ///
1062    /// Tuples
1063    /// ```rust
1064    /// # use clap_builder as clap;
1065    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
1066    /// let cmd = Command::new("prog")
1067    ///     .arg(Arg::new("file")
1068    ///         .action(ArgAction::Set)
1069    ///         .num_args(2)
1070    ///         .short('F'));
1071    ///
1072    /// let m = cmd.clone()
1073    ///     .get_matches_from(vec![
1074    ///         "prog", "-F", "in-file", "out-file"
1075    ///     ]);
1076    /// assert_eq!(
1077    ///     m.get_many::<String>("file").unwrap_or_default().map(|v| v.as_str()).collect::<Vec<_>>(),
1078    ///     vec!["in-file", "out-file"]
1079    /// );
1080    ///
1081    /// let res = cmd.clone()
1082    ///     .try_get_matches_from(vec![
1083    ///         "prog", "-F", "file1"
1084    ///     ]);
1085    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::WrongNumberOfValues);
1086    /// ```
1087    ///
1088    /// A common mistake is to define an option which allows multiple values and a positional
1089    /// argument.
1090    /// ```rust
1091    /// # use clap_builder as clap;
1092    /// # use clap::{Command, Arg, ArgAction};
1093    /// let cmd = Command::new("prog")
1094    ///     .arg(Arg::new("file")
1095    ///         .action(ArgAction::Set)
1096    ///         .num_args(0..)
1097    ///         .short('F'))
1098    ///     .arg(Arg::new("word"));
1099    ///
1100    /// let m = cmd.clone().get_matches_from(vec![
1101    ///     "prog", "-F", "file1", "file2", "file3", "word"
1102    /// ]);
1103    /// let files: Vec<_> = m.get_many::<String>("file").unwrap().collect();
1104    /// assert_eq!(files, ["file1", "file2", "file3", "word"]); // wait...what?!
1105    /// assert!(!m.contains_id("word")); // but we clearly used word!
1106    ///
1107    /// // but this works
1108    /// let m = cmd.clone().get_matches_from(vec![
1109    ///     "prog", "word", "-F", "file1", "file2", "file3",
1110    /// ]);
1111    /// let files: Vec<_> = m.get_many::<String>("file").unwrap().collect();
1112    /// assert_eq!(files, ["file1", "file2", "file3"]);
1113    /// assert_eq!(m.get_one::<String>("word").unwrap(), "word");
1114    /// ```
1115    /// The problem is `clap` doesn't know when to stop parsing values for "file".
1116    ///
1117    /// A solution for the example above is to limit how many values with a maximum, or specific
1118    /// number, or to say [`ArgAction::Append`] is ok, but multiple values are not.
1119    /// ```rust
1120    /// # use clap_builder as clap;
1121    /// # use clap::{Command, Arg, ArgAction};
1122    /// let m = Command::new("prog")
1123    ///     .arg(Arg::new("file")
1124    ///         .action(ArgAction::Append)
1125    ///         .short('F'))
1126    ///     .arg(Arg::new("word"))
1127    ///     .get_matches_from(vec![
1128    ///         "prog", "-F", "file1", "-F", "file2", "-F", "file3", "word"
1129    ///     ]);
1130    ///
1131    /// let files: Vec<_> = m.get_many::<String>("file").unwrap().collect();
1132    /// assert_eq!(files, ["file1", "file2", "file3"]);
1133    /// assert_eq!(m.get_one::<String>("word").unwrap(), "word");
1134    /// ```
1135    #[inline]
1136    #[must_use]
1137    pub fn num_args(mut self, qty: impl IntoResettable<ValueRange>) -> Self {
1138        self.num_vals = qty.into_resettable().into_option();
1139        self
1140    }
1141
1142    #[doc(hidden)]
1143    #[cfg_attr(
1144        feature = "deprecated",
1145        deprecated(since = "4.0.0", note = "Replaced with `Arg::num_args`")
1146    )]
1147    pub fn number_of_values(self, qty: usize) -> Self {
1148        self.num_args(qty)
1149    }
1150
1151    /// Placeholder for the argument's value in the help message / usage.
1152    ///
1153    /// This name is cosmetic only; the name is **not** used to access arguments.
1154    /// This setting can be very helpful when describing the type of input the user should be
1155    /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to
1156    /// use all capital letters for the value name.
1157    ///
1158    /// **NOTE:** implicitly sets [`Arg::action(ArgAction::Set)`]
1159    ///
1160    /// # Examples
1161    ///
1162    /// ```rust
1163    /// # use clap_builder as clap;
1164    /// # use clap::{Command, Arg};
1165    /// Arg::new("cfg")
1166    ///     .long("config")
1167    ///     .value_name("FILE")
1168    /// # ;
1169    /// ```
1170    ///
1171    /// ```rust
1172    /// # use clap_builder as clap;
1173    /// # #[cfg(feature = "help")] {
1174    /// # use clap::{Command, Arg};
1175    /// let m = Command::new("prog")
1176    ///     .arg(Arg::new("config")
1177    ///         .long("config")
1178    ///         .value_name("FILE")
1179    ///         .help("Some help text"))
1180    ///     .get_matches_from(vec![
1181    ///         "prog", "--help"
1182    ///     ]);
1183    /// # }
1184    /// ```
1185    /// Running the above program produces the following output
1186    ///
1187    /// ```text
1188    /// valnames
1189    ///
1190    /// Usage: valnames [OPTIONS]
1191    ///
1192    /// Options:
1193    ///     --config <FILE>     Some help text
1194    ///     -h, --help          Print help information
1195    ///     -V, --version       Print version information
1196    /// ```
1197    /// [positional]: Arg::index()
1198    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
1199    #[inline]
1200    #[must_use]
1201    pub fn value_name(mut self, name: impl IntoResettable<Str>) -> Self {
1202        if let Some(name) = name.into_resettable().into_option() {
1203            self.value_names([name])
1204        } else {
1205            self.val_names.clear();
1206            self
1207        }
1208    }
1209
1210    /// Placeholders for the argument's values in the help message / usage.
1211    ///
1212    /// These names are cosmetic only, used for help and usage strings only. The names are **not**
1213    /// used to access arguments. The values of the arguments are accessed in numeric order (i.e.
1214    /// if you specify two names `one` and `two` `one` will be the first matched value, `two` will
1215    /// be the second).
1216    ///
1217    /// This setting can be very helpful when describing the type of input the user should be
1218    /// using, such as `FILE`, `INTERFACE`, etc. Although not required, it's somewhat convention to
1219    /// use all capital letters for the value name.
1220    ///
1221    /// **Pro Tip:** It may help to use [`Arg::next_line_help(true)`] if there are long, or
1222    /// multiple value names in order to not throw off the help text alignment of all options.
1223    ///
1224    /// **NOTE:** implicitly sets [`Arg::action(ArgAction::Set)`] and [`Arg::num_args(1..)`].
1225    ///
1226    /// # Examples
1227    ///
1228    /// ```rust
1229    /// # use clap_builder as clap;
1230    /// # use clap::{Command, Arg};
1231    /// Arg::new("speed")
1232    ///     .short('s')
1233    ///     .value_names(["fast", "slow"]);
1234    /// ```
1235    ///
1236    /// ```rust
1237    /// # use clap_builder as clap;
1238    /// # #[cfg(feature = "help")] {
1239    /// # use clap::{Command, Arg};
1240    /// let m = Command::new("prog")
1241    ///     .arg(Arg::new("io")
1242    ///         .long("io-files")
1243    ///         .value_names(["INFILE", "OUTFILE"]))
1244    ///     .get_matches_from(vec![
1245    ///         "prog", "--help"
1246    ///     ]);
1247    /// # }
1248    /// ```
1249    ///
1250    /// Running the above program produces the following output
1251    ///
1252    /// ```text
1253    /// valnames
1254    ///
1255    /// Usage: valnames [OPTIONS]
1256    ///
1257    /// Options:
1258    ///     -h, --help                       Print help information
1259    ///     --io-files <INFILE> <OUTFILE>    Some help text
1260    ///     -V, --version                    Print version information
1261    /// ```
1262    /// [`Arg::next_line_help(true)`]: Arg::next_line_help()
1263    /// [`Arg::num_args`]: Arg::num_args()
1264    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
1265    /// [`Arg::num_args(1..)`]: Arg::num_args()
1266    #[must_use]
1267    pub fn value_names(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
1268        self.val_names = names.into_iter().map(|s| s.into()).collect();
1269        self
1270    }
1271
1272    /// Provide the shell a hint about how to complete this argument.
1273    ///
1274    /// See [`ValueHint`] for more information.
1275    ///
1276    /// **NOTE:** implicitly sets [`Arg::action(ArgAction::Set)`].
1277    ///
1278    /// For example, to take a username as argument:
1279    ///
1280    /// ```rust
1281    /// # use clap_builder as clap;
1282    /// # use clap::{Arg, ValueHint};
1283    /// Arg::new("user")
1284    ///     .short('u')
1285    ///     .long("user")
1286    ///     .value_hint(ValueHint::Username);
1287    /// ```
1288    ///
1289    /// To take a full command line and its arguments (for example, when writing a command wrapper):
1290    ///
1291    /// ```rust
1292    /// # use clap_builder as clap;
1293    /// # use clap::{Command, Arg, ValueHint, ArgAction};
1294    /// Command::new("prog")
1295    ///     .trailing_var_arg(true)
1296    ///     .arg(
1297    ///         Arg::new("command")
1298    ///             .action(ArgAction::Set)
1299    ///             .num_args(1..)
1300    ///             .value_hint(ValueHint::CommandWithArguments)
1301    ///     );
1302    /// ```
1303    #[must_use]
1304    pub fn value_hint(mut self, value_hint: impl IntoResettable<ValueHint>) -> Self {
1305        // HACK: we should use `Self::add` and `Self::remove` to type-check that `ArgExt` is used
1306        match value_hint.into_resettable().into_option() {
1307            Some(value_hint) => {
1308                self.ext.set(value_hint);
1309            }
1310            None => {
1311                self.ext.remove::<ValueHint>();
1312            }
1313        }
1314        self
1315    }
1316
1317    /// Match values against [`PossibleValuesParser`][crate::builder::PossibleValuesParser] without matching case.
1318    ///
1319    /// When other arguments are conditionally required based on the
1320    /// value of a case-insensitive argument, the equality check done
1321    /// by [`Arg::required_if_eq`], [`Arg::required_if_eq_any`], or
1322    /// [`Arg::required_if_eq_all`] is case-insensitive.
1323    ///
1324    ///
1325    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
1326    ///
1327    /// **NOTE:** To do unicode case folding, enable the `unicode` feature flag.
1328    ///
1329    /// # Examples
1330    ///
1331    /// ```rust
1332    /// # use clap_builder as clap;
1333    /// # use clap::{Command, Arg, ArgAction};
1334    /// let m = Command::new("pv")
1335    ///     .arg(Arg::new("option")
1336    ///         .long("option")
1337    ///         .action(ArgAction::Set)
1338    ///         .ignore_case(true)
1339    ///         .value_parser(["test123"]))
1340    ///     .get_matches_from(vec![
1341    ///         "pv", "--option", "TeSt123",
1342    ///     ]);
1343    ///
1344    /// assert!(m.get_one::<String>("option").unwrap().eq_ignore_ascii_case("test123"));
1345    /// ```
1346    ///
1347    /// This setting also works when multiple values can be defined:
1348    ///
1349    /// ```rust
1350    /// # use clap_builder as clap;
1351    /// # use clap::{Command, Arg, ArgAction};
1352    /// let m = Command::new("pv")
1353    ///     .arg(Arg::new("option")
1354    ///         .short('o')
1355    ///         .long("option")
1356    ///         .action(ArgAction::Set)
1357    ///         .ignore_case(true)
1358    ///         .num_args(1..)
1359    ///         .value_parser(["test123", "test321"]))
1360    ///     .get_matches_from(vec![
1361    ///         "pv", "--option", "TeSt123", "teST123", "tESt321"
1362    ///     ]);
1363    ///
1364    /// let matched_vals = m.get_many::<String>("option").unwrap().collect::<Vec<_>>();
1365    /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
1366    /// ```
1367    #[inline]
1368    #[must_use]
1369    pub fn ignore_case(self, yes: bool) -> Self {
1370        if yes {
1371            self.setting(ArgSettings::IgnoreCase)
1372        } else {
1373            self.unset_setting(ArgSettings::IgnoreCase)
1374        }
1375    }
1376
1377    /// Allows values which start with a leading hyphen (`-`)
1378    ///
1379    /// To limit values to just numbers, see
1380    /// [`allow_negative_numbers`][Arg::allow_negative_numbers].
1381    ///
1382    /// See also [`trailing_var_arg`][Arg::trailing_var_arg].
1383    ///
1384    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
1385    ///
1386    /// **WARNING:** Prior arguments with `allow_hyphen_values(true)` get precedence over known
1387    /// flags but known flags get precedence over the next possible positional argument with
1388    /// `allow_hyphen_values(true)`.  When combined with [`Arg::num_args(..)`],
1389    /// [`Arg::value_terminator`] is one way to ensure processing stops.
1390    ///
1391    /// **WARNING**: Take caution when using this setting combined with another argument using
1392    /// [`Arg::num_args`], as this becomes ambiguous `$ prog --arg -- -- val`. All
1393    /// three `--, --, val` will be values when the user may have thought the second `--` would
1394    /// constitute the normal, "Only positional args follow" idiom.
1395    ///
1396    /// # Examples
1397    ///
1398    /// ```rust
1399    /// # use clap_builder as clap;
1400    /// # use clap::{Command, Arg, ArgAction};
1401    /// let m = Command::new("prog")
1402    ///     .arg(Arg::new("pat")
1403    ///         .action(ArgAction::Set)
1404    ///         .allow_hyphen_values(true)
1405    ///         .long("pattern"))
1406    ///     .get_matches_from(vec![
1407    ///         "prog", "--pattern", "-file"
1408    ///     ]);
1409    ///
1410    /// assert_eq!(m.get_one::<String>("pat").unwrap(), "-file");
1411    /// ```
1412    ///
1413    /// Not setting `Arg::allow_hyphen_values(true)` and supplying a value which starts with a
1414    /// hyphen is an error.
1415    ///
1416    /// ```rust
1417    /// # use clap_builder as clap;
1418    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
1419    /// let res = Command::new("prog")
1420    ///     .arg(Arg::new("pat")
1421    ///         .action(ArgAction::Set)
1422    ///         .long("pattern"))
1423    ///     .try_get_matches_from(vec![
1424    ///         "prog", "--pattern", "-file"
1425    ///     ]);
1426    ///
1427    /// assert!(res.is_err());
1428    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::UnknownArgument);
1429    /// ```
1430    /// [`Arg::num_args(1)`]: Arg::num_args()
1431    #[inline]
1432    #[must_use]
1433    pub fn allow_hyphen_values(self, yes: bool) -> Self {
1434        if yes {
1435            self.setting(ArgSettings::AllowHyphenValues)
1436        } else {
1437            self.unset_setting(ArgSettings::AllowHyphenValues)
1438        }
1439    }
1440
1441    /// Allows negative numbers to pass as values.
1442    ///
1443    /// This is similar to [`Arg::allow_hyphen_values`] except that it only allows numbers,
1444    /// all other undefined leading hyphens will fail to parse.
1445    ///
1446    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
1447    ///
1448    /// # Examples
1449    ///
1450    /// ```rust
1451    /// # use clap_builder as clap;
1452    /// # use clap::{Command, Arg};
1453    /// let res = Command::new("myprog")
1454    ///     .arg(Arg::new("num").allow_negative_numbers(true))
1455    ///     .try_get_matches_from(vec![
1456    ///         "myprog", "-20"
1457    ///     ]);
1458    /// assert!(res.is_ok());
1459    /// let m = res.unwrap();
1460    /// assert_eq!(m.get_one::<String>("num").unwrap(), "-20");
1461    /// ```
1462    #[inline]
1463    pub fn allow_negative_numbers(self, yes: bool) -> Self {
1464        if yes {
1465            self.setting(ArgSettings::AllowNegativeNumbers)
1466        } else {
1467            self.unset_setting(ArgSettings::AllowNegativeNumbers)
1468        }
1469    }
1470
1471    /// Requires that options use the `--option=val` syntax
1472    ///
1473    /// i.e. an equals between the option and associated value.
1474    ///
1475    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
1476    ///
1477    /// # Examples
1478    ///
1479    /// Setting `require_equals` requires that the option have an equals sign between
1480    /// it and the associated value.
1481    ///
1482    /// ```rust
1483    /// # use clap_builder as clap;
1484    /// # use clap::{Command, Arg, ArgAction};
1485    /// let res = Command::new("prog")
1486    ///     .arg(Arg::new("cfg")
1487    ///         .action(ArgAction::Set)
1488    ///         .require_equals(true)
1489    ///         .long("config"))
1490    ///     .try_get_matches_from(vec![
1491    ///         "prog", "--config=file.conf"
1492    ///     ]);
1493    ///
1494    /// assert!(res.is_ok());
1495    /// ```
1496    ///
1497    /// Setting `require_equals` and *not* supplying the equals will cause an
1498    /// error.
1499    ///
1500    /// ```rust
1501    /// # use clap_builder as clap;
1502    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
1503    /// let res = Command::new("prog")
1504    ///     .arg(Arg::new("cfg")
1505    ///         .action(ArgAction::Set)
1506    ///         .require_equals(true)
1507    ///         .long("config"))
1508    ///     .try_get_matches_from(vec![
1509    ///         "prog", "--config", "file.conf"
1510    ///     ]);
1511    ///
1512    /// assert!(res.is_err());
1513    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::NoEquals);
1514    /// ```
1515    #[inline]
1516    #[must_use]
1517    pub fn require_equals(self, yes: bool) -> Self {
1518        if yes {
1519            self.setting(ArgSettings::RequireEquals)
1520        } else {
1521            self.unset_setting(ArgSettings::RequireEquals)
1522        }
1523    }
1524
1525    #[doc(hidden)]
1526    #[cfg_attr(
1527        feature = "deprecated",
1528        deprecated(since = "4.0.0", note = "Replaced with `Arg::value_delimiter`")
1529    )]
1530    pub fn use_value_delimiter(mut self, yes: bool) -> Self {
1531        if yes {
1532            self.val_delim.get_or_insert(',');
1533        } else {
1534            self.val_delim = None;
1535        }
1536        self
1537    }
1538
1539    /// Allow grouping of multiple values via a delimiter.
1540    ///
1541    /// i.e. allow values (`val1,val2,val3`) to be parsed as three values (`val1`, `val2`,
1542    /// and `val3`) instead of one value (`val1,val2,val3`).
1543    ///
1544    /// # Examples
1545    ///
1546    /// ```rust
1547    /// # use clap_builder as clap;
1548    /// # use clap::{Command, Arg};
1549    /// let m = Command::new("prog")
1550    ///     .arg(Arg::new("config")
1551    ///         .short('c')
1552    ///         .long("config")
1553    ///         .value_delimiter(','))
1554    ///     .get_matches_from(vec![
1555    ///         "prog", "--config=val1,val2,val3"
1556    ///     ]);
1557    ///
1558    /// assert_eq!(m.get_many::<String>("config").unwrap().collect::<Vec<_>>(), ["val1", "val2", "val3"])
1559    /// ```
1560    /// [`Arg::value_delimiter(',')`]: Arg::value_delimiter()
1561    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
1562    #[inline]
1563    #[must_use]
1564    pub fn value_delimiter(mut self, d: impl IntoResettable<char>) -> Self {
1565        self.val_delim = d.into_resettable().into_option();
1566        self
1567    }
1568
1569    /// Sentinel to **stop** parsing multiple values of a given argument.
1570    ///
1571    /// By default when
1572    /// one sets [`num_args(1..)`] on an argument, clap will continue parsing values for that
1573    /// argument until it reaches another valid argument, or one of the other more specific settings
1574    /// for multiple values is used (such as [`num_args`]).
1575    ///
1576    /// **NOTE:** This setting only applies to [options] and [positional arguments]
1577    ///
1578    /// **NOTE:** When the terminator is passed in on the command line, it is **not** stored as one
1579    /// of the values
1580    ///
1581    /// # Examples
1582    ///
1583    /// ```rust
1584    /// # use clap_builder as clap;
1585    /// # use clap::{Command, Arg, ArgAction};
1586    /// Arg::new("vals")
1587    ///     .action(ArgAction::Set)
1588    ///     .num_args(1..)
1589    ///     .value_terminator(";")
1590    /// # ;
1591    /// ```
1592    ///
1593    /// The following example uses two arguments, a sequence of commands, and the location in which
1594    /// to perform them
1595    ///
1596    /// ```rust
1597    /// # use clap_builder as clap;
1598    /// # use clap::{Command, Arg, ArgAction};
1599    /// let m = Command::new("prog")
1600    ///     .arg(Arg::new("cmds")
1601    ///         .action(ArgAction::Set)
1602    ///         .num_args(1..)
1603    ///         .allow_hyphen_values(true)
1604    ///         .value_terminator(";"))
1605    ///     .arg(Arg::new("location"))
1606    ///     .get_matches_from(vec![
1607    ///         "prog", "find", "-type", "f", "-name", "special", ";", "/home/clap"
1608    ///     ]);
1609    /// let cmds: Vec<_> = m.get_many::<String>("cmds").unwrap().collect();
1610    /// assert_eq!(&cmds, &["find", "-type", "f", "-name", "special"]);
1611    /// assert_eq!(m.get_one::<String>("location").unwrap(), "/home/clap");
1612    /// ```
1613    /// [options]: Arg::action
1614    /// [positional arguments]: Arg::index()
1615    /// [`num_args(1..)`]: Arg::num_args()
1616    /// [`num_args`]: Arg::num_args()
1617    #[inline]
1618    #[must_use]
1619    pub fn value_terminator(mut self, term: impl IntoResettable<Str>) -> Self {
1620        self.terminator = term.into_resettable().into_option();
1621        self
1622    }
1623
1624    /// Consume all following arguments.
1625    ///
1626    /// Do not parse them individually, but rather pass them in entirety.
1627    ///
1628    /// It is worth noting that setting this requires all values to come after a `--` to indicate
1629    /// they should all be captured. For example:
1630    ///
1631    /// ```text
1632    /// --foo something -- -v -v -v -b -b -b --baz -q -u -x
1633    /// ```
1634    ///
1635    /// Will result in everything after `--` to be considered one raw argument. This behavior
1636    /// may not be exactly what you are expecting and using [`Arg::trailing_var_arg`]
1637    /// may be more appropriate.
1638    ///
1639    /// **NOTE:** Implicitly sets [`Arg::action(ArgAction::Set)`] [`Arg::num_args(1..)`],
1640    /// [`Arg::allow_hyphen_values(true)`], and [`Arg::last(true)`] when set to `true`.
1641    ///
1642    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
1643    /// [`Arg::num_args(1..)`]: Arg::num_args()
1644    /// [`Arg::allow_hyphen_values(true)`]: Arg::allow_hyphen_values()
1645    /// [`Arg::last(true)`]: Arg::last()
1646    #[inline]
1647    #[must_use]
1648    pub fn raw(mut self, yes: bool) -> Self {
1649        if yes {
1650            self.num_vals.get_or_insert_with(|| (1..).into());
1651        }
1652        self.allow_hyphen_values(yes).last(yes)
1653    }
1654
1655    /// Value for the argument when not present.
1656    ///
1657    /// **NOTE:** If the user *does not* use this argument at runtime [`ArgMatches::contains_id`] will
1658    /// still return `true`. If you wish to determine whether the argument was used at runtime or
1659    /// not, consider [`ArgMatches::value_source`][crate::ArgMatches::value_source].
1660    ///
1661    /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value_if`] but slightly
1662    /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg
1663    /// at runtime. `Arg::default_value_if` however only takes effect when the user has not provided
1664    /// a value at runtime **and** these other conditions are met as well. If you have set
1665    /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide this arg
1666    /// at runtime, nor were the conditions met for `Arg::default_value_if`, the `Arg::default_value`
1667    /// will be applied.
1668    ///
1669    /// Like with command-line values, this will be split by [`Arg::value_delimiter`].
1670    ///
1671    /// # Examples
1672    ///
1673    /// First we use the default value without providing any value at runtime.
1674    ///
1675    /// ```rust
1676    /// # use clap_builder as clap;
1677    /// # use clap::{Command, Arg, parser::ValueSource};
1678    /// let m = Command::new("prog")
1679    ///     .arg(Arg::new("opt")
1680    ///         .long("myopt")
1681    ///         .default_value("myval"))
1682    ///     .get_matches_from(vec![
1683    ///         "prog"
1684    ///     ]);
1685    ///
1686    /// assert_eq!(m.get_one::<String>("opt").unwrap(), "myval");
1687    /// assert!(m.contains_id("opt"));
1688    /// assert_eq!(m.value_source("opt"), Some(ValueSource::DefaultValue));
1689    /// ```
1690    ///
1691    /// Next we provide a value at runtime to override the default.
1692    ///
1693    /// ```rust
1694    /// # use clap_builder as clap;
1695    /// # use clap::{Command, Arg, parser::ValueSource};
1696    /// let m = Command::new("prog")
1697    ///     .arg(Arg::new("opt")
1698    ///         .long("myopt")
1699    ///         .default_value("myval"))
1700    ///     .get_matches_from(vec![
1701    ///         "prog", "--myopt=non_default"
1702    ///     ]);
1703    ///
1704    /// assert_eq!(m.get_one::<String>("opt").unwrap(), "non_default");
1705    /// assert!(m.contains_id("opt"));
1706    /// assert_eq!(m.value_source("opt"), Some(ValueSource::CommandLine));
1707    /// ```
1708    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
1709    /// [`ArgMatches::contains_id`]: crate::ArgMatches::contains_id()
1710    /// [`Arg::default_value_if`]: Arg::default_value_if()
1711    #[inline]
1712    #[must_use]
1713    pub fn default_value(mut self, val: impl IntoResettable<OsStr>) -> Self {
1714        if let Some(val) = val.into_resettable().into_option() {
1715            self.default_values([val])
1716        } else {
1717            self.default_vals.clear();
1718            self
1719        }
1720    }
1721
1722    #[inline]
1723    #[must_use]
1724    #[doc(hidden)]
1725    #[cfg_attr(
1726        feature = "deprecated",
1727        deprecated(since = "4.0.0", note = "Replaced with `Arg::default_value`")
1728    )]
1729    pub fn default_value_os(self, val: impl Into<OsStr>) -> Self {
1730        self.default_values([val])
1731    }
1732
1733    /// Value for the argument when not present.
1734    ///
1735    /// See [`Arg::default_value`].
1736    ///
1737    /// [`Arg::default_value`]: Arg::default_value()
1738    #[inline]
1739    #[must_use]
1740    pub fn default_values(mut self, vals: impl IntoIterator<Item = impl Into<OsStr>>) -> Self {
1741        self.default_vals = vals.into_iter().map(|s| s.into()).collect();
1742        self
1743    }
1744
1745    #[inline]
1746    #[must_use]
1747    #[doc(hidden)]
1748    #[cfg_attr(
1749        feature = "deprecated",
1750        deprecated(since = "4.0.0", note = "Replaced with `Arg::default_values`")
1751    )]
1752    pub fn default_values_os(self, vals: impl IntoIterator<Item = impl Into<OsStr>>) -> Self {
1753        self.default_values(vals)
1754    }
1755
1756    /// Value for the argument when the flag is present but no value is specified.
1757    ///
1758    /// This configuration option is often used to give the user a shortcut and allow them to
1759    /// efficiently specify an option argument without requiring an explicitly value. The `--color`
1760    /// argument is a common example. By supplying a default, such as `default_missing_value("always")`,
1761    /// the user can quickly just add `--color` to the command line to produce the desired color output.
1762    ///
1763    /// **NOTE:** using this configuration option requires the use of the
1764    /// [`.num_args(0..N)`][Arg::num_args] and the
1765    /// [`.require_equals(true)`][Arg::require_equals] configuration option. These are required in
1766    /// order to unambiguously determine what, if any, value was supplied for the argument.
1767    ///
1768    /// Like with command-line values, this will be split by [`Arg::value_delimiter`].
1769    ///
1770    /// # Examples
1771    ///
1772    /// For POSIX style `--color`:
1773    /// ```rust
1774    /// # use clap_builder as clap;
1775    /// # use clap::{Command, Arg, parser::ValueSource};
1776    /// fn cli() -> Command {
1777    ///     Command::new("prog")
1778    ///         .arg(Arg::new("color").long("color")
1779    ///             .value_name("WHEN")
1780    ///             .value_parser(["always", "auto", "never"])
1781    ///             .default_value("auto")
1782    ///             .num_args(0..=1)
1783    ///             .require_equals(true)
1784    ///             .default_missing_value("always")
1785    ///             .help("Specify WHEN to colorize output.")
1786    ///         )
1787    /// }
1788    ///
1789    /// // first, we'll provide no arguments
1790    /// let m  = cli().get_matches_from(vec![
1791    ///         "prog"
1792    ///     ]);
1793    /// assert_eq!(m.get_one::<String>("color").unwrap(), "auto");
1794    /// assert_eq!(m.value_source("color"), Some(ValueSource::DefaultValue));
1795    ///
1796    /// // next, we'll provide a runtime value to override the default (as usually done).
1797    /// let m  = cli().get_matches_from(vec![
1798    ///         "prog", "--color=never"
1799    ///     ]);
1800    /// assert_eq!(m.get_one::<String>("color").unwrap(), "never");
1801    /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine));
1802    ///
1803    /// // finally, we will use the shortcut and only provide the argument without a value.
1804    /// let m  = cli().get_matches_from(vec![
1805    ///         "prog", "--color"
1806    ///     ]);
1807    /// assert_eq!(m.get_one::<String>("color").unwrap(), "always");
1808    /// assert_eq!(m.value_source("color"), Some(ValueSource::CommandLine));
1809    /// ```
1810    ///
1811    /// For bool literals:
1812    /// ```rust
1813    /// # use clap_builder as clap;
1814    /// # use clap::{Command, Arg, parser::ValueSource, value_parser};
1815    /// fn cli() -> Command {
1816    ///     Command::new("prog")
1817    ///         .arg(Arg::new("create").long("create")
1818    ///             .value_name("BOOL")
1819    ///             .value_parser(value_parser!(bool))
1820    ///             .num_args(0..=1)
1821    ///             .require_equals(true)
1822    ///             .default_missing_value("true")
1823    ///         )
1824    /// }
1825    ///
1826    /// // first, we'll provide no arguments
1827    /// let m  = cli().get_matches_from(vec![
1828    ///         "prog"
1829    ///     ]);
1830    /// assert_eq!(m.get_one::<bool>("create").copied(), None);
1831    ///
1832    /// // next, we'll provide a runtime value to override the default (as usually done).
1833    /// let m  = cli().get_matches_from(vec![
1834    ///         "prog", "--create=false"
1835    ///     ]);
1836    /// assert_eq!(m.get_one::<bool>("create").copied(), Some(false));
1837    /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine));
1838    ///
1839    /// // finally, we will use the shortcut and only provide the argument without a value.
1840    /// let m  = cli().get_matches_from(vec![
1841    ///         "prog", "--create"
1842    ///     ]);
1843    /// assert_eq!(m.get_one::<bool>("create").copied(), Some(true));
1844    /// assert_eq!(m.value_source("create"), Some(ValueSource::CommandLine));
1845    /// ```
1846    ///
1847    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
1848    /// [`Arg::default_value`]: Arg::default_value()
1849    #[inline]
1850    #[must_use]
1851    pub fn default_missing_value(mut self, val: impl IntoResettable<OsStr>) -> Self {
1852        if let Some(val) = val.into_resettable().into_option() {
1853            self.default_missing_values_os([val])
1854        } else {
1855            self.default_missing_vals.clear();
1856            self
1857        }
1858    }
1859
1860    /// Value for the argument when the flag is present but no value is specified.
1861    ///
1862    /// See [`Arg::default_missing_value`].
1863    ///
1864    /// [`Arg::default_missing_value`]: Arg::default_missing_value()
1865    /// [`OsStr`]: std::ffi::OsStr
1866    #[inline]
1867    #[must_use]
1868    pub fn default_missing_value_os(self, val: impl Into<OsStr>) -> Self {
1869        self.default_missing_values_os([val])
1870    }
1871
1872    /// Value for the argument when the flag is present but no value is specified.
1873    ///
1874    /// See [`Arg::default_missing_value`].
1875    ///
1876    /// [`Arg::default_missing_value`]: Arg::default_missing_value()
1877    #[inline]
1878    #[must_use]
1879    pub fn default_missing_values(self, vals: impl IntoIterator<Item = impl Into<OsStr>>) -> Self {
1880        self.default_missing_values_os(vals)
1881    }
1882
1883    /// Value for the argument when the flag is present but no value is specified.
1884    ///
1885    /// See [`Arg::default_missing_values`].
1886    ///
1887    /// [`Arg::default_missing_values`]: Arg::default_missing_values()
1888    /// [`OsStr`]: std::ffi::OsStr
1889    #[inline]
1890    #[must_use]
1891    pub fn default_missing_values_os(
1892        mut self,
1893        vals: impl IntoIterator<Item = impl Into<OsStr>>,
1894    ) -> Self {
1895        self.default_missing_vals = vals.into_iter().map(|s| s.into()).collect();
1896        self
1897    }
1898
1899    /// Read from `name` environment variable when argument is not present.
1900    ///
1901    /// If it is not present in the environment, then default
1902    /// rules will apply.
1903    ///
1904    /// If user sets the argument in the environment:
1905    /// - When [`Arg::action(ArgAction::Set)`] is not set, the flag is considered raised.
1906    /// - When [`Arg::action(ArgAction::Set)`] is set,
1907    ///   [`ArgMatches::get_one`][crate::ArgMatches::get_one] will
1908    ///   return value of the environment variable.
1909    ///
1910    /// If user doesn't set the argument in the environment:
1911    /// - When [`Arg::action(ArgAction::Set)`] is not set, the flag is considered off.
1912    /// - When [`Arg::action(ArgAction::Set)`] is set,
1913    ///   [`ArgMatches::get_one`][crate::ArgMatches::get_one] will
1914    ///   return the default specified.
1915    ///
1916    /// Like with command-line values, this will be split by [`Arg::value_delimiter`].
1917    ///
1918    /// # Examples
1919    ///
1920    /// In this example, we show the variable coming from the environment:
1921    ///
1922    /// ```rust
1923    /// # use clap_builder as clap;
1924    /// # use std::env;
1925    /// # use clap::{Command, Arg, ArgAction};
1926    ///
1927    /// env::set_var("MY_FLAG", "env");
1928    ///
1929    /// let m = Command::new("prog")
1930    ///     .arg(Arg::new("flag")
1931    ///         .long("flag")
1932    ///         .env("MY_FLAG")
1933    ///         .action(ArgAction::Set))
1934    ///     .get_matches_from(vec![
1935    ///         "prog"
1936    ///     ]);
1937    ///
1938    /// assert_eq!(m.get_one::<String>("flag").unwrap(), "env");
1939    /// ```
1940    ///
1941    /// In this example, because `prog` is a flag that accepts an optional, case-insensitive
1942    /// boolean literal.
1943    ///
1944    /// Note that the value parser controls how flags are parsed.  In this case we've selected
1945    /// [`FalseyValueParser`][crate::builder::FalseyValueParser].  A `false` literal is `n`, `no`,
1946    /// `f`, `false`, `off` or `0`.  An absent environment variable will also be considered as
1947    /// `false`.  Anything else will considered as `true`.
1948    ///
1949    /// ```rust
1950    /// # use clap_builder as clap;
1951    /// # use std::env;
1952    /// # use clap::{Command, Arg, ArgAction};
1953    /// # use clap::builder::FalseyValueParser;
1954    ///
1955    /// env::set_var("TRUE_FLAG", "true");
1956    /// env::set_var("FALSE_FLAG", "0");
1957    ///
1958    /// let m = Command::new("prog")
1959    ///     .arg(Arg::new("true_flag")
1960    ///         .long("true_flag")
1961    ///         .action(ArgAction::SetTrue)
1962    ///         .value_parser(FalseyValueParser::new())
1963    ///         .env("TRUE_FLAG"))
1964    ///     .arg(Arg::new("false_flag")
1965    ///         .long("false_flag")
1966    ///         .action(ArgAction::SetTrue)
1967    ///         .value_parser(FalseyValueParser::new())
1968    ///         .env("FALSE_FLAG"))
1969    ///     .arg(Arg::new("absent_flag")
1970    ///         .long("absent_flag")
1971    ///         .action(ArgAction::SetTrue)
1972    ///         .value_parser(FalseyValueParser::new())
1973    ///         .env("ABSENT_FLAG"))
1974    ///     .get_matches_from(vec![
1975    ///         "prog"
1976    ///     ]);
1977    ///
1978    /// assert!(m.get_flag("true_flag"));
1979    /// assert!(!m.get_flag("false_flag"));
1980    /// assert!(!m.get_flag("absent_flag"));
1981    /// ```
1982    ///
1983    /// In this example, we show the variable coming from an option on the CLI:
1984    ///
1985    /// ```rust
1986    /// # use clap_builder as clap;
1987    /// # use std::env;
1988    /// # use clap::{Command, Arg, ArgAction};
1989    ///
1990    /// env::set_var("MY_FLAG", "env");
1991    ///
1992    /// let m = Command::new("prog")
1993    ///     .arg(Arg::new("flag")
1994    ///         .long("flag")
1995    ///         .env("MY_FLAG")
1996    ///         .action(ArgAction::Set))
1997    ///     .get_matches_from(vec![
1998    ///         "prog", "--flag", "opt"
1999    ///     ]);
2000    ///
2001    /// assert_eq!(m.get_one::<String>("flag").unwrap(), "opt");
2002    /// ```
2003    ///
2004    /// In this example, we show the variable coming from the environment even with the
2005    /// presence of a default:
2006    ///
2007    /// ```rust
2008    /// # use clap_builder as clap;
2009    /// # use std::env;
2010    /// # use clap::{Command, Arg, ArgAction};
2011    ///
2012    /// env::set_var("MY_FLAG", "env");
2013    ///
2014    /// let m = Command::new("prog")
2015    ///     .arg(Arg::new("flag")
2016    ///         .long("flag")
2017    ///         .env("MY_FLAG")
2018    ///         .action(ArgAction::Set)
2019    ///         .default_value("default"))
2020    ///     .get_matches_from(vec![
2021    ///         "prog"
2022    ///     ]);
2023    ///
2024    /// assert_eq!(m.get_one::<String>("flag").unwrap(), "env");
2025    /// ```
2026    ///
2027    /// In this example, we show the use of multiple values in a single environment variable:
2028    ///
2029    /// ```rust
2030    /// # use clap_builder as clap;
2031    /// # use std::env;
2032    /// # use clap::{Command, Arg, ArgAction};
2033    ///
2034    /// env::set_var("MY_FLAG_MULTI", "env1,env2");
2035    ///
2036    /// let m = Command::new("prog")
2037    ///     .arg(Arg::new("flag")
2038    ///         .long("flag")
2039    ///         .env("MY_FLAG_MULTI")
2040    ///         .action(ArgAction::Set)
2041    ///         .num_args(1..)
2042    ///         .value_delimiter(','))
2043    ///     .get_matches_from(vec![
2044    ///         "prog"
2045    ///     ]);
2046    ///
2047    /// assert_eq!(m.get_many::<String>("flag").unwrap().collect::<Vec<_>>(), vec!["env1", "env2"]);
2048    /// ```
2049    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
2050    /// [`Arg::value_delimiter(',')`]: Arg::value_delimiter()
2051    #[cfg(feature = "env")]
2052    #[inline]
2053    #[must_use]
2054    pub fn env(mut self, name: impl IntoResettable<OsStr>) -> Self {
2055        if let Some(name) = name.into_resettable().into_option() {
2056            let value = env::var_os(&name);
2057            self.env = Some((name, value));
2058        } else {
2059            self.env = None;
2060        }
2061        self
2062    }
2063
2064    #[cfg(feature = "env")]
2065    #[doc(hidden)]
2066    #[cfg_attr(
2067        feature = "deprecated",
2068        deprecated(since = "4.0.0", note = "Replaced with `Arg::env`")
2069    )]
2070    pub fn env_os(self, name: impl Into<OsStr>) -> Self {
2071        self.env(name)
2072    }
2073}
2074
2075/// # Help
2076impl Arg {
2077    /// Sets the description of the argument for short help (`-h`).
2078    ///
2079    /// Typically, this is a short (one line) description of the arg.
2080    ///
2081    /// If [`Arg::long_help`] is not specified, this message will be displayed for `--help`.
2082    ///
2083    /// **NOTE:** Only `Arg::help` is used in completion script generation in order to be concise
2084    ///
2085    /// # Examples
2086    ///
2087    /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
2088    /// include a newline in the help text and have the following text be properly aligned with all
2089    /// the other help text.
2090    ///
2091    /// Setting `help` displays a short message to the side of the argument when the user passes
2092    /// `-h` or `--help` (by default).
2093    ///
2094    /// ```rust
2095    /// # #[cfg(feature = "help")] {
2096    /// # use clap_builder as clap;
2097    /// # use clap::{Command, Arg};
2098    /// let m = Command::new("prog")
2099    ///     .arg(Arg::new("cfg")
2100    ///         .long("config")
2101    ///         .help("Some help text describing the --config arg"))
2102    ///     .get_matches_from(vec![
2103    ///         "prog", "--help"
2104    ///     ]);
2105    /// # }
2106    /// ```
2107    ///
2108    /// The above example displays
2109    ///
2110    /// ```notrust
2111    /// helptest
2112    ///
2113    /// Usage: helptest [OPTIONS]
2114    ///
2115    /// Options:
2116    ///     --config     Some help text describing the --config arg
2117    /// -h, --help       Print help information
2118    /// -V, --version    Print version information
2119    /// ```
2120    /// [`Arg::long_help`]: Arg::long_help()
2121    #[inline]
2122    #[must_use]
2123    pub fn help(mut self, h: impl IntoResettable<StyledStr>) -> Self {
2124        self.help = h.into_resettable().into_option();
2125        self
2126    }
2127
2128    /// Sets the description of the argument for long help (`--help`).
2129    ///
2130    /// Typically this a more detailed (multi-line) message
2131    /// that describes the arg.
2132    ///
2133    /// If [`Arg::help`] is not specified, this message will be displayed for `-h`.
2134    ///
2135    /// **NOTE:** Only [`Arg::help`] is used in completion script generation in order to be concise
2136    ///
2137    /// # Examples
2138    ///
2139    /// Any valid UTF-8 is allowed in the help text. The one exception is when one wishes to
2140    /// include a newline in the help text and have the following text be properly aligned with all
2141    /// the other help text.
2142    ///
2143    /// Setting `help` displays a short message to the side of the argument when the user passes
2144    /// `-h` or `--help` (by default).
2145    ///
2146    /// ```rust
2147    /// # #[cfg(feature = "help")] {
2148    /// # use clap_builder as clap;
2149    /// # use clap::{Command, Arg};
2150    /// let m = Command::new("prog")
2151    ///     .arg(Arg::new("cfg")
2152    ///         .long("config")
2153    ///         .long_help(
2154    /// "The config file used by the myprog must be in JSON format
2155    /// with only valid keys and may not contain other nonsense
2156    /// that cannot be read by this program. Obviously I'm going on
2157    /// and on, so I'll stop now."))
2158    ///     .get_matches_from(vec![
2159    ///         "prog", "--help"
2160    ///     ]);
2161    /// # }
2162    /// ```
2163    ///
2164    /// The above example displays
2165    ///
2166    /// ```text
2167    /// prog
2168    ///
2169    /// Usage: prog [OPTIONS]
2170    ///
2171    /// Options:
2172    ///         --config
2173    ///             The config file used by the myprog must be in JSON format
2174    ///             with only valid keys and may not contain other nonsense
2175    ///             that cannot be read by this program. Obviously I'm going on
2176    ///             and on, so I'll stop now.
2177    ///
2178    ///     -h, --help
2179    ///             Print help information
2180    ///
2181    ///     -V, --version
2182    ///             Print version information
2183    /// ```
2184    /// [`Arg::help`]: Arg::help()
2185    #[inline]
2186    #[must_use]
2187    pub fn long_help(mut self, h: impl IntoResettable<StyledStr>) -> Self {
2188        self.long_help = h.into_resettable().into_option();
2189        self
2190    }
2191
2192    /// Allows custom ordering of args within the help message.
2193    ///
2194    /// `Arg`s with a lower value will be displayed first in the help message.
2195    /// Those with the same display order will be sorted.
2196    ///
2197    /// `Arg`s are automatically assigned a display order based on the order they are added to the
2198    /// [`Command`][crate::Command].
2199    /// Overriding this is helpful when the order arguments are added in isn't the same as the
2200    /// display order, whether in one-off cases or to automatically sort arguments.
2201    ///
2202    /// To change, see [`Command::next_display_order`][crate::Command::next_display_order].
2203    ///
2204    /// **NOTE:** This setting is ignored for [positional arguments] which are always displayed in
2205    /// [index] order.
2206    ///
2207    /// # Examples
2208    ///
2209    /// ```rust
2210    /// # #[cfg(feature = "help")] {
2211    /// # use clap_builder as clap;
2212    /// # use clap::{Command, Arg, ArgAction};
2213    /// let m = Command::new("prog")
2214    ///     .arg(Arg::new("boat")
2215    ///         .short('b')
2216    ///         .long("boat")
2217    ///         .action(ArgAction::Set)
2218    ///         .display_order(0)  // Sort
2219    ///         .help("Some help and text"))
2220    ///     .arg(Arg::new("airplane")
2221    ///         .short('a')
2222    ///         .long("airplane")
2223    ///         .action(ArgAction::Set)
2224    ///         .display_order(0)  // Sort
2225    ///         .help("I should be first!"))
2226    ///     .arg(Arg::new("custom-help")
2227    ///         .short('?')
2228    ///         .action(ArgAction::Help)
2229    ///         .display_order(100)  // Don't sort
2230    ///         .help("Alt help"))
2231    ///     .get_matches_from(vec![
2232    ///         "prog", "--help"
2233    ///     ]);
2234    /// # }
2235    /// ```
2236    ///
2237    /// The above example displays the following help message
2238    ///
2239    /// ```text
2240    /// cust-ord
2241    ///
2242    /// Usage: cust-ord [OPTIONS]
2243    ///
2244    /// Options:
2245    ///     -a, --airplane <airplane>    I should be first!
2246    ///     -b, --boat <boar>            Some help and text
2247    ///     -h, --help                   Print help information
2248    ///     -?                           Alt help
2249    /// ```
2250    /// [positional arguments]: Arg::index()
2251    /// [index]: Arg::index()
2252    #[inline]
2253    #[must_use]
2254    pub fn display_order(mut self, ord: impl IntoResettable<usize>) -> Self {
2255        self.disp_ord = ord.into_resettable().into_option();
2256        self
2257    }
2258
2259    /// Override the [current] help section.
2260    ///
2261    /// [current]: crate::Command::next_help_heading
2262    #[inline]
2263    #[must_use]
2264    pub fn help_heading(mut self, heading: impl IntoResettable<Str>) -> Self {
2265        self.help_heading = Some(heading.into_resettable().into_option());
2266        self
2267    }
2268
2269    /// Render the [help][Arg::help] on the line after the argument.
2270    ///
2271    /// This can be helpful for arguments with very long or complex help messages.
2272    /// This can also be helpful for arguments with very long flag names, or many/long value names.
2273    ///
2274    /// **NOTE:** To apply this setting to all arguments and subcommands, consider using
2275    /// [`crate::Command::next_line_help`]
2276    ///
2277    /// # Examples
2278    ///
2279    /// ```rust
2280    /// # #[cfg(feature = "help")] {
2281    /// # use clap_builder as clap;
2282    /// # use clap::{Command, Arg, ArgAction};
2283    /// let m = Command::new("prog")
2284    ///     .arg(Arg::new("opt")
2285    ///         .long("long-option-flag")
2286    ///         .short('o')
2287    ///         .action(ArgAction::Set)
2288    ///         .next_line_help(true)
2289    ///         .value_names(["value1", "value2"])
2290    ///         .help("Some really long help and complex\n\
2291    ///                help that makes more sense to be\n\
2292    ///                on a line after the option"))
2293    ///     .get_matches_from(vec![
2294    ///         "prog", "--help"
2295    ///     ]);
2296    /// # }
2297    /// ```
2298    ///
2299    /// The above example displays the following help message
2300    ///
2301    /// ```text
2302    /// nlh
2303    ///
2304    /// Usage: nlh [OPTIONS]
2305    ///
2306    /// Options:
2307    ///     -h, --help       Print help information
2308    ///     -V, --version    Print version information
2309    ///     -o, --long-option-flag <value1> <value2>
2310    ///         Some really long help and complex
2311    ///         help that makes more sense to be
2312    ///         on a line after the option
2313    /// ```
2314    #[inline]
2315    #[must_use]
2316    pub fn next_line_help(self, yes: bool) -> Self {
2317        if yes {
2318            self.setting(ArgSettings::NextLineHelp)
2319        } else {
2320            self.unset_setting(ArgSettings::NextLineHelp)
2321        }
2322    }
2323
2324    /// Do not display the argument in help message.
2325    ///
2326    /// **NOTE:** This does **not** hide the argument from usage strings on error
2327    ///
2328    /// # Examples
2329    ///
2330    /// Setting `Hidden` will hide the argument when displaying help text
2331    ///
2332    /// ```rust
2333    /// # #[cfg(feature = "help")] {
2334    /// # use clap_builder as clap;
2335    /// # use clap::{Command, Arg};
2336    /// let m = Command::new("prog")
2337    ///     .arg(Arg::new("cfg")
2338    ///         .long("config")
2339    ///         .hide(true)
2340    ///         .help("Some help text describing the --config arg"))
2341    ///     .get_matches_from(vec![
2342    ///         "prog", "--help"
2343    ///     ]);
2344    /// # }
2345    /// ```
2346    ///
2347    /// The above example displays
2348    ///
2349    /// ```text
2350    /// helptest
2351    ///
2352    /// Usage: helptest [OPTIONS]
2353    ///
2354    /// Options:
2355    /// -h, --help       Print help information
2356    /// -V, --version    Print version information
2357    /// ```
2358    #[inline]
2359    #[must_use]
2360    pub fn hide(self, yes: bool) -> Self {
2361        if yes {
2362            self.setting(ArgSettings::Hidden)
2363        } else {
2364            self.unset_setting(ArgSettings::Hidden)
2365        }
2366    }
2367
2368    /// Do not display the [possible values][crate::builder::ValueParser::possible_values] in the help message.
2369    ///
2370    /// This is useful for args with many values, or ones which are explained elsewhere in the
2371    /// help text.
2372    ///
2373    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
2374    ///
2375    /// To set this for all arguments, see
2376    /// [`Command::hide_possible_values`][crate::Command::hide_possible_values].
2377    ///
2378    /// # Examples
2379    ///
2380    /// ```rust
2381    /// # use clap_builder as clap;
2382    /// # use clap::{Command, Arg, ArgAction};
2383    /// let m = Command::new("prog")
2384    ///     .arg(Arg::new("mode")
2385    ///         .long("mode")
2386    ///         .value_parser(["fast", "slow"])
2387    ///         .action(ArgAction::Set)
2388    ///         .hide_possible_values(true));
2389    /// ```
2390    /// If we were to run the above program with `--help` the `[values: fast, slow]` portion of
2391    /// the help text would be omitted.
2392    #[inline]
2393    #[must_use]
2394    pub fn hide_possible_values(self, yes: bool) -> Self {
2395        if yes {
2396            self.setting(ArgSettings::HidePossibleValues)
2397        } else {
2398            self.unset_setting(ArgSettings::HidePossibleValues)
2399        }
2400    }
2401
2402    /// Do not display the default value of the argument in the help message.
2403    ///
2404    /// This is useful when default behavior of an arg is explained elsewhere in the help text.
2405    ///
2406    /// **NOTE:** Setting this requires [taking values][Arg::num_args]
2407    ///
2408    /// # Examples
2409    ///
2410    /// ```rust
2411    /// # use clap_builder as clap;
2412    /// # use clap::{Command, Arg, ArgAction};
2413    /// let m = Command::new("connect")
2414    ///     .arg(Arg::new("host")
2415    ///         .long("host")
2416    ///         .default_value("localhost")
2417    ///         .action(ArgAction::Set)
2418    ///         .hide_default_value(true));
2419    ///
2420    /// ```
2421    ///
2422    /// If we were to run the above program with `--help` the `[default: localhost]` portion of
2423    /// the help text would be omitted.
2424    #[inline]
2425    #[must_use]
2426    pub fn hide_default_value(self, yes: bool) -> Self {
2427        if yes {
2428            self.setting(ArgSettings::HideDefaultValue)
2429        } else {
2430            self.unset_setting(ArgSettings::HideDefaultValue)
2431        }
2432    }
2433
2434    /// Do not display in help the environment variable name.
2435    ///
2436    /// This is useful when the variable option is explained elsewhere in the help text.
2437    ///
2438    /// # Examples
2439    ///
2440    /// ```rust
2441    /// # use clap_builder as clap;
2442    /// # use clap::{Command, Arg, ArgAction};
2443    /// let m = Command::new("prog")
2444    ///     .arg(Arg::new("mode")
2445    ///         .long("mode")
2446    ///         .env("MODE")
2447    ///         .action(ArgAction::Set)
2448    ///         .hide_env(true));
2449    /// ```
2450    ///
2451    /// If we were to run the above program with `--help` the `[env: MODE]` portion of the help
2452    /// text would be omitted.
2453    #[cfg(feature = "env")]
2454    #[inline]
2455    #[must_use]
2456    pub fn hide_env(self, yes: bool) -> Self {
2457        if yes {
2458            self.setting(ArgSettings::HideEnv)
2459        } else {
2460            self.unset_setting(ArgSettings::HideEnv)
2461        }
2462    }
2463
2464    /// Do not display in help any values inside the associated ENV variables for the argument.
2465    ///
2466    /// This is useful when ENV vars contain sensitive values.
2467    ///
2468    /// # Examples
2469    ///
2470    /// ```rust
2471    /// # use clap_builder as clap;
2472    /// # use clap::{Command, Arg, ArgAction};
2473    /// let m = Command::new("connect")
2474    ///     .arg(Arg::new("host")
2475    ///         .long("host")
2476    ///         .env("CONNECT")
2477    ///         .action(ArgAction::Set)
2478    ///         .hide_env_values(true));
2479    ///
2480    /// ```
2481    ///
2482    /// If we were to run the above program with `$ CONNECT=super_secret connect --help` the
2483    /// `[default: CONNECT=super_secret]` portion of the help text would be omitted.
2484    #[cfg(feature = "env")]
2485    #[inline]
2486    #[must_use]
2487    pub fn hide_env_values(self, yes: bool) -> Self {
2488        if yes {
2489            self.setting(ArgSettings::HideEnvValues)
2490        } else {
2491            self.unset_setting(ArgSettings::HideEnvValues)
2492        }
2493    }
2494
2495    /// Hides an argument from short help (`-h`).
2496    ///
2497    /// **NOTE:** This does **not** hide the argument from usage strings on error
2498    ///
2499    /// **NOTE:** Setting this option will cause next-line-help output style to be used
2500    /// when long help (`--help`) is called.
2501    ///
2502    /// # Examples
2503    ///
2504    /// ```rust
2505    /// # use clap_builder as clap;
2506    /// # use clap::{Command, Arg};
2507    /// Arg::new("debug")
2508    ///     .hide_short_help(true);
2509    /// ```
2510    ///
2511    /// Setting `hide_short_help(true)` will hide the argument when displaying short help text
2512    ///
2513    /// ```rust
2514    /// # #[cfg(feature = "help")] {
2515    /// # use clap_builder as clap;
2516    /// # use clap::{Command, Arg};
2517    /// let m = Command::new("prog")
2518    ///     .arg(Arg::new("cfg")
2519    ///         .long("config")
2520    ///         .hide_short_help(true)
2521    ///         .help("Some help text describing the --config arg"))
2522    ///     .get_matches_from(vec![
2523    ///         "prog", "-h"
2524    ///     ]);
2525    /// # }
2526    /// ```
2527    ///
2528    /// The above example displays
2529    ///
2530    /// ```text
2531    /// helptest
2532    ///
2533    /// Usage: helptest [OPTIONS]
2534    ///
2535    /// Options:
2536    /// -h, --help       Print help information
2537    /// -V, --version    Print version information
2538    /// ```
2539    ///
2540    /// However, when --help is called
2541    ///
2542    /// ```rust
2543    /// # #[cfg(feature = "help")] {
2544    /// # use clap_builder as clap;
2545    /// # use clap::{Command, Arg};
2546    /// let m = Command::new("prog")
2547    ///     .arg(Arg::new("cfg")
2548    ///         .long("config")
2549    ///         .hide_short_help(true)
2550    ///         .help("Some help text describing the --config arg"))
2551    ///     .get_matches_from(vec![
2552    ///         "prog", "--help"
2553    ///     ]);
2554    /// # }
2555    /// ```
2556    ///
2557    /// Then the following would be displayed
2558    ///
2559    /// ```text
2560    /// helptest
2561    ///
2562    /// Usage: helptest [OPTIONS]
2563    ///
2564    /// Options:
2565    ///     --config     Some help text describing the --config arg
2566    /// -h, --help       Print help information
2567    /// -V, --version    Print version information
2568    /// ```
2569    #[inline]
2570    #[must_use]
2571    pub fn hide_short_help(self, yes: bool) -> Self {
2572        if yes {
2573            self.setting(ArgSettings::HiddenShortHelp)
2574        } else {
2575            self.unset_setting(ArgSettings::HiddenShortHelp)
2576        }
2577    }
2578
2579    /// Hides an argument from long help (`--help`).
2580    ///
2581    /// **NOTE:** This does **not** hide the argument from usage strings on error
2582    ///
2583    /// **NOTE:** Setting this option will cause next-line-help output style to be used
2584    /// when long help (`--help`) is called.
2585    ///
2586    /// # Examples
2587    ///
2588    /// Setting `hide_long_help(true)` will hide the argument when displaying long help text
2589    ///
2590    /// ```rust
2591    /// # #[cfg(feature = "help")] {
2592    /// # use clap_builder as clap;
2593    /// # use clap::{Command, Arg};
2594    /// let m = Command::new("prog")
2595    ///     .arg(Arg::new("cfg")
2596    ///         .long("config")
2597    ///         .hide_long_help(true)
2598    ///         .help("Some help text describing the --config arg"))
2599    ///     .get_matches_from(vec![
2600    ///         "prog", "--help"
2601    ///     ]);
2602    /// # }
2603    /// ```
2604    ///
2605    /// The above example displays
2606    ///
2607    /// ```text
2608    /// helptest
2609    ///
2610    /// Usage: helptest [OPTIONS]
2611    ///
2612    /// Options:
2613    /// -h, --help       Print help information
2614    /// -V, --version    Print version information
2615    /// ```
2616    ///
2617    /// However, when -h is called
2618    ///
2619    /// ```rust
2620    /// # #[cfg(feature = "help")] {
2621    /// # use clap_builder as clap;
2622    /// # use clap::{Command, Arg};
2623    /// let m = Command::new("prog")
2624    ///     .arg(Arg::new("cfg")
2625    ///         .long("config")
2626    ///         .hide_long_help(true)
2627    ///         .help("Some help text describing the --config arg"))
2628    ///     .get_matches_from(vec![
2629    ///         "prog", "-h"
2630    ///     ]);
2631    /// # }
2632    /// ```
2633    ///
2634    /// Then the following would be displayed
2635    ///
2636    /// ```text
2637    /// helptest
2638    ///
2639    /// Usage: helptest [OPTIONS]
2640    ///
2641    /// OPTIONS:
2642    ///     --config     Some help text describing the --config arg
2643    /// -h, --help       Print help information
2644    /// -V, --version    Print version information
2645    /// ```
2646    #[inline]
2647    #[must_use]
2648    pub fn hide_long_help(self, yes: bool) -> Self {
2649        if yes {
2650            self.setting(ArgSettings::HiddenLongHelp)
2651        } else {
2652            self.unset_setting(ArgSettings::HiddenLongHelp)
2653        }
2654    }
2655}
2656
2657/// # Advanced Argument Relations
2658impl Arg {
2659    /// The name of the [`ArgGroup`] the argument belongs to.
2660    ///
2661    /// # Examples
2662    ///
2663    /// ```rust
2664    /// # use clap_builder as clap;
2665    /// # use clap::{Command, Arg, ArgAction};
2666    /// Arg::new("debug")
2667    ///     .long("debug")
2668    ///     .action(ArgAction::SetTrue)
2669    ///     .group("mode")
2670    /// # ;
2671    /// ```
2672    ///
2673    /// Multiple arguments can be a member of a single group and then the group checked as if it
2674    /// was one of said arguments.
2675    ///
2676    /// ```rust
2677    /// # use clap_builder as clap;
2678    /// # use clap::{Command, Arg, ArgAction};
2679    /// let m = Command::new("prog")
2680    ///     .arg(Arg::new("debug")
2681    ///         .long("debug")
2682    ///         .action(ArgAction::SetTrue)
2683    ///         .group("mode"))
2684    ///     .arg(Arg::new("verbose")
2685    ///         .long("verbose")
2686    ///         .action(ArgAction::SetTrue)
2687    ///         .group("mode"))
2688    ///     .get_matches_from(vec![
2689    ///         "prog", "--debug"
2690    ///     ]);
2691    /// assert!(m.contains_id("mode"));
2692    /// ```
2693    ///
2694    /// [`ArgGroup`]: crate::ArgGroup
2695    #[must_use]
2696    pub fn group(mut self, group_id: impl IntoResettable<Id>) -> Self {
2697        if let Some(group_id) = group_id.into_resettable().into_option() {
2698            self.groups.push(group_id);
2699        } else {
2700            self.groups.clear();
2701        }
2702        self
2703    }
2704
2705    /// The names of [`ArgGroup`]'s the argument belongs to.
2706    ///
2707    /// # Examples
2708    ///
2709    /// ```rust
2710    /// # use clap_builder as clap;
2711    /// # use clap::{Command, Arg, ArgAction};
2712    /// Arg::new("debug")
2713    ///     .long("debug")
2714    ///     .action(ArgAction::SetTrue)
2715    ///     .groups(["mode", "verbosity"])
2716    /// # ;
2717    /// ```
2718    ///
2719    /// Arguments can be members of multiple groups and then the group checked as if it
2720    /// was one of said arguments.
2721    ///
2722    /// ```rust
2723    /// # use clap_builder as clap;
2724    /// # use clap::{Command, Arg, ArgAction};
2725    /// let m = Command::new("prog")
2726    ///     .arg(Arg::new("debug")
2727    ///         .long("debug")
2728    ///         .action(ArgAction::SetTrue)
2729    ///         .groups(["mode", "verbosity"]))
2730    ///     .arg(Arg::new("verbose")
2731    ///         .long("verbose")
2732    ///         .action(ArgAction::SetTrue)
2733    ///         .groups(["mode", "verbosity"]))
2734    ///     .get_matches_from(vec![
2735    ///         "prog", "--debug"
2736    ///     ]);
2737    /// assert!(m.contains_id("mode"));
2738    /// assert!(m.contains_id("verbosity"));
2739    /// ```
2740    ///
2741    /// [`ArgGroup`]: crate::ArgGroup
2742    #[must_use]
2743    pub fn groups(mut self, group_ids: impl IntoIterator<Item = impl Into<Id>>) -> Self {
2744        self.groups.extend(group_ids.into_iter().map(Into::into));
2745        self
2746    }
2747
2748    /// Specifies the value of the argument if `arg` has been used at runtime.
2749    ///
2750    /// If `default` is set to `None`, `default_value` will be removed.
2751    ///
2752    /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value`] but slightly
2753    /// different. `Arg::default_value` *only* takes effect when the user has not provided this arg
2754    /// at runtime. This setting however only takes effect when the user has not provided a value at
2755    /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value`
2756    /// and `Arg::default_value_if`, and the user **did not** provide this arg at runtime, nor were
2757    /// the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be applied.
2758    ///
2759    /// Like with command-line values, this will be split by [`Arg::value_delimiter`].
2760    ///
2761    /// # Examples
2762    ///
2763    /// First we use the default value only if another arg is present at runtime.
2764    ///
2765    /// ```rust
2766    /// # use clap_builder as clap;
2767    /// # use clap::{Command, Arg, ArgAction};
2768    /// # use clap::builder::{ArgPredicate};
2769    /// let m = Command::new("prog")
2770    ///     .arg(Arg::new("flag")
2771    ///         .long("flag")
2772    ///         .action(ArgAction::SetTrue))
2773    ///     .arg(Arg::new("other")
2774    ///         .long("other")
2775    ///         .default_value_if("flag", ArgPredicate::IsPresent, Some("default")))
2776    ///     .get_matches_from(vec![
2777    ///         "prog", "--flag"
2778    ///     ]);
2779    ///
2780    /// assert_eq!(m.get_one::<String>("other").unwrap(), "default");
2781    /// ```
2782    ///
2783    /// Next we run the same test, but without providing `--flag`.
2784    ///
2785    /// ```rust
2786    /// # use clap_builder as clap;
2787    /// # use clap::{Command, Arg, ArgAction};
2788    /// let m = Command::new("prog")
2789    ///     .arg(Arg::new("flag")
2790    ///         .long("flag")
2791    ///         .action(ArgAction::SetTrue))
2792    ///     .arg(Arg::new("other")
2793    ///         .long("other")
2794    ///         .default_value_if("flag", "true", Some("default")))
2795    ///     .get_matches_from(vec![
2796    ///         "prog"
2797    ///     ]);
2798    ///
2799    /// assert_eq!(m.get_one::<String>("other"), None);
2800    /// ```
2801    ///
2802    /// Now lets only use the default value if `--opt` contains the value `special`.
2803    ///
2804    /// ```rust
2805    /// # use clap_builder as clap;
2806    /// # use clap::{Command, Arg, ArgAction};
2807    /// let m = Command::new("prog")
2808    ///     .arg(Arg::new("opt")
2809    ///         .action(ArgAction::Set)
2810    ///         .long("opt"))
2811    ///     .arg(Arg::new("other")
2812    ///         .long("other")
2813    ///         .default_value_if("opt", "special", Some("default")))
2814    ///     .get_matches_from(vec![
2815    ///         "prog", "--opt", "special"
2816    ///     ]);
2817    ///
2818    /// assert_eq!(m.get_one::<String>("other").unwrap(), "default");
2819    /// ```
2820    ///
2821    /// We can run the same test and provide any value *other than* `special` and we won't get a
2822    /// default value.
2823    ///
2824    /// ```rust
2825    /// # use clap_builder as clap;
2826    /// # use clap::{Command, Arg, ArgAction};
2827    /// let m = Command::new("prog")
2828    ///     .arg(Arg::new("opt")
2829    ///         .action(ArgAction::Set)
2830    ///         .long("opt"))
2831    ///     .arg(Arg::new("other")
2832    ///         .long("other")
2833    ///         .default_value_if("opt", "special", Some("default")))
2834    ///     .get_matches_from(vec![
2835    ///         "prog", "--opt", "hahaha"
2836    ///     ]);
2837    ///
2838    /// assert_eq!(m.get_one::<String>("other"), None);
2839    /// ```
2840    ///
2841    /// If we want to unset the default value for an Arg based on the presence or
2842    /// value of some other Arg.
2843    ///
2844    /// ```rust
2845    /// # use clap_builder as clap;
2846    /// # use clap::{Command, Arg, ArgAction};
2847    /// let m = Command::new("prog")
2848    ///     .arg(Arg::new("flag")
2849    ///         .long("flag")
2850    ///         .action(ArgAction::SetTrue))
2851    ///     .arg(Arg::new("other")
2852    ///         .long("other")
2853    ///         .default_value("default")
2854    ///         .default_value_if("flag", "true", None))
2855    ///     .get_matches_from(vec![
2856    ///         "prog", "--flag"
2857    ///     ]);
2858    ///
2859    /// assert_eq!(m.get_one::<String>("other"), None);
2860    /// ```
2861    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
2862    /// [`Arg::default_value`]: Arg::default_value()
2863    #[must_use]
2864    pub fn default_value_if(
2865        mut self,
2866        arg_id: impl Into<Id>,
2867        predicate: impl Into<ArgPredicate>,
2868        default: impl IntoResettable<OsStr>,
2869    ) -> Self {
2870        self.default_vals_ifs.push((
2871            arg_id.into(),
2872            predicate.into(),
2873            default.into_resettable().into_option(),
2874        ));
2875        self
2876    }
2877
2878    #[must_use]
2879    #[doc(hidden)]
2880    #[cfg_attr(
2881        feature = "deprecated",
2882        deprecated(since = "4.0.0", note = "Replaced with `Arg::default_value_if`")
2883    )]
2884    pub fn default_value_if_os(
2885        self,
2886        arg_id: impl Into<Id>,
2887        predicate: impl Into<ArgPredicate>,
2888        default: impl IntoResettable<OsStr>,
2889    ) -> Self {
2890        self.default_value_if(arg_id, predicate, default)
2891    }
2892
2893    /// Specifies multiple values and conditions in the same manner as [`Arg::default_value_if`].
2894    ///
2895    /// The method takes a slice of tuples in the `(arg, predicate, default)` format.
2896    ///
2897    /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first
2898    /// if multiple conditions are true, the first one found will be applied and the ultimate value.
2899    ///
2900    /// Like with command-line values, this will be split by [`Arg::value_delimiter`].
2901    ///
2902    /// # Examples
2903    ///
2904    /// First we use the default value only if another arg is present at runtime.
2905    ///
2906    /// ```rust
2907    /// # use clap_builder as clap;
2908    /// # use clap::{Command, Arg, ArgAction};
2909    /// let m = Command::new("prog")
2910    ///     .arg(Arg::new("flag")
2911    ///         .long("flag")
2912    ///         .action(ArgAction::SetTrue))
2913    ///     .arg(Arg::new("opt")
2914    ///         .long("opt")
2915    ///         .action(ArgAction::Set))
2916    ///     .arg(Arg::new("other")
2917    ///         .long("other")
2918    ///         .default_value_ifs([
2919    ///             ("flag", "true", Some("default")),
2920    ///             ("opt", "channal", Some("chan")),
2921    ///         ]))
2922    ///     .get_matches_from(vec![
2923    ///         "prog", "--opt", "channal"
2924    ///     ]);
2925    ///
2926    /// assert_eq!(m.get_one::<String>("other").unwrap(), "chan");
2927    /// ```
2928    ///
2929    /// Next we run the same test, but without providing `--flag`.
2930    ///
2931    /// ```rust
2932    /// # use clap_builder as clap;
2933    /// # use clap::{Command, Arg, ArgAction};
2934    /// let m = Command::new("prog")
2935    ///     .arg(Arg::new("flag")
2936    ///         .long("flag")
2937    ///         .action(ArgAction::SetTrue))
2938    ///     .arg(Arg::new("other")
2939    ///         .long("other")
2940    ///         .default_value_ifs([
2941    ///             ("flag", "true", Some("default")),
2942    ///             ("opt", "channal", Some("chan")),
2943    ///         ]))
2944    ///     .get_matches_from(vec![
2945    ///         "prog"
2946    ///     ]);
2947    ///
2948    /// assert_eq!(m.get_one::<String>("other"), None);
2949    /// ```
2950    ///
2951    /// We can also see that these values are applied in order, and if more than one condition is
2952    /// true, only the first evaluated "wins"
2953    ///
2954    /// ```rust
2955    /// # use clap_builder as clap;
2956    /// # use clap::{Command, Arg, ArgAction};
2957    /// # use clap::builder::ArgPredicate;
2958    /// let m = Command::new("prog")
2959    ///     .arg(Arg::new("flag")
2960    ///         .long("flag")
2961    ///         .action(ArgAction::SetTrue))
2962    ///     .arg(Arg::new("opt")
2963    ///         .long("opt")
2964    ///         .action(ArgAction::Set))
2965    ///     .arg(Arg::new("other")
2966    ///         .long("other")
2967    ///         .default_value_ifs([
2968    ///             ("flag", ArgPredicate::IsPresent, Some("default")),
2969    ///             ("opt", ArgPredicate::Equals("channal".into()), Some("chan")),
2970    ///         ]))
2971    ///     .get_matches_from(vec![
2972    ///         "prog", "--opt", "channal", "--flag"
2973    ///     ]);
2974    ///
2975    /// assert_eq!(m.get_one::<String>("other").unwrap(), "default");
2976    /// ```
2977    /// [`Arg::action(ArgAction::Set)`]: Arg::action()
2978    /// [`Arg::default_value_if`]: Arg::default_value_if()
2979    #[must_use]
2980    pub fn default_value_ifs(
2981        mut self,
2982        ifs: impl IntoIterator<
2983            Item = (
2984                impl Into<Id>,
2985                impl Into<ArgPredicate>,
2986                impl IntoResettable<OsStr>,
2987            ),
2988        >,
2989    ) -> Self {
2990        for (arg, predicate, default) in ifs {
2991            self = self.default_value_if(arg, predicate, default);
2992        }
2993        self
2994    }
2995
2996    #[must_use]
2997    #[doc(hidden)]
2998    #[cfg_attr(
2999        feature = "deprecated",
3000        deprecated(since = "4.0.0", note = "Replaced with `Arg::default_value_ifs`")
3001    )]
3002    pub fn default_value_ifs_os(
3003        self,
3004        ifs: impl IntoIterator<
3005            Item = (
3006                impl Into<Id>,
3007                impl Into<ArgPredicate>,
3008                impl IntoResettable<OsStr>,
3009            ),
3010        >,
3011    ) -> Self {
3012        self.default_value_ifs(ifs)
3013    }
3014
3015    /// Set this arg as [required] as long as the specified argument is not present at runtime.
3016    ///
3017    /// **Pro Tip:** Using `Arg::required_unless_present` implies [`Arg::required`] and is therefore not
3018    /// mandatory to also set.
3019    ///
3020    /// # Examples
3021    ///
3022    /// ```rust
3023    /// # use clap_builder as clap;
3024    /// # use clap::Arg;
3025    /// Arg::new("config")
3026    ///     .required_unless_present("debug")
3027    /// # ;
3028    /// ```
3029    ///
3030    /// In the following example, the required argument is *not* provided,
3031    /// but it's not an error because the `unless` arg has been supplied.
3032    ///
3033    /// ```rust
3034    /// # use clap_builder as clap;
3035    /// # use clap::{Command, Arg, ArgAction};
3036    /// let res = Command::new("prog")
3037    ///     .arg(Arg::new("cfg")
3038    ///         .required_unless_present("dbg")
3039    ///         .action(ArgAction::Set)
3040    ///         .long("config"))
3041    ///     .arg(Arg::new("dbg")
3042    ///         .long("debug")
3043    ///         .action(ArgAction::SetTrue))
3044    ///     .try_get_matches_from(vec![
3045    ///         "prog", "--debug"
3046    ///     ]);
3047    ///
3048    /// assert!(res.is_ok());
3049    /// ```
3050    ///
3051    /// Setting `Arg::required_unless_present(name)` and *not* supplying `name` or this arg is an error.
3052    ///
3053    /// ```rust
3054    /// # use clap_builder as clap;
3055    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3056    /// let res = Command::new("prog")
3057    ///     .arg(Arg::new("cfg")
3058    ///         .required_unless_present("dbg")
3059    ///         .action(ArgAction::Set)
3060    ///         .long("config"))
3061    ///     .arg(Arg::new("dbg")
3062    ///         .long("debug"))
3063    ///     .try_get_matches_from(vec![
3064    ///         "prog"
3065    ///     ]);
3066    ///
3067    /// assert!(res.is_err());
3068    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3069    /// ```
3070    /// [required]: Arg::required()
3071    #[must_use]
3072    pub fn required_unless_present(mut self, arg_id: impl IntoResettable<Id>) -> Self {
3073        if let Some(arg_id) = arg_id.into_resettable().into_option() {
3074            self.r_unless.push(arg_id);
3075        } else {
3076            self.r_unless.clear();
3077        }
3078        self
3079    }
3080
3081    /// Sets this arg as [required] unless *all* of the specified arguments are present at runtime.
3082    ///
3083    /// In other words, parsing will succeed only if user either
3084    /// * supplies the `self` arg.
3085    /// * supplies *all* of the `names` arguments.
3086    ///
3087    /// **NOTE:** If you wish for this argument to only be required unless *any of* these args are
3088    /// present see [`Arg::required_unless_present_any`]
3089    ///
3090    /// # Examples
3091    ///
3092    /// ```rust
3093    /// # use clap_builder as clap;
3094    /// # use clap::Arg;
3095    /// Arg::new("config")
3096    ///     .required_unless_present_all(["cfg", "dbg"])
3097    /// # ;
3098    /// ```
3099    ///
3100    /// In the following example, the required argument is *not* provided, but it's not an error
3101    /// because *all* of the `names` args have been supplied.
3102    ///
3103    /// ```rust
3104    /// # use clap_builder as clap;
3105    /// # use clap::{Command, Arg, ArgAction};
3106    /// let res = Command::new("prog")
3107    ///     .arg(Arg::new("cfg")
3108    ///         .required_unless_present_all(["dbg", "infile"])
3109    ///         .action(ArgAction::Set)
3110    ///         .long("config"))
3111    ///     .arg(Arg::new("dbg")
3112    ///         .long("debug")
3113    ///         .action(ArgAction::SetTrue))
3114    ///     .arg(Arg::new("infile")
3115    ///         .short('i')
3116    ///         .action(ArgAction::Set))
3117    ///     .try_get_matches_from(vec![
3118    ///         "prog", "--debug", "-i", "file"
3119    ///     ]);
3120    ///
3121    /// assert!(res.is_ok());
3122    /// ```
3123    ///
3124    /// Setting [`Arg::required_unless_present_all(names)`] and *not* supplying
3125    /// either *all* of `unless` args or the `self` arg is an error.
3126    ///
3127    /// ```rust
3128    /// # use clap_builder as clap;
3129    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3130    /// let res = Command::new("prog")
3131    ///     .arg(Arg::new("cfg")
3132    ///         .required_unless_present_all(["dbg", "infile"])
3133    ///         .action(ArgAction::Set)
3134    ///         .long("config"))
3135    ///     .arg(Arg::new("dbg")
3136    ///         .long("debug")
3137    ///         .action(ArgAction::SetTrue))
3138    ///     .arg(Arg::new("infile")
3139    ///         .short('i')
3140    ///         .action(ArgAction::Set))
3141    ///     .try_get_matches_from(vec![
3142    ///         "prog"
3143    ///     ]);
3144    ///
3145    /// assert!(res.is_err());
3146    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3147    /// ```
3148    /// [required]: Arg::required()
3149    /// [`Arg::required_unless_present_any`]: Arg::required_unless_present_any()
3150    /// [`Arg::required_unless_present_all(names)`]: Arg::required_unless_present_all()
3151    #[must_use]
3152    pub fn required_unless_present_all(
3153        mut self,
3154        names: impl IntoIterator<Item = impl Into<Id>>,
3155    ) -> Self {
3156        self.r_unless_all.extend(names.into_iter().map(Into::into));
3157        self
3158    }
3159
3160    /// Sets this arg as [required] unless *any* of the specified arguments are present at runtime.
3161    ///
3162    /// In other words, parsing will succeed only if user either
3163    /// * supplies the `self` arg.
3164    /// * supplies *one or more* of the `unless` arguments.
3165    ///
3166    /// **NOTE:** If you wish for this argument to be required unless *all of* these args are
3167    /// present see [`Arg::required_unless_present_all`]
3168    ///
3169    /// # Examples
3170    ///
3171    /// ```rust
3172    /// # use clap_builder as clap;
3173    /// # use clap::Arg;
3174    /// Arg::new("config")
3175    ///     .required_unless_present_any(["cfg", "dbg"])
3176    /// # ;
3177    /// ```
3178    ///
3179    /// Setting [`Arg::required_unless_present_any(names)`] requires that the argument be used at runtime
3180    /// *unless* *at least one of* the args in `names` are present. In the following example, the
3181    /// required argument is *not* provided, but it's not an error because one the `unless` args
3182    /// have been supplied.
3183    ///
3184    /// ```rust
3185    /// # use clap_builder as clap;
3186    /// # use clap::{Command, Arg, ArgAction};
3187    /// let res = Command::new("prog")
3188    ///     .arg(Arg::new("cfg")
3189    ///         .required_unless_present_any(["dbg", "infile"])
3190    ///         .action(ArgAction::Set)
3191    ///         .long("config"))
3192    ///     .arg(Arg::new("dbg")
3193    ///         .long("debug")
3194    ///         .action(ArgAction::SetTrue))
3195    ///     .arg(Arg::new("infile")
3196    ///         .short('i')
3197    ///         .action(ArgAction::Set))
3198    ///     .try_get_matches_from(vec![
3199    ///         "prog", "--debug"
3200    ///     ]);
3201    ///
3202    /// assert!(res.is_ok());
3203    /// ```
3204    ///
3205    /// Setting [`Arg::required_unless_present_any(names)`] and *not* supplying *at least one of* `names`
3206    /// or this arg is an error.
3207    ///
3208    /// ```rust
3209    /// # use clap_builder as clap;
3210    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3211    /// let res = Command::new("prog")
3212    ///     .arg(Arg::new("cfg")
3213    ///         .required_unless_present_any(["dbg", "infile"])
3214    ///         .action(ArgAction::Set)
3215    ///         .long("config"))
3216    ///     .arg(Arg::new("dbg")
3217    ///         .long("debug")
3218    ///         .action(ArgAction::SetTrue))
3219    ///     .arg(Arg::new("infile")
3220    ///         .short('i')
3221    ///         .action(ArgAction::Set))
3222    ///     .try_get_matches_from(vec![
3223    ///         "prog"
3224    ///     ]);
3225    ///
3226    /// assert!(res.is_err());
3227    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3228    /// ```
3229    /// [required]: Arg::required()
3230    /// [`Arg::required_unless_present_any(names)`]: Arg::required_unless_present_any()
3231    /// [`Arg::required_unless_present_all`]: Arg::required_unless_present_all()
3232    #[must_use]
3233    pub fn required_unless_present_any(
3234        mut self,
3235        names: impl IntoIterator<Item = impl Into<Id>>,
3236    ) -> Self {
3237        self.r_unless.extend(names.into_iter().map(Into::into));
3238        self
3239    }
3240
3241    /// This argument is [required] only if the specified `arg` is present at runtime and its value
3242    /// equals `val`.
3243    ///
3244    /// # Examples
3245    ///
3246    /// ```rust
3247    /// # use clap_builder as clap;
3248    /// # use clap::Arg;
3249    /// Arg::new("config")
3250    ///     .required_if_eq("other_arg", "value")
3251    /// # ;
3252    /// ```
3253    ///
3254    /// ```rust
3255    /// # use clap_builder as clap;
3256    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3257    /// let res = Command::new("prog")
3258    ///     .arg(Arg::new("cfg")
3259    ///         .action(ArgAction::Set)
3260    ///         .required_if_eq("other", "special")
3261    ///         .long("config"))
3262    ///     .arg(Arg::new("other")
3263    ///         .long("other")
3264    ///         .action(ArgAction::Set))
3265    ///     .try_get_matches_from(vec![
3266    ///         "prog", "--other", "not-special"
3267    ///     ]);
3268    ///
3269    /// assert!(res.is_ok()); // We didn't use --other=special, so "cfg" wasn't required
3270    ///
3271    /// let res = Command::new("prog")
3272    ///     .arg(Arg::new("cfg")
3273    ///         .action(ArgAction::Set)
3274    ///         .required_if_eq("other", "special")
3275    ///         .long("config"))
3276    ///     .arg(Arg::new("other")
3277    ///         .long("other")
3278    ///         .action(ArgAction::Set))
3279    ///     .try_get_matches_from(vec![
3280    ///         "prog", "--other", "special"
3281    ///     ]);
3282    ///
3283    /// // We did use --other=special so "cfg" had become required but was missing.
3284    /// assert!(res.is_err());
3285    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3286    ///
3287    /// let res = Command::new("prog")
3288    ///     .arg(Arg::new("cfg")
3289    ///         .action(ArgAction::Set)
3290    ///         .required_if_eq("other", "special")
3291    ///         .long("config"))
3292    ///     .arg(Arg::new("other")
3293    ///         .long("other")
3294    ///         .action(ArgAction::Set))
3295    ///     .try_get_matches_from(vec![
3296    ///         "prog", "--other", "SPECIAL"
3297    ///     ]);
3298    ///
3299    /// // By default, the comparison is case-sensitive, so "cfg" wasn't required
3300    /// assert!(res.is_ok());
3301    ///
3302    /// let res = Command::new("prog")
3303    ///     .arg(Arg::new("cfg")
3304    ///         .action(ArgAction::Set)
3305    ///         .required_if_eq("other", "special")
3306    ///         .long("config"))
3307    ///     .arg(Arg::new("other")
3308    ///         .long("other")
3309    ///         .ignore_case(true)
3310    ///         .action(ArgAction::Set))
3311    ///     .try_get_matches_from(vec![
3312    ///         "prog", "--other", "SPECIAL"
3313    ///     ]);
3314    ///
3315    /// // However, case-insensitive comparisons can be enabled.  This typically occurs when using Arg::possible_values().
3316    /// assert!(res.is_err());
3317    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3318    /// ```
3319    /// [`Arg::requires(name)`]: Arg::requires()
3320    /// [Conflicting]: Arg::conflicts_with()
3321    /// [required]: Arg::required()
3322    #[must_use]
3323    pub fn required_if_eq(mut self, arg_id: impl Into<Id>, val: impl Into<OsStr>) -> Self {
3324        self.r_ifs.push((arg_id.into(), val.into()));
3325        self
3326    }
3327
3328    /// Specify this argument is [required] based on multiple conditions.
3329    ///
3330    /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become
3331    /// valid if one of the specified `arg`'s value equals its corresponding `val`.
3332    ///
3333    /// # Examples
3334    ///
3335    /// ```rust
3336    /// # use clap_builder as clap;
3337    /// # use clap::Arg;
3338    /// Arg::new("config")
3339    ///     .required_if_eq_any([
3340    ///         ("extra", "val"),
3341    ///         ("option", "spec")
3342    ///     ])
3343    /// # ;
3344    /// ```
3345    ///
3346    /// Setting `Arg::required_if_eq_any([(arg, val)])` makes this arg required if any of the `arg`s
3347    /// are used at runtime and it's corresponding value is equal to `val`. If the `arg`'s value is
3348    /// anything other than `val`, this argument isn't required.
3349    ///
3350    /// ```rust
3351    /// # use clap_builder as clap;
3352    /// # use clap::{Command, Arg, ArgAction};
3353    /// let res = Command::new("prog")
3354    ///     .arg(Arg::new("cfg")
3355    ///         .required_if_eq_any([
3356    ///             ("extra", "val"),
3357    ///             ("option", "spec")
3358    ///         ])
3359    ///         .action(ArgAction::Set)
3360    ///         .long("config"))
3361    ///     .arg(Arg::new("extra")
3362    ///         .action(ArgAction::Set)
3363    ///         .long("extra"))
3364    ///     .arg(Arg::new("option")
3365    ///         .action(ArgAction::Set)
3366    ///         .long("option"))
3367    ///     .try_get_matches_from(vec![
3368    ///         "prog", "--option", "other"
3369    ///     ]);
3370    ///
3371    /// assert!(res.is_ok()); // We didn't use --option=spec, or --extra=val so "cfg" isn't required
3372    /// ```
3373    ///
3374    /// Setting `Arg::required_if_eq_any([(arg, val)])` and having any of the `arg`s used with its
3375    /// value of `val` but *not* using this arg is an error.
3376    ///
3377    /// ```rust
3378    /// # use clap_builder as clap;
3379    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3380    /// let res = Command::new("prog")
3381    ///     .arg(Arg::new("cfg")
3382    ///         .required_if_eq_any([
3383    ///             ("extra", "val"),
3384    ///             ("option", "spec")
3385    ///         ])
3386    ///         .action(ArgAction::Set)
3387    ///         .long("config"))
3388    ///     .arg(Arg::new("extra")
3389    ///         .action(ArgAction::Set)
3390    ///         .long("extra"))
3391    ///     .arg(Arg::new("option")
3392    ///         .action(ArgAction::Set)
3393    ///         .long("option"))
3394    ///     .try_get_matches_from(vec![
3395    ///         "prog", "--option", "spec"
3396    ///     ]);
3397    ///
3398    /// assert!(res.is_err());
3399    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3400    /// ```
3401    /// [`Arg::requires(name)`]: Arg::requires()
3402    /// [Conflicting]: Arg::conflicts_with()
3403    /// [required]: Arg::required()
3404    #[must_use]
3405    pub fn required_if_eq_any(
3406        mut self,
3407        ifs: impl IntoIterator<Item = (impl Into<Id>, impl Into<OsStr>)>,
3408    ) -> Self {
3409        self.r_ifs
3410            .extend(ifs.into_iter().map(|(id, val)| (id.into(), val.into())));
3411        self
3412    }
3413
3414    /// Specify this argument is [required] based on multiple conditions.
3415    ///
3416    /// The conditions are set up in a `(arg, val)` style tuple. The requirement will only become
3417    /// valid if every one of the specified `arg`'s value equals its corresponding `val`.
3418    ///
3419    /// # Examples
3420    ///
3421    /// ```rust
3422    /// # use clap_builder as clap;
3423    /// # use clap::Arg;
3424    /// Arg::new("config")
3425    ///     .required_if_eq_all([
3426    ///         ("extra", "val"),
3427    ///         ("option", "spec")
3428    ///     ])
3429    /// # ;
3430    /// ```
3431    ///
3432    /// Setting `Arg::required_if_eq_all([(arg, val)])` makes this arg required if all of the `arg`s
3433    /// are used at runtime and every value is equal to its corresponding `val`. If the `arg`'s value is
3434    /// anything other than `val`, this argument isn't required.
3435    ///
3436    /// ```rust
3437    /// # use clap_builder as clap;
3438    /// # use clap::{Command, Arg, ArgAction};
3439    /// let res = Command::new("prog")
3440    ///     .arg(Arg::new("cfg")
3441    ///         .required_if_eq_all([
3442    ///             ("extra", "val"),
3443    ///             ("option", "spec")
3444    ///         ])
3445    ///         .action(ArgAction::Set)
3446    ///         .long("config"))
3447    ///     .arg(Arg::new("extra")
3448    ///         .action(ArgAction::Set)
3449    ///         .long("extra"))
3450    ///     .arg(Arg::new("option")
3451    ///         .action(ArgAction::Set)
3452    ///         .long("option"))
3453    ///     .try_get_matches_from(vec![
3454    ///         "prog", "--option", "spec"
3455    ///     ]);
3456    ///
3457    /// assert!(res.is_ok()); // We didn't use --option=spec --extra=val so "cfg" isn't required
3458    /// ```
3459    ///
3460    /// Setting `Arg::required_if_eq_all([(arg, val)])` and having all of the `arg`s used with its
3461    /// value of `val` but *not* using this arg is an error.
3462    ///
3463    /// ```rust
3464    /// # use clap_builder as clap;
3465    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3466    /// let res = Command::new("prog")
3467    ///     .arg(Arg::new("cfg")
3468    ///         .required_if_eq_all([
3469    ///             ("extra", "val"),
3470    ///             ("option", "spec")
3471    ///         ])
3472    ///         .action(ArgAction::Set)
3473    ///         .long("config"))
3474    ///     .arg(Arg::new("extra")
3475    ///         .action(ArgAction::Set)
3476    ///         .long("extra"))
3477    ///     .arg(Arg::new("option")
3478    ///         .action(ArgAction::Set)
3479    ///         .long("option"))
3480    ///     .try_get_matches_from(vec![
3481    ///         "prog", "--extra", "val", "--option", "spec"
3482    ///     ]);
3483    ///
3484    /// assert!(res.is_err());
3485    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3486    /// ```
3487    /// [required]: Arg::required()
3488    #[must_use]
3489    pub fn required_if_eq_all(
3490        mut self,
3491        ifs: impl IntoIterator<Item = (impl Into<Id>, impl Into<OsStr>)>,
3492    ) -> Self {
3493        self.r_ifs_all
3494            .extend(ifs.into_iter().map(|(id, val)| (id.into(), val.into())));
3495        self
3496    }
3497
3498    /// Require another argument if this arg matches the [`ArgPredicate`]
3499    ///
3500    /// This method takes `value, another_arg` pair. At runtime, clap will check
3501    /// if this arg (`self`) matches the [`ArgPredicate`].
3502    /// If it does, `another_arg` will be marked as required.
3503    ///
3504    /// # Examples
3505    ///
3506    /// ```rust
3507    /// # use clap_builder as clap;
3508    /// # use clap::Arg;
3509    /// Arg::new("config")
3510    ///     .requires_if("val", "arg")
3511    /// # ;
3512    /// ```
3513    ///
3514    /// Setting `Arg::requires_if(val, arg)` requires that the `arg` be used at runtime if the
3515    /// defining argument's value is equal to `val`. If the defining argument is anything other than
3516    /// `val`, the other argument isn't required.
3517    ///
3518    /// ```rust
3519    /// # use clap_builder as clap;
3520    /// # use clap::{Command, Arg, ArgAction};
3521    /// let res = Command::new("prog")
3522    ///     .arg(Arg::new("cfg")
3523    ///         .action(ArgAction::Set)
3524    ///         .requires_if("my.cfg", "other")
3525    ///         .long("config"))
3526    ///     .arg(Arg::new("other"))
3527    ///     .try_get_matches_from(vec![
3528    ///         "prog", "--config", "some.cfg"
3529    ///     ]);
3530    ///
3531    /// assert!(res.is_ok()); // We didn't use --config=my.cfg, so other wasn't required
3532    /// ```
3533    ///
3534    /// Setting `Arg::requires_if(val, arg)` and setting the value to `val` but *not* supplying
3535    /// `arg` is an error.
3536    ///
3537    /// ```rust
3538    /// # use clap_builder as clap;
3539    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3540    /// let res = Command::new("prog")
3541    ///     .arg(Arg::new("cfg")
3542    ///         .action(ArgAction::Set)
3543    ///         .requires_if("my.cfg", "input")
3544    ///         .long("config"))
3545    ///     .arg(Arg::new("input"))
3546    ///     .try_get_matches_from(vec![
3547    ///         "prog", "--config", "my.cfg"
3548    ///     ]);
3549    ///
3550    /// assert!(res.is_err());
3551    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3552    /// ```
3553    /// [`Arg::requires(name)`]: Arg::requires()
3554    /// [Conflicting]: Arg::conflicts_with()
3555    /// [override]: Arg::overrides_with()
3556    #[must_use]
3557    pub fn requires_if(mut self, val: impl Into<ArgPredicate>, arg_id: impl Into<Id>) -> Self {
3558        self.requires.push((val.into(), arg_id.into()));
3559        self
3560    }
3561
3562    /// Allows multiple conditional requirements.
3563    ///
3564    /// The requirement will only become valid if this arg's value matches the
3565    /// [`ArgPredicate`].
3566    ///
3567    /// # Examples
3568    ///
3569    /// ```rust
3570    /// # use clap_builder as clap;
3571    /// # use clap::Arg;
3572    /// Arg::new("config")
3573    ///     .requires_ifs([
3574    ///         ("val", "arg"),
3575    ///         ("other_val", "arg2"),
3576    ///     ])
3577    /// # ;
3578    /// ```
3579    ///
3580    /// Setting `Arg::requires_ifs(["val", "arg"])` requires that the `arg` be used at runtime if the
3581    /// defining argument's value is equal to `val`. If the defining argument's value is anything other
3582    /// than `val`, `arg` isn't required.
3583    ///
3584    /// ```rust
3585    /// # use clap_builder as clap;
3586    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3587    /// let res = Command::new("prog")
3588    ///     .arg(Arg::new("cfg")
3589    ///         .action(ArgAction::Set)
3590    ///         .requires_ifs([
3591    ///             ("special.conf", "opt"),
3592    ///             ("other.conf", "other"),
3593    ///         ])
3594    ///         .long("config"))
3595    ///     .arg(Arg::new("opt")
3596    ///         .long("option")
3597    ///         .action(ArgAction::Set))
3598    ///     .arg(Arg::new("other"))
3599    ///     .try_get_matches_from(vec![
3600    ///         "prog", "--config", "special.conf"
3601    ///     ]);
3602    ///
3603    /// assert!(res.is_err()); // We  used --config=special.conf so --option <val> is required
3604    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3605    /// ```
3606    ///
3607    /// Setting `Arg::requires_ifs` with [`ArgPredicate::IsPresent`] and *not* supplying all the
3608    /// arguments is an error.
3609    ///
3610    /// ```rust
3611    /// # use clap_builder as clap;
3612    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction, builder::ArgPredicate};
3613    /// let res = Command::new("prog")
3614    ///     .arg(Arg::new("cfg")
3615    ///         .action(ArgAction::Set)
3616    ///         .requires_ifs([
3617    ///             (ArgPredicate::IsPresent, "input"),
3618    ///             (ArgPredicate::IsPresent, "output"),
3619    ///         ])
3620    ///         .long("config"))
3621    ///     .arg(Arg::new("input"))
3622    ///     .arg(Arg::new("output"))
3623    ///     .try_get_matches_from(vec![
3624    ///         "prog", "--config", "file.conf", "in.txt"
3625    ///     ]);
3626    ///
3627    /// assert!(res.is_err());
3628    /// // We didn't use output
3629    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::MissingRequiredArgument);
3630    /// ```
3631    ///
3632    /// [`Arg::requires(name)`]: Arg::requires()
3633    /// [Conflicting]: Arg::conflicts_with()
3634    /// [override]: Arg::overrides_with()
3635    #[must_use]
3636    pub fn requires_ifs(
3637        mut self,
3638        ifs: impl IntoIterator<Item = (impl Into<ArgPredicate>, impl Into<Id>)>,
3639    ) -> Self {
3640        self.requires
3641            .extend(ifs.into_iter().map(|(val, arg)| (val.into(), arg.into())));
3642        self
3643    }
3644
3645    #[doc(hidden)]
3646    #[cfg_attr(
3647        feature = "deprecated",
3648        deprecated(since = "4.0.0", note = "Replaced with `Arg::requires_ifs`")
3649    )]
3650    pub fn requires_all(self, ids: impl IntoIterator<Item = impl Into<Id>>) -> Self {
3651        self.requires_ifs(ids.into_iter().map(|id| (ArgPredicate::IsPresent, id)))
3652    }
3653
3654    /// This argument is mutually exclusive with the specified argument.
3655    ///
3656    /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules
3657    /// only need to be set for one of the two arguments, they do not need to be set for each.
3658    ///
3659    /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
3660    /// (i.e. if A conflicts with B, defining `A.conflicts_with(B)` is sufficient. You do not
3661    /// need to also do `B.conflicts_with(A)`)
3662    ///
3663    /// **NOTE:** [`Arg::conflicts_with_all(names)`] allows specifying an argument which conflicts with more than one argument.
3664    ///
3665    /// **NOTE** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
3666    ///
3667    /// **NOTE:** All arguments implicitly conflict with themselves.
3668    ///
3669    /// # Examples
3670    ///
3671    /// ```rust
3672    /// # use clap_builder as clap;
3673    /// # use clap::Arg;
3674    /// Arg::new("config")
3675    ///     .conflicts_with("debug")
3676    /// # ;
3677    /// ```
3678    ///
3679    /// Setting conflicting argument, and having both arguments present at runtime is an error.
3680    ///
3681    /// ```rust
3682    /// # use clap_builder as clap;
3683    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3684    /// let res = Command::new("prog")
3685    ///     .arg(Arg::new("cfg")
3686    ///         .action(ArgAction::Set)
3687    ///         .conflicts_with("debug")
3688    ///         .long("config"))
3689    ///     .arg(Arg::new("debug")
3690    ///         .long("debug")
3691    ///         .action(ArgAction::SetTrue))
3692    ///     .try_get_matches_from(vec![
3693    ///         "prog", "--debug", "--config", "file.conf"
3694    ///     ]);
3695    ///
3696    /// assert!(res.is_err());
3697    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict);
3698    /// ```
3699    ///
3700    /// [`Arg::conflicts_with_all(names)`]: Arg::conflicts_with_all()
3701    /// [`Arg::exclusive(true)`]: Arg::exclusive()
3702    #[must_use]
3703    pub fn conflicts_with(mut self, arg_id: impl IntoResettable<Id>) -> Self {
3704        if let Some(arg_id) = arg_id.into_resettable().into_option() {
3705            self.blacklist.push(arg_id);
3706        } else {
3707            self.blacklist.clear();
3708        }
3709        self
3710    }
3711
3712    /// This argument is mutually exclusive with the specified arguments.
3713    ///
3714    /// See [`Arg::conflicts_with`].
3715    ///
3716    /// **NOTE:** Conflicting rules take precedence over being required by default. Conflict rules
3717    /// only need to be set for one of the two arguments, they do not need to be set for each.
3718    ///
3719    /// **NOTE:** Defining a conflict is two-way, but does *not* need to defined for both arguments
3720    /// (i.e. if A conflicts with B, defining `A.conflicts_with(B)` is sufficient. You do not need
3721    /// need to also do `B.conflicts_with(A)`)
3722    ///
3723    /// **NOTE:** [`Arg::exclusive(true)`] allows specifying an argument which conflicts with every other argument.
3724    ///
3725    /// # Examples
3726    ///
3727    /// ```rust
3728    /// # use clap_builder as clap;
3729    /// # use clap::Arg;
3730    /// Arg::new("config")
3731    ///     .conflicts_with_all(["debug", "input"])
3732    /// # ;
3733    /// ```
3734    ///
3735    /// Setting conflicting argument, and having any of the arguments present at runtime with a
3736    /// conflicting argument is an error.
3737    ///
3738    /// ```rust
3739    /// # use clap_builder as clap;
3740    /// # use clap::{Command, Arg, error::ErrorKind, ArgAction};
3741    /// let res = Command::new("prog")
3742    ///     .arg(Arg::new("cfg")
3743    ///         .action(ArgAction::Set)
3744    ///         .conflicts_with_all(["debug", "input"])
3745    ///         .long("config"))
3746    ///     .arg(Arg::new("debug")
3747    ///         .long("debug"))
3748    ///     .arg(Arg::new("input"))
3749    ///     .try_get_matches_from(vec![
3750    ///         "prog", "--config", "file.conf", "file.txt"
3751    ///     ]);
3752    ///
3753    /// assert!(res.is_err());
3754    /// assert_eq!(res.unwrap_err().kind(), ErrorKind::ArgumentConflict);
3755    /// ```
3756    /// [`Arg::conflicts_with`]: Arg::conflicts_with()
3757    /// [`Arg::exclusive(true)`]: Arg::exclusive()
3758    #[must_use]
3759    pub fn conflicts_with_all(mut self, names: impl IntoIterator<Item = impl Into<Id>>) -> Self {
3760        self.blacklist.extend(names.into_iter().map(Into::into));
3761        self
3762    }
3763
3764    /// Sets an overridable argument.
3765    ///
3766    /// i.e. this argument and the following argument
3767    /// will override each other in POSIX style (whichever argument was specified at runtime
3768    /// **last** "wins")
3769    ///
3770    /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any
3771    /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed
3772    ///
3773    /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with`].
3774    ///
3775    /// # Examples
3776    ///
3777    /// ```rust
3778    /// # use clap_builder as clap;
3779    /// # use clap::{Command, arg};
3780    /// let m = Command::new("prog")
3781    ///     .arg(arg!(-f --flag "some flag")
3782    ///         .conflicts_with("debug"))
3783    ///     .arg(arg!(-d --debug "other flag"))
3784    ///     .arg(arg!(-c --color "third flag")
3785    ///         .overrides_with("flag"))
3786    ///     .get_matches_from(vec![
3787    ///         "prog", "-f", "-d", "-c"]);
3788    ///             //    ^~~~~~~~~~~~^~~~~ flag is overridden by color
3789    ///
3790    /// assert!(m.get_flag("color"));
3791    /// assert!(m.get_flag("debug")); // even though flag conflicts with debug, it's as if flag
3792    ///                                 // was never used because it was overridden with color
3793    /// assert!(!m.get_flag("flag"));
3794    /// ```
3795    #[must_use]
3796    pub fn overrides_with(mut self, arg_id: impl IntoResettable<Id>) -> Self {
3797        if let Some(arg_id) = arg_id.into_resettable().into_option() {
3798            self.overrides.push(arg_id);
3799        } else {
3800            self.overrides.clear();
3801        }
3802        self
3803    }
3804
3805    /// Sets multiple mutually overridable arguments by name.
3806    ///
3807    /// i.e. this argument and the following argument will override each other in POSIX style
3808    /// (whichever argument was specified at runtime **last** "wins")
3809    ///
3810    /// **NOTE:** When an argument is overridden it is essentially as if it never was used, any
3811    /// conflicts, requirements, etc. are evaluated **after** all "overrides" have been removed
3812    ///
3813    /// **NOTE:** Overriding an argument implies they [conflict][Arg::conflicts_with_all`].
3814    ///
3815    /// # Examples
3816    ///
3817    /// ```rust
3818    /// # use clap_builder as clap;
3819    /// # use clap::{Command, arg};
3820    /// let m = Command::new("prog")
3821    ///     .arg(arg!(-f --flag "some flag")
3822    ///         .conflicts_with("color"))
3823    ///     .arg(arg!(-d --debug "other flag"))
3824    ///     .arg(arg!(-c --color "third flag")
3825    ///         .overrides_with_all(["flag", "debug"]))
3826    ///     .get_matches_from(vec![
3827    ///         "prog", "-f", "-d", "-c"]);
3828    ///             //    ^~~~~~^~~~~~~~~ flag and debug are overridden by color
3829    ///
3830    /// assert!(m.get_flag("color")); // even though flag conflicts with color, it's as if flag
3831    ///                                 // and debug were never used because they were overridden
3832    ///                                 // with color
3833    /// assert!(!m.get_flag("debug"));
3834    /// assert!(!m.get_flag("flag"));
3835    /// ```
3836    #[must_use]
3837    pub fn overrides_with_all(mut self, names: impl IntoIterator<Item = impl Into<Id>>) -> Self {
3838        self.overrides.extend(names.into_iter().map(Into::into));
3839        self
3840    }
3841}
3842
3843/// # Reflection
3844impl Arg {
3845    /// Get the name of the argument
3846    #[inline]
3847    pub fn get_id(&self) -> &Id {
3848        &self.id
3849    }
3850
3851    /// Get the help specified for this argument, if any
3852    #[inline]
3853    pub fn get_help(&self) -> Option<&StyledStr> {
3854        self.help.as_ref()
3855    }
3856
3857    /// Get the long help specified for this argument, if any
3858    ///
3859    /// # Examples
3860    ///
3861    /// ```rust
3862    /// # use clap_builder as clap;
3863    /// # use clap::Arg;
3864    /// let arg = Arg::new("foo").long_help("long help");
3865    /// assert_eq!(Some("long help".to_owned()), arg.get_long_help().map(|s| s.to_string()));
3866    /// ```
3867    ///
3868    #[inline]
3869    pub fn get_long_help(&self) -> Option<&StyledStr> {
3870        self.long_help.as_ref()
3871    }
3872
3873    /// Get the placement within help
3874    #[inline]
3875    pub fn get_display_order(&self) -> usize {
3876        self.disp_ord.unwrap_or(999)
3877    }
3878
3879    /// Get the help heading specified for this argument, if any
3880    #[inline]
3881    pub fn get_help_heading(&self) -> Option<&str> {
3882        self.help_heading
3883            .as_ref()
3884            .map(|s| s.as_deref())
3885            .unwrap_or_default()
3886    }
3887
3888    /// Get the short option name for this argument, if any
3889    #[inline]
3890    pub fn get_short(&self) -> Option<char> {
3891        self.short
3892    }
3893
3894    /// Get visible short aliases for this argument, if any
3895    #[inline]
3896    pub fn get_visible_short_aliases(&self) -> Option<Vec<char>> {
3897        if self.short_aliases.is_empty() {
3898            None
3899        } else {
3900            Some(
3901                self.short_aliases
3902                    .iter()
3903                    .filter_map(|(c, v)| if *v { Some(c) } else { None })
3904                    .copied()
3905                    .collect(),
3906            )
3907        }
3908    }
3909
3910    /// Get *all* short aliases for this argument, if any, both visible and hidden.
3911    #[inline]
3912    pub fn get_all_short_aliases(&self) -> Option<Vec<char>> {
3913        if self.short_aliases.is_empty() {
3914            None
3915        } else {
3916            Some(self.short_aliases.iter().map(|(s, _)| s).copied().collect())
3917        }
3918    }
3919
3920    /// Get the short option name and its visible aliases, if any
3921    #[inline]
3922    pub fn get_short_and_visible_aliases(&self) -> Option<Vec<char>> {
3923        let mut shorts = match self.short {
3924            Some(short) => vec![short],
3925            None => return None,
3926        };
3927        if let Some(aliases) = self.get_visible_short_aliases() {
3928            shorts.extend(aliases);
3929        }
3930        Some(shorts)
3931    }
3932
3933    /// Get the long option name for this argument, if any
3934    #[inline]
3935    pub fn get_long(&self) -> Option<&str> {
3936        self.long.as_deref()
3937    }
3938
3939    /// Get visible aliases for this argument, if any
3940    #[inline]
3941    pub fn get_visible_aliases(&self) -> Option<Vec<&str>> {
3942        if self.aliases.is_empty() {
3943            None
3944        } else {
3945            Some(
3946                self.aliases
3947                    .iter()
3948                    .filter_map(|(s, v)| if *v { Some(s.as_str()) } else { None })
3949                    .collect(),
3950            )
3951        }
3952    }
3953
3954    /// Get *all* aliases for this argument, if any, both visible and hidden.
3955    #[inline]
3956    pub fn get_all_aliases(&self) -> Option<Vec<&str>> {
3957        if self.aliases.is_empty() {
3958            None
3959        } else {
3960            Some(self.aliases.iter().map(|(s, _)| s.as_str()).collect())
3961        }
3962    }
3963
3964    /// Get the long option name and its visible aliases, if any
3965    #[inline]
3966    pub fn get_long_and_visible_aliases(&self) -> Option<Vec<&str>> {
3967        let mut longs = match self.get_long() {
3968            Some(long) => vec![long],
3969            None => return None,
3970        };
3971        if let Some(aliases) = self.get_visible_aliases() {
3972            longs.extend(aliases);
3973        }
3974        Some(longs)
3975    }
3976
3977    /// Get hidden aliases for this argument, if any
3978    #[inline]
3979    pub fn get_aliases(&self) -> Option<Vec<&str>> {
3980        if self.aliases.is_empty() {
3981            None
3982        } else {
3983            Some(
3984                self.aliases
3985                    .iter()
3986                    .filter_map(|(s, v)| if !*v { Some(s.as_str()) } else { None })
3987                    .collect(),
3988            )
3989        }
3990    }
3991
3992    /// Get the names of possible values for this argument. Only useful for user
3993    /// facing applications, such as building help messages or man files
3994    pub fn get_possible_values(&self) -> Vec<PossibleValue> {
3995        if !self.is_takes_value_set() {
3996            vec![]
3997        } else {
3998            self.get_value_parser()
3999                .possible_values()
4000                .map(|pvs| pvs.collect())
4001                .unwrap_or_default()
4002        }
4003    }
4004
4005    /// Get the names of values for this argument.
4006    #[inline]
4007    pub fn get_value_names(&self) -> Option<&[Str]> {
4008        if self.val_names.is_empty() {
4009            None
4010        } else {
4011            Some(&self.val_names)
4012        }
4013    }
4014
4015    /// Get the number of values for this argument.
4016    #[inline]
4017    pub fn get_num_args(&self) -> Option<ValueRange> {
4018        self.num_vals
4019    }
4020
4021    #[inline]
4022    pub(crate) fn get_min_vals(&self) -> usize {
4023        self.get_num_args().expect(INTERNAL_ERROR_MSG).min_values()
4024    }
4025
4026    /// Get the delimiter between multiple values
4027    #[inline]
4028    pub fn get_value_delimiter(&self) -> Option<char> {
4029        self.val_delim
4030    }
4031
4032    /// Get the value terminator for this argument. The `value_terminator` is a value
4033    /// that terminates parsing of multi-valued arguments.
4034    #[inline]
4035    pub fn get_value_terminator(&self) -> Option<&Str> {
4036        self.terminator.as_ref()
4037    }
4038
4039    /// Get the index of this argument, if any
4040    #[inline]
4041    pub fn get_index(&self) -> Option<usize> {
4042        self.index
4043    }
4044
4045    /// Get the value hint of this argument
4046    pub fn get_value_hint(&self) -> ValueHint {
4047        // HACK: we should use `Self::add` and `Self::remove` to type-check that `ArgExt` is used
4048        self.ext.get::<ValueHint>().copied().unwrap_or_else(|| {
4049            if self.is_takes_value_set() {
4050                let type_id = self.get_value_parser().type_id();
4051                if type_id == AnyValueId::of::<std::path::PathBuf>() {
4052                    ValueHint::AnyPath
4053                } else {
4054                    ValueHint::default()
4055                }
4056            } else {
4057                ValueHint::default()
4058            }
4059        })
4060    }
4061
4062    /// Get the environment variable name specified for this argument, if any
4063    ///
4064    /// # Examples
4065    ///
4066    /// ```rust
4067    /// # use clap_builder as clap;
4068    /// # use std::ffi::OsStr;
4069    /// # use clap::Arg;
4070    /// let arg = Arg::new("foo").env("ENVIRONMENT");
4071    /// assert_eq!(arg.get_env(), Some(OsStr::new("ENVIRONMENT")));
4072    /// ```
4073    #[cfg(feature = "env")]
4074    pub fn get_env(&self) -> Option<&std::ffi::OsStr> {
4075        self.env.as_ref().map(|x| x.0.as_os_str())
4076    }
4077
4078    /// Get the default values specified for this argument, if any
4079    ///
4080    /// # Examples
4081    ///
4082    /// ```rust
4083    /// # use clap_builder as clap;
4084    /// # use clap::Arg;
4085    /// let arg = Arg::new("foo").default_value("default value");
4086    /// assert_eq!(arg.get_default_values(), &["default value"]);
4087    /// ```
4088    pub fn get_default_values(&self) -> &[OsStr] {
4089        &self.default_vals
4090    }
4091
4092    /// Checks whether this argument is a positional or not.
4093    ///
4094    /// # Examples
4095    ///
4096    /// ```rust
4097    /// # use clap_builder as clap;
4098    /// # use clap::Arg;
4099    /// let arg = Arg::new("foo");
4100    /// assert_eq!(arg.is_positional(), true);
4101    ///
4102    /// let arg = Arg::new("foo").long("foo");
4103    /// assert_eq!(arg.is_positional(), false);
4104    /// ```
4105    pub fn is_positional(&self) -> bool {
4106        self.get_long().is_none() && self.get_short().is_none()
4107    }
4108
4109    /// Reports whether [`Arg::required`] is set
4110    pub fn is_required_set(&self) -> bool {
4111        self.is_set(ArgSettings::Required)
4112    }
4113
4114    pub(crate) fn is_multiple_values_set(&self) -> bool {
4115        self.get_num_args().unwrap_or_default().is_multiple()
4116    }
4117
4118    pub(crate) fn is_takes_value_set(&self) -> bool {
4119        self.get_num_args()
4120            .unwrap_or_else(|| 1.into())
4121            .takes_values()
4122    }
4123
4124    /// Report whether [`Arg::allow_hyphen_values`] is set
4125    pub fn is_allow_hyphen_values_set(&self) -> bool {
4126        self.is_set(ArgSettings::AllowHyphenValues)
4127    }
4128
4129    /// Report whether [`Arg::allow_negative_numbers`] is set
4130    pub fn is_allow_negative_numbers_set(&self) -> bool {
4131        self.is_set(ArgSettings::AllowNegativeNumbers)
4132    }
4133
4134    /// Behavior when parsing the argument
4135    pub fn get_action(&self) -> &ArgAction {
4136        const DEFAULT: ArgAction = ArgAction::Set;
4137        self.action.as_ref().unwrap_or(&DEFAULT)
4138    }
4139
4140    /// Configured parser for argument values
4141    ///
4142    /// # Example
4143    ///
4144    /// ```rust
4145    /// # use clap_builder as clap;
4146    /// let cmd = clap::Command::new("raw")
4147    ///     .arg(
4148    ///         clap::Arg::new("port")
4149    ///             .value_parser(clap::value_parser!(usize))
4150    ///     );
4151    /// let value_parser = cmd.get_arguments()
4152    ///     .find(|a| a.get_id() == "port").unwrap()
4153    ///     .get_value_parser();
4154    /// println!("{value_parser:?}");
4155    /// ```
4156    pub fn get_value_parser(&self) -> &super::ValueParser {
4157        if let Some(value_parser) = self.value_parser.as_ref() {
4158            value_parser
4159        } else {
4160            static DEFAULT: super::ValueParser = super::ValueParser::string();
4161            &DEFAULT
4162        }
4163    }
4164
4165    /// Report whether [`Arg::global`] is set
4166    pub fn is_global_set(&self) -> bool {
4167        self.is_set(ArgSettings::Global)
4168    }
4169
4170    /// Report whether [`Arg::next_line_help`] is set
4171    pub fn is_next_line_help_set(&self) -> bool {
4172        self.is_set(ArgSettings::NextLineHelp)
4173    }
4174
4175    /// Report whether [`Arg::hide`] is set
4176    pub fn is_hide_set(&self) -> bool {
4177        self.is_set(ArgSettings::Hidden)
4178    }
4179
4180    /// Report whether [`Arg::hide_default_value`] is set
4181    pub fn is_hide_default_value_set(&self) -> bool {
4182        self.is_set(ArgSettings::HideDefaultValue)
4183    }
4184
4185    /// Report whether [`Arg::hide_possible_values`] is set
4186    pub fn is_hide_possible_values_set(&self) -> bool {
4187        self.is_set(ArgSettings::HidePossibleValues)
4188    }
4189
4190    /// Report whether [`Arg::hide_env`] is set
4191    #[cfg(feature = "env")]
4192    pub fn is_hide_env_set(&self) -> bool {
4193        self.is_set(ArgSettings::HideEnv)
4194    }
4195
4196    /// Report whether [`Arg::hide_env_values`] is set
4197    #[cfg(feature = "env")]
4198    pub fn is_hide_env_values_set(&self) -> bool {
4199        self.is_set(ArgSettings::HideEnvValues)
4200    }
4201
4202    /// Report whether [`Arg::hide_short_help`] is set
4203    pub fn is_hide_short_help_set(&self) -> bool {
4204        self.is_set(ArgSettings::HiddenShortHelp)
4205    }
4206
4207    /// Report whether [`Arg::hide_long_help`] is set
4208    pub fn is_hide_long_help_set(&self) -> bool {
4209        self.is_set(ArgSettings::HiddenLongHelp)
4210    }
4211
4212    /// Report whether [`Arg::require_equals`] is set
4213    pub fn is_require_equals_set(&self) -> bool {
4214        self.is_set(ArgSettings::RequireEquals)
4215    }
4216
4217    /// Reports whether [`Arg::exclusive`] is set
4218    pub fn is_exclusive_set(&self) -> bool {
4219        self.is_set(ArgSettings::Exclusive)
4220    }
4221
4222    /// Report whether [`Arg::trailing_var_arg`] is set
4223    pub fn is_trailing_var_arg_set(&self) -> bool {
4224        self.is_set(ArgSettings::TrailingVarArg)
4225    }
4226
4227    /// Reports whether [`Arg::last`] is set
4228    pub fn is_last_set(&self) -> bool {
4229        self.is_set(ArgSettings::Last)
4230    }
4231
4232    /// Reports whether [`Arg::ignore_case`] is set
4233    pub fn is_ignore_case_set(&self) -> bool {
4234        self.is_set(ArgSettings::IgnoreCase)
4235    }
4236
4237    /// Access an [`ArgExt`]
4238    #[cfg(feature = "unstable-ext")]
4239    pub fn get<T: ArgExt + Extension>(&self) -> Option<&T> {
4240        self.ext.get::<T>()
4241    }
4242
4243    /// Remove an [`ArgExt`]
4244    #[cfg(feature = "unstable-ext")]
4245    pub fn remove<T: ArgExt + Extension>(mut self) -> Option<T> {
4246        self.ext.remove::<T>()
4247    }
4248}
4249
4250/// # Internally used only
4251impl Arg {
4252    pub(crate) fn _build(&mut self) {
4253        if self.action.is_none() {
4254            if self.num_vals == Some(ValueRange::EMPTY) {
4255                let action = ArgAction::SetTrue;
4256                self.action = Some(action);
4257            } else {
4258                let action =
4259                    if self.is_positional() && self.num_vals.unwrap_or_default().is_unbounded() {
4260                        // Allow collecting arguments interleaved with flags
4261                        //
4262                        // Bounded values are probably a group and the user should explicitly opt-in to
4263                        // Append
4264                        ArgAction::Append
4265                    } else {
4266                        ArgAction::Set
4267                    };
4268                self.action = Some(action);
4269            }
4270        }
4271        if let Some(action) = self.action.as_ref() {
4272            if let Some(default_value) = action.default_value() {
4273                if self.default_vals.is_empty() {
4274                    self.default_vals = vec![default_value.into()];
4275                }
4276            }
4277            if let Some(default_value) = action.default_missing_value() {
4278                if self.default_missing_vals.is_empty() {
4279                    self.default_missing_vals = vec![default_value.into()];
4280                }
4281            }
4282        }
4283
4284        if self.value_parser.is_none() {
4285            if let Some(default) = self.action.as_ref().and_then(|a| a.default_value_parser()) {
4286                self.value_parser = Some(default);
4287            } else {
4288                self.value_parser = Some(super::ValueParser::string());
4289            }
4290        }
4291
4292        let val_names_len = self.val_names.len();
4293        if val_names_len > 1 {
4294            self.num_vals.get_or_insert(val_names_len.into());
4295        } else {
4296            let nargs = if self.get_action().takes_values() {
4297                ValueRange::SINGLE
4298            } else {
4299                ValueRange::EMPTY
4300            };
4301            self.num_vals.get_or_insert(nargs);
4302        }
4303    }
4304
4305    // Used for positionals when printing
4306    pub(crate) fn name_no_brackets(&self) -> String {
4307        debug!("Arg::name_no_brackets:{}", self.get_id());
4308        let delim = " ";
4309        if !self.val_names.is_empty() {
4310            debug!("Arg::name_no_brackets: val_names={:#?}", self.val_names);
4311
4312            if self.val_names.len() > 1 {
4313                self.val_names
4314                    .iter()
4315                    .map(|n| format!("<{n}>"))
4316                    .collect::<Vec<_>>()
4317                    .join(delim)
4318            } else {
4319                self.val_names
4320                    .first()
4321                    .expect(INTERNAL_ERROR_MSG)
4322                    .as_str()
4323                    .to_owned()
4324            }
4325        } else {
4326            debug!("Arg::name_no_brackets: just name");
4327            self.get_id().as_str().to_owned()
4328        }
4329    }
4330
4331    pub(crate) fn stylized(&self, styles: &Styles, required: Option<bool>) -> StyledStr {
4332        use std::fmt::Write as _;
4333        let literal = styles.get_literal();
4334
4335        let mut styled = StyledStr::new();
4336        // Write the name such --long or -l
4337        if let Some(l) = self.get_long() {
4338            let _ = write!(styled, "{literal}--{l}{literal:#}",);
4339        } else if let Some(s) = self.get_short() {
4340            let _ = write!(styled, "{literal}-{s}{literal:#}");
4341        }
4342        styled.push_styled(&self.stylize_arg_suffix(styles, required));
4343        styled
4344    }
4345
4346    pub(crate) fn stylize_arg_suffix(&self, styles: &Styles, required: Option<bool>) -> StyledStr {
4347        use std::fmt::Write as _;
4348        let literal = styles.get_literal();
4349        let placeholder = styles.get_placeholder();
4350        let mut styled = StyledStr::new();
4351
4352        let mut need_closing_bracket = false;
4353        if self.is_takes_value_set() && !self.is_positional() {
4354            let is_optional_val = self.get_min_vals() == 0;
4355            let (style, start) = if self.is_require_equals_set() {
4356                if is_optional_val {
4357                    need_closing_bracket = true;
4358                    (placeholder, "[=")
4359                } else {
4360                    (literal, "=")
4361                }
4362            } else if is_optional_val {
4363                need_closing_bracket = true;
4364                (placeholder, " [")
4365            } else {
4366                (placeholder, " ")
4367            };
4368            let _ = write!(styled, "{style}{start}{style:#}");
4369        }
4370        if self.is_takes_value_set() || self.is_positional() {
4371            let required = required.unwrap_or_else(|| self.is_required_set());
4372            let arg_val = self.render_arg_val(required);
4373            let _ = write!(styled, "{placeholder}{arg_val}{placeholder:#}",);
4374        } else if matches!(*self.get_action(), ArgAction::Count) {
4375            let _ = write!(styled, "{placeholder}...{placeholder:#}",);
4376        }
4377        if need_closing_bracket {
4378            let _ = write!(styled, "{placeholder}]{placeholder:#}",);
4379        }
4380
4381        styled
4382    }
4383
4384    /// Write the values such as `<name1> <name2>`
4385    fn render_arg_val(&self, required: bool) -> String {
4386        let mut rendered = String::new();
4387
4388        let num_vals = self.get_num_args().unwrap_or_else(|| 1.into());
4389
4390        let mut val_names = if self.val_names.is_empty() {
4391            vec![self.id.as_internal_str().to_owned()]
4392        } else {
4393            self.val_names.clone()
4394        };
4395        if val_names.len() == 1 {
4396            let min = num_vals.min_values().max(1);
4397            let val_name = val_names.pop().unwrap();
4398            val_names = vec![val_name; min];
4399        }
4400
4401        debug_assert!(self.is_takes_value_set());
4402        for (n, val_name) in val_names.iter().enumerate() {
4403            let arg_name = if self.is_positional() && (num_vals.min_values() == 0 || !required) {
4404                format!("[{val_name}]")
4405            } else {
4406                format!("<{val_name}>")
4407            };
4408
4409            if n != 0 {
4410                rendered.push(' ');
4411            }
4412            rendered.push_str(&arg_name);
4413        }
4414
4415        let mut extra_values = false;
4416        extra_values |= val_names.len() < num_vals.max_values();
4417        if self.is_positional() && matches!(*self.get_action(), ArgAction::Append) {
4418            extra_values = true;
4419        }
4420        if extra_values {
4421            rendered.push_str("...");
4422        }
4423
4424        rendered
4425    }
4426
4427    /// Either multiple values or occurrences
4428    pub(crate) fn is_multiple(&self) -> bool {
4429        self.is_multiple_values_set() || matches!(*self.get_action(), ArgAction::Append)
4430    }
4431}
4432
4433impl From<&'_ Arg> for Arg {
4434    fn from(a: &Arg) -> Self {
4435        a.clone()
4436    }
4437}
4438
4439impl PartialEq for Arg {
4440    fn eq(&self, other: &Arg) -> bool {
4441        self.get_id() == other.get_id()
4442    }
4443}
4444
4445impl PartialOrd for Arg {
4446    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
4447        Some(self.cmp(other))
4448    }
4449}
4450
4451impl Ord for Arg {
4452    fn cmp(&self, other: &Arg) -> Ordering {
4453        self.get_id().cmp(other.get_id())
4454    }
4455}
4456
4457impl Eq for Arg {}
4458
4459impl Display for Arg {
4460    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
4461        let plain = Styles::plain();
4462        self.stylized(&plain, None).fmt(f)
4463    }
4464}
4465
4466impl fmt::Debug for Arg {
4467    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
4468        let mut ds = f.debug_struct("Arg");
4469
4470        #[allow(unused_mut)]
4471        let mut ds = ds
4472            .field("id", &self.id)
4473            .field("help", &self.help)
4474            .field("long_help", &self.long_help)
4475            .field("action", &self.action)
4476            .field("value_parser", &self.value_parser)
4477            .field("blacklist", &self.blacklist)
4478            .field("settings", &self.settings)
4479            .field("overrides", &self.overrides)
4480            .field("groups", &self.groups)
4481            .field("requires", &self.requires)
4482            .field("r_ifs", &self.r_ifs)
4483            .field("r_unless", &self.r_unless)
4484            .field("short", &self.short)
4485            .field("long", &self.long)
4486            .field("aliases", &self.aliases)
4487            .field("short_aliases", &self.short_aliases)
4488            .field("disp_ord", &self.disp_ord)
4489            .field("val_names", &self.val_names)
4490            .field("num_vals", &self.num_vals)
4491            .field("val_delim", &self.val_delim)
4492            .field("default_vals", &self.default_vals)
4493            .field("default_vals_ifs", &self.default_vals_ifs)
4494            .field("terminator", &self.terminator)
4495            .field("index", &self.index)
4496            .field("help_heading", &self.help_heading)
4497            .field("default_missing_vals", &self.default_missing_vals)
4498            .field("ext", &self.ext);
4499
4500        #[cfg(feature = "env")]
4501        {
4502            ds = ds.field("env", &self.env);
4503        }
4504
4505        ds.finish()
4506    }
4507}
4508
4509/// User-provided data that can be attached to an [`Arg`]
4510#[cfg(feature = "unstable-ext")]
4511pub trait ArgExt: Extension {}
4512
4513// Flags
4514#[cfg(test)]
4515mod test {
4516    use super::Arg;
4517    use super::ArgAction;
4518
4519    #[test]
4520    fn flag_display_long() {
4521        let mut f = Arg::new("flg").long("flag").action(ArgAction::SetTrue);
4522        f._build();
4523
4524        assert_eq!(f.to_string(), "--flag");
4525    }
4526
4527    #[test]
4528    fn flag_display_short() {
4529        let mut f2 = Arg::new("flg").short('f').action(ArgAction::SetTrue);
4530        f2._build();
4531
4532        assert_eq!(f2.to_string(), "-f");
4533    }
4534
4535    #[test]
4536    fn flag_display_count() {
4537        let mut f2 = Arg::new("flg").long("flag").action(ArgAction::Count);
4538        f2._build();
4539
4540        assert_eq!(f2.to_string(), "--flag...");
4541    }
4542
4543    #[test]
4544    fn flag_display_single_alias() {
4545        let mut f = Arg::new("flg")
4546            .long("flag")
4547            .visible_alias("als")
4548            .action(ArgAction::SetTrue);
4549        f._build();
4550
4551        assert_eq!(f.to_string(), "--flag");
4552    }
4553
4554    #[test]
4555    fn flag_display_multiple_aliases() {
4556        let mut f = Arg::new("flg").short('f').action(ArgAction::SetTrue);
4557        f.aliases = vec![
4558            ("alias_not_visible".into(), false),
4559            ("f2".into(), true),
4560            ("f3".into(), true),
4561            ("f4".into(), true),
4562        ];
4563        f._build();
4564
4565        assert_eq!(f.to_string(), "-f");
4566    }
4567
4568    #[test]
4569    fn flag_display_single_short_alias() {
4570        let mut f = Arg::new("flg").short('a').action(ArgAction::SetTrue);
4571        f.short_aliases = vec![('b', true)];
4572        f._build();
4573
4574        assert_eq!(f.to_string(), "-a");
4575    }
4576
4577    #[test]
4578    fn flag_display_multiple_short_aliases() {
4579        let mut f = Arg::new("flg").short('a').action(ArgAction::SetTrue);
4580        f.short_aliases = vec![('b', false), ('c', true), ('d', true), ('e', true)];
4581        f._build();
4582
4583        assert_eq!(f.to_string(), "-a");
4584    }
4585
4586    // Options
4587
4588    #[test]
4589    fn option_display_multiple_occurrences() {
4590        let mut o = Arg::new("opt").long("option").action(ArgAction::Append);
4591        o._build();
4592
4593        assert_eq!(o.to_string(), "--option <opt>");
4594    }
4595
4596    #[test]
4597    fn option_display_multiple_values() {
4598        let mut o = Arg::new("opt")
4599            .long("option")
4600            .action(ArgAction::Set)
4601            .num_args(1..);
4602        o._build();
4603
4604        assert_eq!(o.to_string(), "--option <opt>...");
4605    }
4606
4607    #[test]
4608    fn option_display_zero_or_more_values() {
4609        let mut o = Arg::new("opt")
4610            .long("option")
4611            .action(ArgAction::Set)
4612            .num_args(0..);
4613        o._build();
4614
4615        assert_eq!(o.to_string(), "--option [<opt>...]");
4616    }
4617
4618    #[test]
4619    fn option_display_one_or_more_values() {
4620        let mut o = Arg::new("opt")
4621            .long("option")
4622            .action(ArgAction::Set)
4623            .num_args(1..);
4624        o._build();
4625
4626        assert_eq!(o.to_string(), "--option <opt>...");
4627    }
4628
4629    #[test]
4630    fn option_display_zero_or_more_values_with_value_name() {
4631        let mut o = Arg::new("opt")
4632            .short('o')
4633            .action(ArgAction::Set)
4634            .num_args(0..)
4635            .value_names(["file"]);
4636        o._build();
4637
4638        assert_eq!(o.to_string(), "-o [<file>...]");
4639    }
4640
4641    #[test]
4642    fn option_display_one_or_more_values_with_value_name() {
4643        let mut o = Arg::new("opt")
4644            .short('o')
4645            .action(ArgAction::Set)
4646            .num_args(1..)
4647            .value_names(["file"]);
4648        o._build();
4649
4650        assert_eq!(o.to_string(), "-o <file>...");
4651    }
4652
4653    #[test]
4654    fn option_display_optional_value() {
4655        let mut o = Arg::new("opt")
4656            .long("option")
4657            .action(ArgAction::Set)
4658            .num_args(0..=1);
4659        o._build();
4660
4661        assert_eq!(o.to_string(), "--option [<opt>]");
4662    }
4663
4664    #[test]
4665    fn option_display_value_names() {
4666        let mut o = Arg::new("opt")
4667            .short('o')
4668            .action(ArgAction::Set)
4669            .value_names(["file", "name"]);
4670        o._build();
4671
4672        assert_eq!(o.to_string(), "-o <file> <name>");
4673    }
4674
4675    #[test]
4676    fn option_display3() {
4677        let mut o = Arg::new("opt")
4678            .short('o')
4679            .num_args(1..)
4680            .action(ArgAction::Set)
4681            .value_names(["file", "name"]);
4682        o._build();
4683
4684        assert_eq!(o.to_string(), "-o <file> <name>...");
4685    }
4686
4687    #[test]
4688    fn option_display_single_alias() {
4689        let mut o = Arg::new("opt")
4690            .long("option")
4691            .action(ArgAction::Set)
4692            .visible_alias("als");
4693        o._build();
4694
4695        assert_eq!(o.to_string(), "--option <opt>");
4696    }
4697
4698    #[test]
4699    fn option_display_multiple_aliases() {
4700        let mut o = Arg::new("opt")
4701            .long("option")
4702            .action(ArgAction::Set)
4703            .visible_aliases(["als2", "als3", "als4"])
4704            .alias("als_not_visible");
4705        o._build();
4706
4707        assert_eq!(o.to_string(), "--option <opt>");
4708    }
4709
4710    #[test]
4711    fn option_display_single_short_alias() {
4712        let mut o = Arg::new("opt")
4713            .short('a')
4714            .action(ArgAction::Set)
4715            .visible_short_alias('b');
4716        o._build();
4717
4718        assert_eq!(o.to_string(), "-a <opt>");
4719    }
4720
4721    #[test]
4722    fn option_display_multiple_short_aliases() {
4723        let mut o = Arg::new("opt")
4724            .short('a')
4725            .action(ArgAction::Set)
4726            .visible_short_aliases(['b', 'c', 'd'])
4727            .short_alias('e');
4728        o._build();
4729
4730        assert_eq!(o.to_string(), "-a <opt>");
4731    }
4732
4733    // Positionals
4734
4735    #[test]
4736    fn positional_display_multiple_values() {
4737        let mut p = Arg::new("pos").index(1).num_args(1..);
4738        p._build();
4739
4740        assert_eq!(p.to_string(), "[pos]...");
4741    }
4742
4743    #[test]
4744    fn positional_display_multiple_values_required() {
4745        let mut p = Arg::new("pos").index(1).num_args(1..).required(true);
4746        p._build();
4747
4748        assert_eq!(p.to_string(), "<pos>...");
4749    }
4750
4751    #[test]
4752    fn positional_display_zero_or_more_values() {
4753        let mut p = Arg::new("pos").index(1).num_args(0..);
4754        p._build();
4755
4756        assert_eq!(p.to_string(), "[pos]...");
4757    }
4758
4759    #[test]
4760    fn positional_display_one_or_more_values() {
4761        let mut p = Arg::new("pos").index(1).num_args(1..);
4762        p._build();
4763
4764        assert_eq!(p.to_string(), "[pos]...");
4765    }
4766
4767    #[test]
4768    fn positional_display_one_or_more_values_required() {
4769        let mut p = Arg::new("pos").index(1).num_args(1..).required(true);
4770        p._build();
4771
4772        assert_eq!(p.to_string(), "<pos>...");
4773    }
4774
4775    #[test]
4776    fn positional_display_optional_value() {
4777        let mut p = Arg::new("pos")
4778            .index(1)
4779            .num_args(0..=1)
4780            .action(ArgAction::Set);
4781        p._build();
4782
4783        assert_eq!(p.to_string(), "[pos]");
4784    }
4785
4786    #[test]
4787    fn positional_display_multiple_occurrences() {
4788        let mut p = Arg::new("pos").index(1).action(ArgAction::Append);
4789        p._build();
4790
4791        assert_eq!(p.to_string(), "[pos]...");
4792    }
4793
4794    #[test]
4795    fn positional_display_multiple_occurrences_required() {
4796        let mut p = Arg::new("pos")
4797            .index(1)
4798            .action(ArgAction::Append)
4799            .required(true);
4800        p._build();
4801
4802        assert_eq!(p.to_string(), "<pos>...");
4803    }
4804
4805    #[test]
4806    fn positional_display_required() {
4807        let mut p = Arg::new("pos").index(1).required(true);
4808        p._build();
4809
4810        assert_eq!(p.to_string(), "<pos>");
4811    }
4812
4813    #[test]
4814    fn positional_display_val_names() {
4815        let mut p = Arg::new("pos").index(1).value_names(["file1", "file2"]);
4816        p._build();
4817
4818        assert_eq!(p.to_string(), "[file1] [file2]");
4819    }
4820
4821    #[test]
4822    fn positional_display_val_names_required() {
4823        let mut p = Arg::new("pos")
4824            .index(1)
4825            .value_names(["file1", "file2"])
4826            .required(true);
4827        p._build();
4828
4829        assert_eq!(p.to_string(), "<file1> <file2>");
4830    }
4831}