4 use std
::ffi
::{OsStr, OsString}
;
5 use std
::fmt
::{Debug, Display}
;
6 use std
::iter
::{Cloned, Flatten, Map}
;
11 use indexmap
::IndexMap
;
14 use crate::parser
::AnyValue
;
15 use crate::parser
::AnyValueId
;
16 use crate::parser
::MatchedArg
;
17 use crate::parser
::MatchesError
;
18 use crate::parser
::ValueSource
;
19 use crate::util
::{Id, Key}
;
21 use crate::INTERNAL_ERROR_MSG
;
23 /// Container for parse results.
25 /// Used to get information about the arguments that were supplied to the program at runtime by
26 /// the user. New instances of this struct are obtained by using the [`Command::get_matches`] family of
32 /// # use clap::{Command, Arg, ValueSource};
33 /// let matches = Command::new("MyApp")
34 /// .arg(Arg::new("out")
37 /// .takes_value(true)
38 /// .default_value("-"))
39 /// .arg(Arg::new("cfg")
41 /// .takes_value(true))
42 /// .get_matches(); // builds the instance of ArgMatches
44 /// // to get information about the "cfg" argument we created, such as the value supplied we use
45 /// // various ArgMatches methods, such as [ArgMatches::get_one]
46 /// if let Some(c) = matches.get_one::<String>("cfg") {
47 /// println!("Value for -c: {}", c);
50 /// // The ArgMatches::get_one method returns an Option because the user may not have supplied
51 /// // that argument at runtime. But if we specified that the argument was "required" as we did
52 /// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually
53 /// // used at runtime.
54 /// println!("Value for --output: {}", matches.get_one::<String>("out").unwrap());
56 /// // You can check the presence of an argument's values
57 /// if matches.contains_id("out") {
58 /// // However, if you want to know where the value came from
59 /// if matches.value_source("out").expect("checked contains_id") == ValueSource::CommandLine {
60 /// println!("`out` set by user");
62 /// println!("`out` is defaulted");
66 /// [`Command::get_matches`]: crate::Command::get_matches()
67 #[derive(Debug, Clone, Default, PartialEq, Eq)]
68 pub struct ArgMatches
{
69 #[cfg(debug_assertions)]
70 pub(crate) valid_args
: Vec
<Id
>,
71 #[cfg(debug_assertions)]
72 pub(crate) valid_subcommands
: Vec
<Id
>,
73 #[cfg(debug_assertions)]
74 pub(crate) disable_asserts
: bool
,
75 pub(crate) args
: IndexMap
<Id
, MatchedArg
>,
76 pub(crate) subcommand
: Option
<Box
<SubCommand
>>,
81 /// Gets the value of a specific option or positional argument.
83 /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime.
85 /// Returns an error if the wrong type was used.
87 /// Returns `None` if the option wasn't present.
89 /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
90 /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
94 /// If the argument definition and access mismatch. To handle this case programmatically, see
95 /// [`ArgMatches::try_get_one`].
100 /// # use clap::{Command, Arg, value_parser};
101 /// let m = Command::new("myapp")
102 /// .arg(Arg::new("port")
103 /// .value_parser(value_parser!(usize))
104 /// .takes_value(true)
106 /// .get_matches_from(vec!["myapp", "2020"]);
108 /// let port: usize = *m
110 /// .expect("`port`is required");
111 /// assert_eq!(port, 2020);
113 /// [option]: crate::Arg::takes_value()
114 /// [positional]: crate::Arg::index()
115 /// [`default_value`]: crate::Arg::default_value()
117 pub fn get_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(&self, id
: &str) -> Option
<&T
> {
118 let internal_id
= Id
::from(id
);
119 MatchesError
::unwrap(&internal_id
, self.try_get_one(id
))
122 /// Gets the value of a specific [`ArgAction::Count`][crate::ArgAction::Count] flag
126 /// If the argument's action is not [`ArgAction::Count`][crate::ArgAction::Count]
131 /// # use clap::Command;
133 /// let cmd = Command::new("mycmd")
137 /// .action(clap::ArgAction::Count)
140 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
142 /// matches.get_count("flag"),
147 pub fn get_count(&self, id
: &str) -> u8 {
150 .expect("ArgAction::Count is defaulted")
153 /// Gets the value of a specific [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] flag
157 /// If the argument's action is not [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse]
162 /// # use clap::Command;
164 /// let cmd = Command::new("mycmd")
168 /// .action(clap::ArgAction::SetTrue)
171 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
172 /// assert!(matches.contains_id("flag"));
174 /// matches.get_flag("flag"),
179 pub fn get_flag(&self, id
: &str) -> bool
{
182 .expect("ArgAction::SetTrue / ArgAction::SetFalse is defaulted")
185 /// Iterate over values of a specific option or positional argument.
187 /// i.e. an argument that takes multiple values at runtime.
189 /// Returns an error if the wrong type was used.
191 /// Returns `None` if the option wasn't present.
195 /// If the argument definition and access mismatch. To handle this case programmatically, see
196 /// [`ArgMatches::try_get_many`].
201 /// # use clap::{Command, Arg, value_parser, ArgAction};
202 /// let m = Command::new("myprog")
203 /// .arg(Arg::new("ports")
204 /// .action(ArgAction::Append)
205 /// .value_parser(value_parser!(usize))
207 /// .takes_value(true)
209 /// .get_matches_from(vec![
210 /// "myprog", "-p", "22", "-p", "80", "-p", "2020"
212 /// let vals: Vec<usize> = m.get_many("ports")
213 /// .expect("`port`is required")
216 /// assert_eq!(vals, [22, 80, 2020]);
219 pub fn get_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
222 ) -> Option
<ValuesRef
<T
>> {
223 let internal_id
= Id
::from(id
);
224 MatchesError
::unwrap(&internal_id
, self.try_get_many(id
))
227 /// Iterate over the original argument values.
229 /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
230 /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
231 /// filename on a Unix system as an argument value may contain invalid UTF-8.
233 /// Returns `None` if the option wasn't present.
237 /// If the argument definition and access mismatch. To handle this case programmatically, see
238 /// [`ArgMatches::try_get_raw`].
242 #[cfg_attr(not(unix), doc = " ```ignore")]
243 #[cfg_attr(unix, doc = " ```")]
244 /// # use clap::{Command, arg, value_parser};
245 /// # use std::ffi::{OsStr,OsString};
246 /// # use std::os::unix::ffi::{OsStrExt,OsStringExt};
247 /// use std::path::PathBuf;
249 /// let m = Command::new("utf8")
250 /// .arg(arg!(<arg> ... "some arg").value_parser(value_parser!(PathBuf)))
251 /// .get_matches_from(vec![OsString::from("myprog"),
253 /// OsString::from_vec(vec![b'H', b'i']),
255 /// OsString::from_vec(vec![0xe9, b'!'])]);
257 /// let mut itr = m.get_raw("arg")
258 /// .expect("`port`is required")
260 /// assert_eq!(itr.next(), Some(OsStr::new("Hi")));
261 /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!'])));
262 /// assert_eq!(itr.next(), None);
264 /// [`Iterator`]: std::iter::Iterator
265 /// [`OsSt`]: std::ffi::OsStr
266 /// [values]: OsValues
267 /// [`String`]: std::string::String
269 pub fn get_raw(&self, id
: &str) -> Option
<RawValues
<'_
>> {
270 let internal_id
= Id
::from(id
);
271 MatchesError
::unwrap(&internal_id
, self.try_get_raw(id
))
274 /// Returns the value of a specific option or positional argument.
276 /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime.
278 /// Returns an error if the wrong type was used. No item will have been removed.
280 /// Returns `None` if the option wasn't present.
282 /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
283 /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
287 /// If the argument definition and access mismatch. To handle this case programmatically, see
288 /// [`ArgMatches::try_remove_one`].
293 /// # use clap::{Command, Arg, value_parser};
294 /// let mut m = Command::new("myprog")
295 /// .arg(Arg::new("file")
297 /// .takes_value(true))
298 /// .get_matches_from(vec![
299 /// "myprog", "file.txt",
301 /// let vals: String = m.remove_one("file")
302 /// .expect("`file`is required");
303 /// assert_eq!(vals, "file.txt");
305 /// [option]: crate::Arg::takes_value()
306 /// [positional]: crate::Arg::index()
307 /// [`default_value`]: crate::Arg::default_value()
309 pub fn remove_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(&mut self, id
: &str) -> Option
<T
> {
310 let internal_id
= Id
::from(id
);
311 MatchesError
::unwrap(&internal_id
, self.try_remove_one(id
))
314 /// Return values of a specific option or positional argument.
316 /// i.e. an argument that takes multiple values at runtime.
318 /// Returns an error if the wrong type was used. No item will have been removed.
320 /// Returns `None` if the option wasn't present.
324 /// If the argument definition and access mismatch. To handle this case programmatically, see
325 /// [`ArgMatches::try_remove_many`].
330 /// # use clap::{Command, Arg, value_parser, ArgAction};
331 /// let mut m = Command::new("myprog")
332 /// .arg(Arg::new("file")
333 /// .action(ArgAction::Append)
334 /// .multiple_values(true)
336 /// .takes_value(true))
337 /// .get_matches_from(vec![
338 /// "myprog", "file1.txt", "file2.txt", "file3.txt", "file4.txt",
340 /// let vals: Vec<String> = m.remove_many("file")
341 /// .expect("`file`is required")
343 /// assert_eq!(vals, ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]);
346 pub fn remove_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
349 ) -> Option
<Values2
<T
>> {
350 let internal_id
= Id
::from(id
);
351 MatchesError
::unwrap(&internal_id
, self.try_remove_many(id
))
354 /// Check if values are present for the argument or group id
356 /// *NOTE:* This will always return `true` if [`default_value`] has been set.
357 /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
361 /// If `id` is is not a valid argument or group name. To handle this case programmatically, see
362 /// [`ArgMatches::try_contains_id`].
367 /// # use clap::{Command, Arg};
368 /// let m = Command::new("myprog")
369 /// .arg(Arg::new("debug")
371 /// .get_matches_from(vec![
375 /// assert!(m.contains_id("debug"));
378 /// [`default_value`]: crate::Arg::default_value()
379 pub fn contains_id(&self, id
: &str) -> bool
{
380 let internal_id
= Id
::from(id
);
381 MatchesError
::unwrap(&internal_id
, self.try_contains_id(id
))
384 /// Check if any args were present on the command line
389 /// # use clap::{Command, Arg};
390 /// let mut cmd = Command::new("myapp")
391 /// .arg(Arg::new("output")
392 /// .takes_value(true));
395 /// .try_get_matches_from_mut(vec!["myapp", "something"])
397 /// assert!(m.args_present());
400 /// .try_get_matches_from_mut(vec!["myapp"])
402 /// assert!(! m.args_present());
403 pub fn args_present(&self) -> bool
{
404 !self.args
.is_empty()
407 /// Deprecated, replaced with [`ArgMatches::get_one()`]
409 feature
= "deprecated",
410 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_one()`")
412 #[cfg_attr(debug_assertions, track_caller)]
413 pub fn value_of
<T
: Key
>(&self, id
: T
) -> Option
<&str> {
414 let id
= Id
::from(id
);
415 let arg
= self.get_arg(&id
)?
;
416 let v
= unwrap_string_arg(&id
, arg
.first()?
);
420 /// Deprecated, replaced with [`ArgMatches::get_one()`]
422 feature
= "deprecated",
423 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_one()`")
425 #[cfg_attr(debug_assertions, track_caller)]
426 pub fn value_of_lossy
<T
: Key
>(&self, id
: T
) -> Option
<Cow
<'_
, str>> {
427 let id
= Id
::from(id
);
428 let arg
= self.get_arg(&id
)?
;
429 let v
= unwrap_os_string_arg(&id
, arg
.first()?
);
430 Some(v
.to_string_lossy())
433 /// Deprecated, replaced with [`ArgMatches::get_one()`]
435 feature
= "deprecated",
436 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_one()`")
438 #[cfg_attr(debug_assertions, track_caller)]
439 pub fn value_of_os
<T
: Key
>(&self, id
: T
) -> Option
<&OsStr
> {
440 let id
= Id
::from(id
);
441 let arg
= self.get_arg(&id
)?
;
442 let v
= unwrap_os_string_arg(&id
, arg
.first()?
);
446 /// Deprecated, replaced with [`ArgMatches::get_many()`]
448 feature
= "deprecated",
449 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
451 #[cfg_attr(debug_assertions, track_caller)]
452 pub fn values_of
<T
: Key
>(&self, id
: T
) -> Option
<Values
> {
453 #![allow(deprecated)]
454 let id
= Id
::from(id
);
455 let arg
= self.get_arg(&id
)?
;
457 iter
: arg
.vals_flatten().map(unwrap_string
),
463 /// Get an [`Iterator`] over groups of values of a specific option.
465 /// specifically grouped by the occurrences of the options.
467 /// Each group is a `Vec<&str>` containing the arguments passed to a single occurrence
470 /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
471 /// the iterator will only contain a single item.
473 /// Returns `None` if the option wasn't present.
477 /// If the value is invalid UTF-8.
479 /// If `id` is not a valid argument or group id.
483 /// # use clap::{Command,Arg, ArgAction};
484 /// let m = Command::new("myprog")
485 /// .arg(Arg::new("exec")
488 /// .action(ArgAction::Append)
489 /// .value_terminator(";"))
490 /// .get_matches_from(vec![
491 /// "myprog", "-x", "echo", "hi", ";", "-x", "echo", "bye"]);
492 /// let vals: Vec<Vec<&str>> = m.grouped_values_of("exec").unwrap().collect();
493 /// assert_eq!(vals, [["echo", "hi"], ["echo", "bye"]]);
495 /// [`Iterator`]: std::iter::Iterator
496 #[cfg(feature = "unstable-grouped")]
497 #[cfg_attr(debug_assertions, track_caller)]
498 pub fn grouped_values_of
<T
: Key
>(&self, id
: T
) -> Option
<GroupedValues
> {
499 let id
= Id
::from(id
);
500 let arg
= self.get_arg(&id
)?
;
501 let v
= GroupedValues
{
502 iter
: arg
.vals().map(|g
| g
.iter().map(unwrap_string
).collect()),
503 len
: arg
.vals().len(),
508 /// Deprecated, replaced with [`ArgMatches::get_many()`]
510 feature
= "deprecated",
511 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
513 #[cfg_attr(debug_assertions, track_caller)]
514 pub fn values_of_lossy
<T
: Key
>(&self, id
: T
) -> Option
<Vec
<String
>> {
515 let id
= Id
::from(id
);
516 let arg
= self.get_arg(&id
)?
;
519 .map(|v
| unwrap_os_string_arg(&id
, v
).to_string_lossy().into_owned())
524 /// Deprecated, replaced with [`ArgMatches::get_many()`]
526 feature
= "deprecated",
527 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
529 #[cfg_attr(debug_assertions, track_caller)]
530 pub fn values_of_os
<T
: Key
>(&self, id
: T
) -> Option
<OsValues
> {
531 #![allow(deprecated)]
532 let id
= Id
::from(id
);
533 let arg
= self.get_arg(&id
)?
;
535 iter
: arg
.vals_flatten().map(unwrap_os_string
),
541 /// Deprecated, replaced with [`ArgMatches::get_one()`]
543 feature
= "deprecated",
544 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_one()`")
546 #[cfg_attr(debug_assertions, track_caller)]
547 pub fn value_of_t
<R
>(&self, name
: &str) -> Result
<R
, Error
>
550 <R
as FromStr
>::Err
: Display
,
552 #![allow(deprecated)]
555 .ok_or_else(|| Error
::argument_not_found_auto(name
.to_string()))?
;
556 v
.parse
::<R
>().map_err(|e
| {
557 let message
= format
!(
558 "The argument '{}' isn't a valid value for '{}': {}",
562 Error
::value_validation(name
.to_string(), v
.to_string(), message
.into())
566 /// Deprecated, replaced with [`ArgMatches::get_one()`]
568 feature
= "deprecated",
569 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_one()`")
571 #[cfg_attr(debug_assertions, track_caller)]
572 pub fn value_of_t_or_exit
<R
>(&self, name
: &str) -> R
575 <R
as FromStr
>::Err
: Display
,
577 #![allow(deprecated)]
578 self.value_of_t(name
).unwrap_or_else(|e
| e
.exit())
581 /// Deprecated, replaced with [`ArgMatches::get_many()`]
583 feature
= "deprecated",
584 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
586 #[cfg_attr(debug_assertions, track_caller)]
587 pub fn values_of_t
<R
>(&self, name
: &str) -> Result
<Vec
<R
>, Error
>
590 <R
as FromStr
>::Err
: Display
,
592 #![allow(deprecated)]
595 .ok_or_else(|| Error
::argument_not_found_auto(name
.to_string()))?
;
597 v
.parse
::<R
>().map_err(|e
| {
598 let message
= format
!("The argument '{}' isn't a valid value: {}", v
, e
);
600 Error
::value_validation(name
.to_string(), v
.to_string(), message
.into())
606 /// Deprecated, replaced with [`ArgMatches::get_many()`]
608 feature
= "deprecated",
609 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
611 #[cfg_attr(debug_assertions, track_caller)]
612 pub fn values_of_t_or_exit
<R
>(&self, name
: &str) -> Vec
<R
>
615 <R
as FromStr
>::Err
: Display
,
617 #![allow(deprecated)]
618 self.values_of_t(name
).unwrap_or_else(|e
| e
.exit())
621 /// Deprecated, replaced with [`ArgAction::SetTrue`][crate::ArgAction] or
622 /// [`ArgMatches::contains_id`].
624 feature
= "deprecated",
627 note
= "Replaced with either `ArgAction::SetTrue` or `ArgMatches::contains_id(...)`"
630 #[cfg_attr(debug_assertions, track_caller)]
631 pub fn is_present
<T
: Key
>(&self, id
: T
) -> bool
{
632 let id
= Id
::from(id
);
634 #[cfg(debug_assertions)]
637 self.args
.contains_key(&id
)
640 /// Report where argument value came from
644 /// If `id` is is not a valid argument or group id.
649 /// # use clap::{Command, Arg, ValueSource};
650 /// let m = Command::new("myprog")
651 /// .arg(Arg::new("debug")
653 /// .get_matches_from(vec![
657 /// assert_eq!(m.value_source("debug"), Some(ValueSource::CommandLine));
660 /// [`default_value`]: crate::Arg::default_value()
661 #[cfg_attr(debug_assertions, track_caller)]
662 pub fn value_source
<T
: Key
>(&self, id
: T
) -> Option
<ValueSource
> {
663 let id
= Id
::from(id
);
665 let value
= self.get_arg(&id
);
667 value
.and_then(MatchedArg
::source
)
670 /// Deprecated, replaced with [`ArgAction::Count`][crate::ArgAction],
671 /// [`ArgMatches::get_many`]`.len()`, or [`ArgMatches::value_source`].
673 feature
= "deprecated",
676 note
= "Replaced with either `ArgAction::Count`, `ArgMatches::get_many(...).len()`, or `ArgMatches::value_source`"
679 #[cfg_attr(debug_assertions, track_caller)]
680 pub fn occurrences_of
<T
: Key
>(&self, id
: T
) -> u64 {
681 #![allow(deprecated)]
682 self.get_arg(&Id
::from(id
))
683 .map_or(0, |a
| a
.get_occurrences())
686 /// The first index of that an argument showed up.
688 /// Indices are similar to argv indices, but are not exactly 1:1.
690 /// For flags (i.e. those arguments which don't have an associated value), indices refer
691 /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
692 /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
693 /// index for `val` would be recorded. This is by design.
695 /// Besides the flag/option discrepancy, the primary difference between an argv index and clap
696 /// index, is that clap continues counting once all arguments have properly separated, whereas
697 /// an argv index does not.
699 /// The examples should clear this up.
701 /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first*
702 /// index. See [`ArgMatches::indices_of`].
706 /// If `id` is is not a valid argument or group id.
710 /// The argv indices are listed in the comments below. See how they correspond to the clap
711 /// indices. Note that if it's not listed in a clap index, this is because it's not saved in
712 /// in an `ArgMatches` struct for querying.
715 /// # use clap::{Command, Arg};
716 /// let m = Command::new("myapp")
717 /// .arg(Arg::new("flag")
719 /// .arg(Arg::new("option")
721 /// .takes_value(true))
722 /// .get_matches_from(vec!["myapp", "-f", "-o", "val"]);
723 /// // ARGV indices: ^0 ^1 ^2 ^3
724 /// // clap indices: ^1 ^3
726 /// assert_eq!(m.index_of("flag"), Some(1));
727 /// assert_eq!(m.index_of("option"), Some(3));
730 /// Now notice, if we use one of the other styles of options:
733 /// # use clap::{Command, Arg};
734 /// let m = Command::new("myapp")
735 /// .arg(Arg::new("flag")
737 /// .arg(Arg::new("option")
739 /// .takes_value(true))
740 /// .get_matches_from(vec!["myapp", "-f", "-o=val"]);
741 /// // ARGV indices: ^0 ^1 ^2
742 /// // clap indices: ^1 ^3
744 /// assert_eq!(m.index_of("flag"), Some(1));
745 /// assert_eq!(m.index_of("option"), Some(3));
748 /// Things become much more complicated, or clear if we look at a more complex combination of
749 /// flags. Let's also throw in the final option style for good measure.
752 /// # use clap::{Command, Arg};
753 /// let m = Command::new("myapp")
754 /// .arg(Arg::new("flag")
756 /// .arg(Arg::new("flag2")
758 /// .arg(Arg::new("flag3")
760 /// .arg(Arg::new("option")
762 /// .takes_value(true))
763 /// .get_matches_from(vec!["myapp", "-fzF", "-oval"]);
764 /// // ARGV indices: ^0 ^1 ^2
765 /// // clap indices: ^1,2,3 ^5
767 /// // clap sees the above as 'myapp -f -z -F -o val'
768 /// // ^0 ^1 ^2 ^3 ^4 ^5
769 /// assert_eq!(m.index_of("flag"), Some(1));
770 /// assert_eq!(m.index_of("flag2"), Some(3));
771 /// assert_eq!(m.index_of("flag3"), Some(2));
772 /// assert_eq!(m.index_of("option"), Some(5));
775 /// One final combination of flags/options to see how they combine:
778 /// # use clap::{Command, Arg};
779 /// let m = Command::new("myapp")
780 /// .arg(Arg::new("flag")
782 /// .arg(Arg::new("flag2")
784 /// .arg(Arg::new("flag3")
786 /// .arg(Arg::new("option")
788 /// .takes_value(true))
789 /// .get_matches_from(vec!["myapp", "-fzFoval"]);
790 /// // ARGV indices: ^0 ^1
791 /// // clap indices: ^1,2,3^5
793 /// // clap sees the above as 'myapp -f -z -F -o val'
794 /// // ^0 ^1 ^2 ^3 ^4 ^5
795 /// assert_eq!(m.index_of("flag"), Some(1));
796 /// assert_eq!(m.index_of("flag2"), Some(3));
797 /// assert_eq!(m.index_of("flag3"), Some(2));
798 /// assert_eq!(m.index_of("option"), Some(5));
801 /// The last part to mention is when values are sent in multiple groups with a [delimiter].
804 /// # use clap::{Command, Arg};
805 /// let m = Command::new("myapp")
806 /// .arg(Arg::new("option")
808 /// .use_value_delimiter(true)
809 /// .multiple_values(true))
810 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
811 /// // ARGV indices: ^0 ^1
812 /// // clap indices: ^2 ^3 ^4
814 /// // clap sees the above as 'myapp -o val1 val2 val3'
815 /// // ^0 ^1 ^2 ^3 ^4
816 /// assert_eq!(m.index_of("option"), Some(2));
817 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
819 /// [delimiter]: crate::Arg::value_delimiter()
820 #[cfg_attr(debug_assertions, track_caller)]
821 pub fn index_of
<T
: Key
>(&self, id
: T
) -> Option
<usize> {
822 let arg
= self.get_arg(&Id
::from(id
))?
;
823 let i
= arg
.get_index(0)?
;
827 /// All indices an argument appeared at when parsing.
829 /// Indices are similar to argv indices, but are not exactly 1:1.
831 /// For flags (i.e. those arguments which don't have an associated value), indices refer
832 /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
833 /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
834 /// index for `val` would be recorded. This is by design.
836 /// *NOTE:* For more information about how clap indices compared to argv indices, see
837 /// [`ArgMatches::index_of`]
841 /// If `id` is is not a valid argument or group id.
846 /// # use clap::{Command, Arg};
847 /// let m = Command::new("myapp")
848 /// .arg(Arg::new("option")
850 /// .use_value_delimiter(true)
851 /// .multiple_values(true))
852 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
853 /// // ARGV indices: ^0 ^1
854 /// // clap indices: ^2 ^3 ^4
856 /// // clap sees the above as 'myapp -o val1 val2 val3'
857 /// // ^0 ^1 ^2 ^3 ^4
858 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
861 /// Another quick example is when flags and options are used together
864 /// # use clap::{Command, Arg, ArgAction};
865 /// let m = Command::new("myapp")
866 /// .arg(Arg::new("option")
868 /// .takes_value(true)
869 /// .action(ArgAction::Append))
870 /// .arg(Arg::new("flag")
872 /// .action(ArgAction::Count))
873 /// .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]);
874 /// // ARGV indices: ^0 ^1 ^2 ^3 ^4 ^5 ^6
875 /// // clap indices: ^2 ^3 ^5 ^6
877 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
878 /// assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[6]);
881 /// One final example, which is an odd case; if we *don't* use value delimiter as we did with
882 /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they
883 /// would all be a single value of `val1,val2,val3`, in which case they'd only receive a single
887 /// # use clap::{Command, Arg};
888 /// let m = Command::new("myapp")
889 /// .arg(Arg::new("option")
891 /// .takes_value(true)
892 /// .multiple_values(true))
893 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
894 /// // ARGV indices: ^0 ^1
895 /// // clap indices: ^2
897 /// // clap sees the above as 'myapp -o "val1,val2,val3"'
899 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);
901 /// [`ArgMatches::index_of`]: ArgMatches::index_of()
902 /// [delimiter]: Arg::value_delimiter()
903 #[cfg_attr(debug_assertions, track_caller)]
904 pub fn indices_of
<T
: Key
>(&self, id
: T
) -> Option
<Indices
<'_
>> {
905 let arg
= self.get_arg(&Id
::from(id
))?
;
916 feature
= "deprecated",
917 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::try_get_one()`")
919 pub fn is_valid_arg(&self, _id
: impl Key
) -> bool
{
920 #[cfg(debug_assertions)]
922 let id
= Id
::from(_id
);
923 self.disable_asserts
|| id
== Id
::empty_hash() || self.valid_args
.contains(&id
)
925 #[cfg(not(debug_assertions))]
934 /// The name and `ArgMatches` of the current [subcommand].
936 /// Subcommand values are put in a child [`ArgMatches`]
938 /// Returns `None` if the subcommand wasn't present at runtime,
943 /// # use clap::{Command, Arg, };
944 /// let app_m = Command::new("git")
945 /// .subcommand(Command::new("clone"))
946 /// .subcommand(Command::new("push"))
947 /// .subcommand(Command::new("commit"))
950 /// match app_m.subcommand() {
951 /// Some(("clone", sub_m)) => {}, // clone was used
952 /// Some(("push", sub_m)) => {}, // push was used
953 /// Some(("commit", sub_m)) => {}, // commit was used
954 /// _ => {}, // Either no subcommand or one not tested for...
958 /// Another useful scenario is when you want to support third party, or external, subcommands.
959 /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
960 /// with pattern matching!
963 /// # use clap::Command;
964 /// // Assume there is an external subcommand named "subcmd"
965 /// let app_m = Command::new("myprog")
966 /// .allow_external_subcommands(true)
967 /// .get_matches_from(vec![
968 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
971 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
972 /// // string argument name
973 /// match app_m.subcommand() {
974 /// Some((external, sub_m)) => {
975 /// let ext_args: Vec<&str> = sub_m.get_many::<String>("")
976 /// .unwrap().map(|s| s.as_str()).collect();
977 /// assert_eq!(external, "subcmd");
978 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
983 /// [subcommand]: crate::Command::subcommand
985 pub fn subcommand(&self) -> Option
<(&str, &ArgMatches
)> {
986 self.subcommand
.as_ref().map(|sc
| (&*sc
.name
, &sc
.matches
))
989 /// Return the name and `ArgMatches` of the current [subcommand].
991 /// Subcommand values are put in a child [`ArgMatches`]
993 /// Returns `None` if the subcommand wasn't present at runtime,
998 /// # use clap::{Command, Arg, };
999 /// let mut app_m = Command::new("git")
1000 /// .subcommand(Command::new("clone"))
1001 /// .subcommand(Command::new("push"))
1002 /// .subcommand(Command::new("commit"))
1003 /// .subcommand_required(true)
1006 /// let (name, sub_m) = app_m.remove_subcommand().expect("required");
1007 /// match (name.as_str(), sub_m) {
1008 /// ("clone", sub_m) => {}, // clone was used
1009 /// ("push", sub_m) => {}, // push was used
1010 /// ("commit", sub_m) => {}, // commit was used
1011 /// (name, _) => unimplemented!("{}", name),
1015 /// Another useful scenario is when you want to support third party, or external, subcommands.
1016 /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
1017 /// with pattern matching!
1020 /// # use clap::Command;
1021 /// // Assume there is an external subcommand named "subcmd"
1022 /// let mut app_m = Command::new("myprog")
1023 /// .allow_external_subcommands(true)
1024 /// .get_matches_from(vec![
1025 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
1028 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
1029 /// // string argument name
1030 /// match app_m.remove_subcommand() {
1031 /// Some((external, mut sub_m)) => {
1032 /// let ext_args: Vec<String> = sub_m.remove_many("")
1033 /// .expect("`file`is required")
1035 /// assert_eq!(external, "subcmd");
1036 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
1041 /// [subcommand]: crate::Command::subcommand
1042 pub fn remove_subcommand(&mut self) -> Option
<(String
, ArgMatches
)> {
1043 self.subcommand
.take().map(|sc
| (sc
.name
, sc
.matches
))
1046 /// The `ArgMatches` for the current [subcommand].
1048 /// Subcommand values are put in a child [`ArgMatches`]
1050 /// Returns `None` if the subcommand wasn't present at runtime,
1054 /// If `id` is is not a valid subcommand.
1059 /// # use clap::{Command, Arg, ArgAction};
1060 /// let app_m = Command::new("myprog")
1061 /// .arg(Arg::new("debug")
1063 /// .action(ArgAction::SetTrue)
1065 /// .subcommand(Command::new("test")
1066 /// .arg(Arg::new("opt")
1068 /// .takes_value(true)))
1069 /// .get_matches_from(vec![
1070 /// "myprog", "-d", "test", "--option", "val"
1073 /// // Both parent commands, and child subcommands can have arguments present at the same times
1074 /// assert!(*app_m.get_one::<bool>("debug").expect("defaulted by clap"));
1076 /// // Get the subcommand's ArgMatches instance
1077 /// if let Some(sub_m) = app_m.subcommand_matches("test") {
1078 /// // Use the struct like normal
1079 /// assert_eq!(sub_m.get_one::<String>("opt").map(|s| s.as_str()), Some("val"));
1083 /// [subcommand]: crate::Command::subcommand
1084 /// [`Command`]: crate::Command
1085 pub fn subcommand_matches
<T
: Key
>(&self, id
: T
) -> Option
<&ArgMatches
> {
1086 self.get_subcommand(&id
.into()).map(|sc
| &sc
.matches
)
1089 /// The name of the current [subcommand].
1091 /// Returns `None` if the subcommand wasn't present at runtime,
1096 /// # use clap::{Command, Arg, };
1097 /// let app_m = Command::new("git")
1098 /// .subcommand(Command::new("clone"))
1099 /// .subcommand(Command::new("push"))
1100 /// .subcommand(Command::new("commit"))
1103 /// match app_m.subcommand_name() {
1104 /// Some("clone") => {}, // clone was used
1105 /// Some("push") => {}, // push was used
1106 /// Some("commit") => {}, // commit was used
1107 /// _ => {}, // Either no subcommand or one not tested for...
1110 /// [subcommand]: crate::Command::subcommand
1111 /// [`Command`]: crate::Command
1113 pub fn subcommand_name(&self) -> Option
<&str> {
1114 self.subcommand
.as_ref().map(|sc
| &*sc
.name
)
1117 /// Check if a subcommand can be queried
1119 /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer
1120 /// mistakes. In some context, this doesn't work, so users can use this function to check
1121 /// before they do a query on `ArgMatches`.
1124 pub fn is_valid_subcommand(&self, _id
: impl Key
) -> bool
{
1125 #[cfg(debug_assertions)]
1127 let id
= Id
::from(_id
);
1128 self.disable_asserts
|| id
== Id
::empty_hash() || self.valid_subcommands
.contains(&id
)
1130 #[cfg(not(debug_assertions))]
1139 /// Non-panicking version of [`ArgMatches::get_one`]
1140 pub fn try_get_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1143 ) -> Result
<Option
<&T
>, MatchesError
> {
1144 let id
= Id
::from(id
);
1145 let arg
= self.try_get_arg_t
::<T
>(&id
)?
;
1146 let value
= match arg
.and_then(|a
| a
.first()) {
1147 Some(value
) => value
,
1153 .downcast_ref
::<T
>()
1155 .expect(INTERNAL_ERROR_MSG
)) // enforced by `try_get_arg_t`
1158 /// Non-panicking version of [`ArgMatches::get_many`]
1159 pub fn try_get_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1162 ) -> Result
<Option
<ValuesRef
<T
>>, MatchesError
> {
1163 let id
= Id
::from(id
);
1164 let arg
= match self.try_get_arg_t
::<T
>(&id
)?
{
1166 None
=> return Ok(None
),
1168 let len
= arg
.num_vals();
1169 let values
= arg
.vals_flatten();
1170 let values
= ValuesRef
{
1171 // enforced by `try_get_arg_t`
1172 iter
: values
.map(|v
| v
.downcast_ref
::<T
>().expect(INTERNAL_ERROR_MSG
)),
1178 /// Non-panicking version of [`ArgMatches::get_raw`]
1179 pub fn try_get_raw(&self, id
: &str) -> Result
<Option
<RawValues
<'_
>>, MatchesError
> {
1180 let id
= Id
::from(id
);
1181 let arg
= match self.try_get_arg(&id
)?
{
1183 None
=> return Ok(None
),
1185 let len
= arg
.num_vals();
1186 let values
= arg
.raw_vals_flatten();
1187 let values
= RawValues
{
1188 iter
: values
.map(OsString
::as_os_str
),
1194 /// Non-panicking version of [`ArgMatches::remove_one`]
1195 pub fn try_remove_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1198 ) -> Result
<Option
<T
>, MatchesError
> {
1199 let id
= Id
::from(id
);
1200 match self.try_remove_arg_t
::<T
>(&id
)?
{
1201 Some(values
) => Ok(values
1202 .into_vals_flatten()
1203 // enforced by `try_get_arg_t`
1204 .map(|v
| v
.downcast_into
::<T
>().expect(INTERNAL_ERROR_MSG
))
1210 /// Non-panicking version of [`ArgMatches::remove_many`]
1211 pub fn try_remove_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1214 ) -> Result
<Option
<Values2
<T
>>, MatchesError
> {
1215 let id
= Id
::from(id
);
1216 let arg
= match self.try_remove_arg_t
::<T
>(&id
)?
{
1218 None
=> return Ok(None
),
1220 let len
= arg
.num_vals();
1221 let values
= arg
.into_vals_flatten();
1222 let values
= Values2
{
1223 // enforced by `try_get_arg_t`
1224 iter
: values
.map(|v
| v
.downcast_into
::<T
>().expect(INTERNAL_ERROR_MSG
)),
1230 /// Non-panicking version of [`ArgMatches::contains_id`]
1231 pub fn try_contains_id(&self, id
: &str) -> Result
<bool
, MatchesError
> {
1232 let id
= Id
::from(id
);
1234 self.verify_arg(&id
)?
;
1236 let presence
= self.args
.contains_key(&id
);
1244 fn try_get_arg(&self, arg
: &Id
) -> Result
<Option
<&MatchedArg
>, MatchesError
> {
1245 self.verify_arg(arg
)?
;
1246 Ok(self.args
.get(arg
))
1250 fn try_get_arg_t
<T
: Any
+ Send
+ Sync
+ '
static>(
1253 ) -> Result
<Option
<&MatchedArg
>, MatchesError
> {
1254 let arg
= match self.try_get_arg(arg
)?
{
1260 self.verify_arg_t
::<T
>(arg
)?
;
1265 fn try_remove_arg_t
<T
: Any
+ Send
+ Sync
+ '
static>(
1268 ) -> Result
<Option
<MatchedArg
>, MatchesError
> {
1269 self.verify_arg(arg
)?
;
1270 let matched
= match self.args
.remove(arg
) {
1271 Some(matched
) => matched
,
1277 let expected
= AnyValueId
::of
::<T
>();
1278 let actual
= matched
.infer_type_id(expected
);
1279 if actual
== expected
{
1282 self.args
.insert(arg
.clone(), matched
);
1283 Err(MatchesError
::Downcast { actual, expected }
)
1287 fn verify_arg_t
<T
: Any
+ Send
+ Sync
+ '
static>(
1290 ) -> Result
<(), MatchesError
> {
1291 let expected
= AnyValueId
::of
::<T
>();
1292 let actual
= arg
.infer_type_id(expected
);
1293 if expected
== actual
{
1296 Err(MatchesError
::Downcast { actual, expected }
)
1301 fn verify_arg(&self, _arg
: &Id
) -> Result
<(), MatchesError
> {
1302 #[cfg(debug_assertions)]
1304 if self.disable_asserts
|| *_arg
== Id
::empty_hash() || self.valid_args
.contains(_arg
) {
1305 } else if self.valid_subcommands
.contains(_arg
) {
1307 "Subcommand `{:?}` used where an argument or group name was expected.",
1310 return Err(MatchesError
::UnknownArgument {}
);
1313 "`{:?}` is not an id of an argument or a group.\n\
1314 Make sure you're using the name of the argument itself \
1315 and not the name of short or long flags.",
1318 return Err(MatchesError
::UnknownArgument {}
);
1325 #[cfg_attr(debug_assertions, track_caller)]
1326 fn get_arg(&self, arg
: &Id
) -> Option
<&MatchedArg
> {
1327 #[cfg(debug_assertions)]
1329 if self.disable_asserts
|| *arg
== Id
::empty_hash() || self.valid_args
.contains(arg
) {
1330 } else if self.valid_subcommands
.contains(arg
) {
1332 "Subcommand `{:?}` used where an argument or group name was expected.",
1337 "`{:?}` is not an id of an argument or a group.\n\
1338 Make sure you're using the name of the argument itself \
1339 and not the name of short or long flags.",
1349 #[cfg_attr(debug_assertions, track_caller)]
1350 fn get_subcommand(&self, id
: &Id
) -> Option
<&SubCommand
> {
1351 #[cfg(debug_assertions)]
1353 if self.disable_asserts
1354 || *id
== Id
::empty_hash()
1355 || self.valid_subcommands
.contains(id
)
1357 } else if self.valid_args
.contains(id
) {
1359 "Argument or group `{:?}` used where a subcommand name was expected.",
1363 panic
!("`{:?}` is not a name of a subcommand.", id
);
1367 if let Some(ref sc
) = self.subcommand
{
1377 #[derive(Debug, Clone, PartialEq, Eq)]
1378 pub(crate) struct SubCommand
{
1380 pub(crate) name
: String
,
1381 pub(crate) matches
: ArgMatches
,
1384 /// Iterate over multiple values for an argument via [`ArgMatches::remove_many`].
1389 /// # use clap::{Command, Arg, ArgAction};
1390 /// let mut m = Command::new("myapp")
1391 /// .arg(Arg::new("output")
1393 /// .action(ArgAction::Append)
1394 /// .takes_value(true))
1395 /// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1397 /// let mut values = m.remove_many::<String>("output")
1400 /// assert_eq!(values.next(), Some(String::from("val1")));
1401 /// assert_eq!(values.next(), Some(String::from("val2")));
1402 /// assert_eq!(values.next(), None);
1404 #[derive(Clone, Debug)]
1405 pub struct Values2
<T
> {
1406 #[allow(clippy::type_complexity)]
1407 iter
: Map
<Flatten
<std
::vec
::IntoIter
<Vec
<AnyValue
>>>, fn(AnyValue
) -> T
>,
1411 impl<T
> Iterator
for Values2
<T
> {
1414 fn next(&mut self) -> Option
<Self::Item
> {
1417 fn size_hint(&self) -> (usize, Option
<usize>) {
1418 (self.len
, Some(self.len
))
1422 impl<T
> DoubleEndedIterator
for Values2
<T
> {
1423 fn next_back(&mut self) -> Option
<Self::Item
> {
1424 self.iter
.next_back()
1428 impl<T
> ExactSizeIterator
for Values2
<T
> {}
1430 /// Creates an empty iterator.
1431 impl<T
> Default
for Values2
<T
> {
1432 fn default() -> Self {
1433 let empty
: Vec
<Vec
<AnyValue
>> = Default
::default();
1435 iter
: empty
.into_iter().flatten().map(|_
| unreachable
!()),
1441 /// Iterate over multiple values for an argument via [`ArgMatches::get_many`].
1446 /// # use clap::{Command, Arg, ArgAction};
1447 /// let m = Command::new("myapp")
1448 /// .arg(Arg::new("output")
1450 /// .action(ArgAction::Append)
1451 /// .takes_value(true))
1452 /// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1454 /// let mut values = m.get_many::<String>("output")
1456 /// .map(|s| s.as_str());
1458 /// assert_eq!(values.next(), Some("val1"));
1459 /// assert_eq!(values.next(), Some("val2"));
1460 /// assert_eq!(values.next(), None);
1462 #[derive(Clone, Debug)]
1463 pub struct ValuesRef
<'a
, T
> {
1464 #[allow(clippy::type_complexity)]
1465 iter
: Map
<Flatten
<Iter
<'a
, Vec
<AnyValue
>>>, fn(&AnyValue
) -> &T
>,
1469 impl<'a
, T
: 'a
> Iterator
for ValuesRef
<'a
, T
> {
1472 fn next(&mut self) -> Option
<Self::Item
> {
1475 fn size_hint(&self) -> (usize, Option
<usize>) {
1476 (self.len
, Some(self.len
))
1480 impl<'a
, T
: 'a
> DoubleEndedIterator
for ValuesRef
<'a
, T
> {
1481 fn next_back(&mut self) -> Option
<Self::Item
> {
1482 self.iter
.next_back()
1486 impl<'a
, T
: 'a
> ExactSizeIterator
for ValuesRef
<'a
, T
> {}
1488 /// Creates an empty iterator.
1489 impl<'a
, T
: 'a
> Default
for ValuesRef
<'a
, T
> {
1490 fn default() -> Self {
1491 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1493 iter
: EMPTY
[..].iter().flatten().map(|_
| unreachable
!()),
1499 /// Iterate over raw argument values via [`ArgMatches::get_raw`].
1503 #[cfg_attr(not(unix), doc = " ```ignore")]
1504 #[cfg_attr(unix, doc = " ```")]
1505 /// # use clap::{Command, arg, value_parser};
1506 /// use std::ffi::OsString;
1507 /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
1509 /// let m = Command::new("utf8")
1510 /// .arg(arg!(<arg> "some arg")
1511 /// .value_parser(value_parser!(OsString)))
1512 /// .get_matches_from(vec![OsString::from("myprog"),
1514 /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
1516 /// &*m.get_raw("arg")
1518 /// .next().unwrap()
1520 /// [b'H', b'i', b' ', 0xe9, b'!']
1523 #[derive(Clone, Debug)]
1524 pub struct RawValues
<'a
> {
1525 #[allow(clippy::type_complexity)]
1526 iter
: Map
<Flatten
<Iter
<'a
, Vec
<OsString
>>>, fn(&OsString
) -> &OsStr
>,
1530 impl<'a
> Iterator
for RawValues
<'a
> {
1531 type Item
= &'a OsStr
;
1533 fn next(&mut self) -> Option
<&'a OsStr
> {
1536 fn size_hint(&self) -> (usize, Option
<usize>) {
1537 (self.len
, Some(self.len
))
1541 impl<'a
> DoubleEndedIterator
for RawValues
<'a
> {
1542 fn next_back(&mut self) -> Option
<&'a OsStr
> {
1543 self.iter
.next_back()
1547 impl<'a
> ExactSizeIterator
for RawValues
<'a
> {}
1549 /// Creates an empty iterator.
1550 impl Default
for RawValues
<'_
> {
1551 fn default() -> Self {
1552 static EMPTY
: [Vec
<OsString
>; 0] = [];
1554 iter
: EMPTY
[..].iter().flatten().map(|_
| unreachable
!()),
1560 // The following were taken and adapted from vec_map source
1561 // repo: https://github.com/contain-rs/vec-map
1562 // commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
1563 // license: MIT - Copyright (c) 2015 The Rust Project Developers
1565 /// Deprecated, replaced with [`ArgMatches::get_many()`]
1567 feature
= "deprecated",
1568 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
1570 #[derive(Clone, Debug)]
1571 pub struct Values
<'a
> {
1572 #[allow(clippy::type_complexity)]
1573 iter
: Map
<Flatten
<Iter
<'a
, Vec
<AnyValue
>>>, for<'r
> fn(&'r AnyValue
) -> &'r
str>,
1577 #[allow(deprecated)]
1578 impl<'a
> Iterator
for Values
<'a
> {
1579 type Item
= &'a
str;
1581 fn next(&mut self) -> Option
<&'a
str> {
1584 fn size_hint(&self) -> (usize, Option
<usize>) {
1585 (self.len
, Some(self.len
))
1589 #[allow(deprecated)]
1590 impl<'a
> DoubleEndedIterator
for Values
<'a
> {
1591 fn next_back(&mut self) -> Option
<&'a
str> {
1592 self.iter
.next_back()
1596 #[allow(deprecated)]
1597 impl<'a
> ExactSizeIterator
for Values
<'a
> {}
1599 /// Creates an empty iterator.
1600 #[allow(deprecated)]
1601 impl<'a
> Default
for Values
<'a
> {
1602 fn default() -> Self {
1603 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1605 iter
: EMPTY
[..].iter().flatten().map(|_
| unreachable
!()),
1612 #[allow(missing_debug_implementations)]
1613 pub struct GroupedValues
<'a
> {
1614 #[allow(clippy::type_complexity)]
1615 iter
: Map
<Iter
<'a
, Vec
<AnyValue
>>, fn(&Vec
<AnyValue
>) -> Vec
<&str>>,
1619 impl<'a
> Iterator
for GroupedValues
<'a
> {
1620 type Item
= Vec
<&'a
str>;
1622 fn next(&mut self) -> Option
<Self::Item
> {
1625 fn size_hint(&self) -> (usize, Option
<usize>) {
1626 (self.len
, Some(self.len
))
1630 impl<'a
> DoubleEndedIterator
for GroupedValues
<'a
> {
1631 fn next_back(&mut self) -> Option
<Self::Item
> {
1632 self.iter
.next_back()
1636 impl<'a
> ExactSizeIterator
for GroupedValues
<'a
> {}
1638 /// Creates an empty iterator. Used for `unwrap_or_default()`.
1639 impl<'a
> Default
for GroupedValues
<'a
> {
1640 fn default() -> Self {
1641 #![allow(deprecated)]
1642 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1644 iter
: EMPTY
[..].iter().map(|_
| unreachable
!()),
1650 /// Deprecated, replaced with [`ArgMatches::get_many()`]
1652 feature
= "deprecated",
1653 deprecated(since
= "3.2.0", note
= "Replaced with `ArgMatches::get_many()`")
1655 #[derive(Clone, Debug)]
1656 pub struct OsValues
<'a
> {
1657 #[allow(clippy::type_complexity)]
1658 iter
: Map
<Flatten
<Iter
<'a
, Vec
<AnyValue
>>>, fn(&AnyValue
) -> &OsStr
>,
1662 #[allow(deprecated)]
1663 impl<'a
> Iterator
for OsValues
<'a
> {
1664 type Item
= &'a OsStr
;
1666 fn next(&mut self) -> Option
<&'a OsStr
> {
1669 fn size_hint(&self) -> (usize, Option
<usize>) {
1670 (self.len
, Some(self.len
))
1674 #[allow(deprecated)]
1675 impl<'a
> DoubleEndedIterator
for OsValues
<'a
> {
1676 fn next_back(&mut self) -> Option
<&'a OsStr
> {
1677 self.iter
.next_back()
1681 #[allow(deprecated)]
1682 impl<'a
> ExactSizeIterator
for OsValues
<'a
> {}
1684 /// Creates an empty iterator.
1685 #[allow(deprecated)]
1686 impl Default
for OsValues
<'_
> {
1687 fn default() -> Self {
1688 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1690 iter
: EMPTY
[..].iter().flatten().map(|_
| unreachable
!()),
1696 /// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
1701 /// # use clap::{Command, Arg};
1702 /// let m = Command::new("myapp")
1703 /// .arg(Arg::new("output")
1705 /// .multiple_values(true)
1706 /// .takes_value(true))
1707 /// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
1709 /// let mut indices = m.indices_of("output").unwrap();
1711 /// assert_eq!(indices.next(), Some(2));
1712 /// assert_eq!(indices.next(), Some(3));
1713 /// assert_eq!(indices.next(), None);
1715 /// [`ArgMatches::indices_of`]: ArgMatches::indices_of()
1716 #[derive(Clone, Debug)]
1717 pub struct Indices
<'a
> {
1718 iter
: Cloned
<Iter
<'a
, usize>>,
1722 impl<'a
> Iterator
for Indices
<'a
> {
1725 fn next(&mut self) -> Option
<usize> {
1728 fn size_hint(&self) -> (usize, Option
<usize>) {
1729 (self.len
, Some(self.len
))
1733 impl<'a
> DoubleEndedIterator
for Indices
<'a
> {
1734 fn next_back(&mut self) -> Option
<usize> {
1735 self.iter
.next_back()
1739 impl<'a
> ExactSizeIterator
for Indices
<'a
> {}
1741 /// Creates an empty iterator.
1742 impl<'a
> Default
for Indices
<'a
> {
1743 fn default() -> Self {
1744 static EMPTY
: [usize; 0] = [];
1745 // This is never called because the iterator is empty:
1747 iter
: EMPTY
[..].iter().cloned(),
1753 #[cfg_attr(debug_assertions, track_caller)]
1755 fn unwrap_string(value
: &AnyValue
) -> &str {
1756 match value
.downcast_ref
::<String
>() {
1757 Some(value
) => value
,
1759 panic
!("Must use `_os` lookups with `Arg::allow_invalid_utf8`",)
1764 #[cfg_attr(debug_assertions, track_caller)]
1766 fn unwrap_string_arg
<'v
>(id
: &Id
, value
: &'v AnyValue
) -> &'v
str {
1767 match value
.downcast_ref
::<String
>() {
1768 Some(value
) => value
,
1771 "Must use `_os` lookups with `Arg::allow_invalid_utf8` at `{:?}`",
1778 #[cfg_attr(debug_assertions, track_caller)]
1780 fn unwrap_os_string(value
: &AnyValue
) -> &OsStr
{
1781 match value
.downcast_ref
::<OsString
>() {
1782 Some(value
) => value
,
1784 panic
!("Must use `Arg::allow_invalid_utf8` with `_os` lookups",)
1789 #[cfg_attr(debug_assertions, track_caller)]
1791 fn unwrap_os_string_arg
<'v
>(id
: &Id
, value
: &'v AnyValue
) -> &'v OsStr
{
1792 match value
.downcast_ref
::<OsString
>() {
1793 Some(value
) => value
,
1796 "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `{:?}`",
1808 fn check_auto_traits() {
1809 static_assertions
::assert_impl_all
!(ArgMatches
: Send
, Sync
, Unpin
);
1813 fn test_default_values() {
1814 #![allow(deprecated)]
1815 let mut values
: Values
= Values
::default();
1816 assert_eq
!(values
.next(), None
);
1820 fn test_default_osvalues() {
1821 #![allow(deprecated)]
1822 let mut values
: OsValues
= OsValues
::default();
1823 assert_eq
!(values
.next(), None
);
1827 fn test_default_raw_values() {
1828 let mut values
: RawValues
= Default
::default();
1829 assert_eq
!(values
.next(), None
);
1833 fn test_default_indices() {
1834 let mut indices
: Indices
= Indices
::default();
1835 assert_eq
!(indices
.next(), None
);
1839 fn test_default_indices_with_shorter_lifetime() {
1840 let matches
= ArgMatches
::default();
1841 let mut indices
= matches
.indices_of("").unwrap_or_default();
1842 assert_eq
!(indices
.next(), None
);
1846 fn values_exact_size() {
1847 let l
= crate::Command
::new("test")
1849 crate::Arg
::new("POTATO")
1851 .multiple_values(true)
1854 .try_get_matches_from(["test", "one"])
1856 .get_many
::<String
>("POTATO")
1863 fn os_values_exact_size() {
1864 let l
= crate::Command
::new("test")
1866 crate::Arg
::new("POTATO")
1868 .multiple_values(true)
1869 .value_parser(crate::builder
::ValueParser
::os_string())
1872 .try_get_matches_from(["test", "one"])
1874 .get_many
::<std
::ffi
::OsString
>("POTATO")
1881 fn indices_exact_size() {
1882 let l
= crate::Command
::new("test")
1884 crate::Arg
::new("POTATO")
1886 .multiple_values(true)
1889 .try_get_matches_from(["test", "one"])
1891 .indices_of("POTATO")