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