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