3 use std
::ffi
::{OsStr, OsString}
;
5 use std
::iter
::{Cloned, Flatten, Map}
;
9 #[cfg(debug_assertions)]
10 use crate::builder
::Str
;
11 use crate::parser
::AnyValue
;
12 use crate::parser
::AnyValueId
;
13 use crate::parser
::MatchedArg
;
14 use crate::parser
::MatchesError
;
15 use crate::parser
::ValueSource
;
16 use crate::util
::FlatMap
;
18 use crate::INTERNAL_ERROR_MSG
;
20 /// Container for parse results.
22 /// Used to get information about the arguments that were supplied to the program at runtime by
23 /// the user. New instances of this struct are obtained by using the [`Command::get_matches`] family of
29 /// # use clap_builder as clap;
30 /// # use clap::{Command, Arg, ArgAction};
31 /// # use clap::parser::ValueSource;
32 /// let matches = Command::new("MyApp")
33 /// .arg(Arg::new("out")
36 /// .action(ArgAction::Set)
37 /// .default_value("-"))
38 /// .arg(Arg::new("cfg")
40 /// .action(ArgAction::Set))
41 /// .get_matches(); // builds the instance of ArgMatches
43 /// // to get information about the "cfg" argument we created, such as the value supplied we use
44 /// // various ArgMatches methods, such as [ArgMatches::get_one]
45 /// if let Some(c) = matches.get_one::<String>("cfg") {
46 /// println!("Value for -c: {}", c);
49 /// // The ArgMatches::get_one method returns an Option because the user may not have supplied
50 /// // that argument at runtime. But if we specified that the argument was "required" as we did
51 /// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually
52 /// // used at runtime.
53 /// println!("Value for --output: {}", matches.get_one::<String>("out").unwrap());
55 /// // You can check the presence of an argument's values
56 /// if matches.contains_id("out") {
57 /// // However, if you want to know where the value came from
58 /// if matches.value_source("out").expect("checked contains_id") == ValueSource::CommandLine {
59 /// println!("`out` set by user");
61 /// println!("`out` is defaulted");
65 /// [`Command::get_matches`]: crate::Command::get_matches()
66 #[derive(Debug, Clone, Default, PartialEq, Eq)]
67 pub struct ArgMatches
{
68 #[cfg(debug_assertions)]
69 pub(crate) valid_args
: Vec
<Id
>,
70 #[cfg(debug_assertions)]
71 pub(crate) valid_subcommands
: Vec
<Str
>,
72 pub(crate) args
: FlatMap
<Id
, MatchedArg
>,
73 pub(crate) subcommand
: Option
<Box
<SubCommand
>>,
78 /// Gets the value of a specific option or positional argument.
80 /// i.e. an argument that [takes an additional value][crate::Arg::num_args] at runtime.
82 /// Returns an error if the wrong type was used.
84 /// Returns `None` if the option wasn't present.
86 /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
87 /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
91 /// If the argument definition and access mismatch. To handle this case programmatically, see
92 /// [`ArgMatches::try_get_one`].
97 /// # use clap_builder as clap;
98 /// # use clap::{Command, Arg, value_parser, ArgAction};
99 /// let m = Command::new("myapp")
100 /// .arg(Arg::new("port")
101 /// .value_parser(value_parser!(usize))
102 /// .action(ArgAction::Set)
104 /// .get_matches_from(vec!["myapp", "2020"]);
106 /// let port: usize = *m
108 /// .expect("`port`is required");
109 /// assert_eq!(port, 2020);
111 /// [positional]: crate::Arg::index()
112 /// [`default_value`]: crate::Arg::default_value()
113 #[cfg_attr(debug_assertions, track_caller)]
114 pub fn get_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(&self, id
: &str) -> Option
<&T
> {
115 MatchesError
::unwrap(id
, self.try_get_one(id
))
118 /// Gets the value of a specific [`ArgAction::Count`][crate::ArgAction::Count] flag
122 /// If the argument's action is not [`ArgAction::Count`][crate::ArgAction::Count]
127 /// # use clap_builder as clap;
128 /// # use clap::Command;
130 /// let cmd = Command::new("mycmd")
134 /// .action(clap::ArgAction::Count)
137 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
139 /// matches.get_count("flag"),
143 #[cfg_attr(debug_assertions, track_caller)]
144 pub fn get_count(&self, id
: &str) -> u8 {
145 *self.get_one
::<u8>(id
).unwrap_or_else(|| {
147 "arg `{}`'s `ArgAction` should be `Count` which should provide a default",
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_builder as clap;
163 /// # use clap::Command;
165 /// let cmd = Command::new("mycmd")
169 /// .action(clap::ArgAction::SetTrue)
172 /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
173 /// assert!(matches.contains_id("flag"));
175 /// matches.get_flag("flag"),
179 #[cfg_attr(debug_assertions, track_caller)]
180 pub fn get_flag(&self, id
: &str) -> bool
{
185 "arg `{}`'s `ArgAction` should be one of `SetTrue`, `SetFalse` which should provide a default",
191 /// Iterate over values of a specific option or positional argument.
193 /// i.e. an argument that takes multiple values at runtime.
195 /// Returns an error if the wrong type was used.
197 /// Returns `None` if the option wasn't present.
201 /// If the argument definition and access mismatch. To handle this case programmatically, see
202 /// [`ArgMatches::try_get_many`].
207 /// # use clap_builder as clap;
208 /// # use clap::{Command, Arg, value_parser, ArgAction};
209 /// let m = Command::new("myprog")
210 /// .arg(Arg::new("ports")
211 /// .action(ArgAction::Append)
212 /// .value_parser(value_parser!(usize))
215 /// .get_matches_from(vec![
216 /// "myprog", "-p", "22", "-p", "80", "-p", "2020"
218 /// let vals: Vec<usize> = m.get_many("ports")
219 /// .expect("`port`is required")
222 /// assert_eq!(vals, [22, 80, 2020]);
224 #[cfg_attr(debug_assertions, track_caller)]
225 pub fn get_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
228 ) -> Option
<ValuesRef
<T
>> {
229 MatchesError
::unwrap(id
, self.try_get_many(id
))
232 /// Iterate over the values passed to each occurrence of an option.
234 /// Each item is itself an iterator containing the arguments passed to a single occurrence
237 /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
238 /// the iterator will only contain a single item.
240 /// Returns `None` if the option wasn't present.
244 /// If the argument definition and access mismatch. To handle this case programmatically, see
245 /// [`ArgMatches::try_get_occurrences`].
249 /// # use clap_builder as clap;
250 /// # use clap::{Command,Arg, ArgAction, value_parser};
251 /// let m = Command::new("myprog")
252 /// .arg(Arg::new("x")
255 /// .action(ArgAction::Append)
256 /// .value_parser(value_parser!(String)))
257 /// .get_matches_from(vec![
258 /// "myprog", "-x", "a", "b", "-x", "c", "d"]);
259 /// let vals: Vec<Vec<&String>> = m.get_occurrences("x").unwrap().map(Iterator::collect).collect();
260 /// assert_eq!(vals, [["a", "b"], ["c", "d"]]);
262 #[cfg_attr(debug_assertions, track_caller)]
263 pub fn get_occurrences
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
266 ) -> Option
<OccurrencesRef
<T
>> {
267 MatchesError
::unwrap(id
, self.try_get_occurrences(id
))
270 /// Iterate over the original argument values.
272 /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
273 /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
274 /// filename on a Unix system as an argument value may contain invalid UTF-8.
276 /// Returns `None` if the option wasn't present.
280 /// If the argument definition and access mismatch. To handle this case programmatically, see
281 /// [`ArgMatches::try_get_raw`].
287 /// # use clap_builder as clap;
288 /// # use clap::{Command, arg, value_parser};
289 /// # use std::ffi::{OsStr,OsString};
290 /// # use std::os::unix::ffi::{OsStrExt,OsStringExt};
291 /// use std::path::PathBuf;
293 /// let m = Command::new("utf8")
294 /// .arg(arg!(<arg> ... "some arg").value_parser(value_parser!(PathBuf)))
295 /// .get_matches_from(vec![OsString::from("myprog"),
297 /// OsString::from_vec(vec![b'H', b'i']),
299 /// OsString::from_vec(vec![0xe9, b'!'])]);
301 /// let mut itr = m.get_raw("arg")
302 /// .expect("`port`is required")
304 /// assert_eq!(itr.next(), Some(OsStr::new("Hi")));
305 /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!'])));
306 /// assert_eq!(itr.next(), None);
309 /// [`Iterator`]: std::iter::Iterator
310 /// [`OsSt`]: std::ffi::OsStr
311 /// [values]: OsValues
312 /// [`String`]: std::string::String
313 #[cfg_attr(debug_assertions, track_caller)]
314 pub fn get_raw(&self, id
: &str) -> Option
<RawValues
<'_
>> {
315 MatchesError
::unwrap(id
, self.try_get_raw(id
))
318 /// Iterate over the original values for each occurrence of an option.
320 /// Similar to [`ArgMatches::get_occurrences`] but returns raw values.
322 /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
323 /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
324 /// filename on a Unix system as an argument value may contain invalid UTF-8.
326 /// Returns `None` if the option wasn't present.
330 /// If the argument definition and access mismatch. To handle this case programmatically, see
331 /// [`ArgMatches::try_get_raw_occurrences`].
337 /// # use clap_builder as clap;
338 /// # use clap::{Command, arg, value_parser, ArgAction, Arg};
339 /// # use std::ffi::{OsStr,OsString};
340 /// # use std::os::unix::ffi::{OsStrExt,OsStringExt};
341 /// use std::path::PathBuf;
343 /// let m = Command::new("myprog")
344 /// .arg(Arg::new("x")
347 /// .action(ArgAction::Append)
348 /// .value_parser(value_parser!(PathBuf)))
349 /// .get_matches_from(vec![OsString::from("myprog"),
350 /// OsString::from("-x"),
351 /// OsString::from("a"), OsString::from("b"),
352 /// OsString::from("-x"),
353 /// OsString::from("c"),
355 /// OsString::from_vec(vec![0xe9, b'!'])]);
356 /// let mut itr = m.get_raw_occurrences("x")
357 /// .expect("`-x`is required")
358 /// .map(Iterator::collect::<Vec<_>>);
359 /// assert_eq!(itr.next(), Some(vec![OsStr::new("a"), OsStr::new("b")]));
360 /// assert_eq!(itr.next(), Some(vec![OsStr::new("c"), OsStr::from_bytes(&[0xe9, b'!'])]));
361 /// assert_eq!(itr.next(), None);
364 /// [`Iterator`]: std::iter::Iterator
365 /// [`OsStr`]: std::ffi::OsStr
366 /// [values]: OsValues
367 /// [`String`]: std::string::String
368 #[cfg_attr(debug_assertions, track_caller)]
369 pub fn get_raw_occurrences(&self, id
: &str) -> Option
<RawOccurrences
<'_
>> {
370 MatchesError
::unwrap(id
, self.try_get_raw_occurrences(id
))
373 /// Returns the value of a specific option or positional argument.
375 /// i.e. an argument that [takes an additional value][crate::Arg::num_args] at runtime.
377 /// Returns an error if the wrong type was used. No item will have been removed.
379 /// Returns `None` if the option wasn't present.
381 /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
382 /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
386 /// If the argument definition and access mismatch. To handle this case programmatically, see
387 /// [`ArgMatches::try_remove_one`].
392 /// # use clap_builder as clap;
393 /// # use clap::{Command, Arg, value_parser, ArgAction};
394 /// let mut m = Command::new("myprog")
395 /// .arg(Arg::new("file")
397 /// .action(ArgAction::Set))
398 /// .get_matches_from(vec![
399 /// "myprog", "file.txt",
401 /// let vals: String = m.remove_one("file")
402 /// .expect("`file`is required");
403 /// assert_eq!(vals, "file.txt");
405 /// [positional]: crate::Arg::index()
406 /// [`default_value`]: crate::Arg::default_value()
407 #[cfg_attr(debug_assertions, track_caller)]
408 pub fn remove_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(&mut self, id
: &str) -> Option
<T
> {
409 MatchesError
::unwrap(id
, self.try_remove_one(id
))
412 /// Return values of a specific option or positional argument.
414 /// i.e. an argument that takes multiple values at runtime.
416 /// Returns an error if the wrong type was used. No item will have been removed.
418 /// Returns `None` if the option wasn't present.
422 /// If the argument definition and access mismatch. To handle this case programmatically, see
423 /// [`ArgMatches::try_remove_many`].
428 /// # use clap_builder as clap;
429 /// # use clap::{Command, Arg, value_parser, ArgAction};
430 /// let mut m = Command::new("myprog")
431 /// .arg(Arg::new("file")
432 /// .action(ArgAction::Append)
435 /// .get_matches_from(vec![
436 /// "myprog", "file1.txt", "file2.txt", "file3.txt", "file4.txt",
438 /// let vals: Vec<String> = m.remove_many("file")
439 /// .expect("`file`is required")
441 /// assert_eq!(vals, ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]);
443 #[cfg_attr(debug_assertions, track_caller)]
444 pub fn remove_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
447 ) -> Option
<Values
<T
>> {
448 MatchesError
::unwrap(id
, self.try_remove_many(id
))
451 /// Return values for each occurrence of an option.
453 /// Each item is itself an iterator containing the arguments passed to a single occurrence of
456 /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
457 /// the iterator will only contain a single item.
459 /// Returns `None` if the option wasn't present.
463 /// If the argument definition and access mismatch. To handle this case programmatically, see
464 /// [`ArgMatches::try_remove_occurrences`].
469 /// # use clap_builder as clap;
470 /// # use clap::{Command, Arg, value_parser, ArgAction};
471 /// let mut m = Command::new("myprog")
472 /// .arg(Arg::new("x")
475 /// .action(ArgAction::Append)
476 /// .value_parser(value_parser!(String)))
477 /// .get_matches_from(vec![
478 /// "myprog", "-x", "a", "b", "-x", "c", "d"]);
479 /// let vals: Vec<Vec<String>> = m.remove_occurrences("x").unwrap().map(Iterator::collect).collect();
480 /// assert_eq!(vals, [["a", "b"], ["c", "d"]]);
482 #[cfg_attr(debug_assertions, track_caller)]
483 pub fn remove_occurrences
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
486 ) -> Option
<Occurrences
<T
>> {
487 MatchesError
::unwrap(id
, self.try_remove_occurrences(id
))
490 /// Check if values are present for the argument or group id
492 /// *NOTE:* This will always return `true` if [`default_value`] has been set.
493 /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
497 /// If `id` is not a valid argument or group name. To handle this case programmatically, see
498 /// [`ArgMatches::try_contains_id`].
503 /// # use clap_builder as clap;
504 /// # use clap::{Command, Arg, ArgAction};
505 /// let m = Command::new("myprog")
506 /// .arg(Arg::new("debug")
508 /// .action(ArgAction::SetTrue))
509 /// .get_matches_from(vec![
513 /// assert!(m.contains_id("debug"));
516 /// [`default_value`]: crate::Arg::default_value()
517 pub fn contains_id(&self, id
: &str) -> bool
{
518 MatchesError
::unwrap(id
, self.try_contains_id(id
))
521 /// Iterate over [`Arg`][crate::Arg] and [`ArgGroup`][crate::ArgGroup] [`Id`][crate::Id]s via [`ArgMatches::ids`].
526 /// # use clap_builder as clap;
527 /// # use clap::{Command, arg, value_parser};
529 /// let m = Command::new("myprog")
530 /// .arg(arg!(--color <when>)
531 /// .value_parser(["auto", "always", "never"]))
532 /// .arg(arg!(--config <path>)
533 /// .value_parser(value_parser!(std::path::PathBuf)))
534 /// .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
535 /// assert_eq!(m.ids().len(), 2);
538 /// .map(|id| id.as_str())
539 /// .collect::<Vec<_>>(),
540 /// ["config", "color"]
543 pub fn ids(&self) -> IdsRef
<'_
> {
545 iter
: self.args
.keys(),
549 /// Check if any args were present on the command line
554 /// # use clap_builder as clap;
555 /// # use clap::{Command, Arg, ArgAction};
556 /// let mut cmd = Command::new("myapp")
557 /// .arg(Arg::new("output")
558 /// .action(ArgAction::Set));
561 /// .try_get_matches_from_mut(vec!["myapp", "something"])
563 /// assert!(m.args_present());
566 /// .try_get_matches_from_mut(vec!["myapp"])
568 /// assert!(! m.args_present());
569 pub fn args_present(&self) -> bool
{
570 !self.args
.is_empty()
573 /// Report where argument value came from
577 /// If `id` is not a valid argument or group id.
582 /// # use clap_builder as clap;
583 /// # use clap::{Command, Arg, ArgAction};
584 /// # use clap::parser::ValueSource;
585 /// let m = Command::new("myprog")
586 /// .arg(Arg::new("debug")
588 /// .action(ArgAction::SetTrue))
589 /// .get_matches_from(vec![
593 /// assert_eq!(m.value_source("debug"), Some(ValueSource::CommandLine));
596 /// [`default_value`]: crate::Arg::default_value()
597 #[cfg_attr(debug_assertions, track_caller)]
598 pub fn value_source(&self, id
: &str) -> Option
<ValueSource
> {
599 let value
= self.get_arg(id
);
601 value
.and_then(MatchedArg
::source
)
604 /// The first index of that an argument showed up.
606 /// Indices are similar to argv indices, but are not exactly 1:1.
608 /// For flags (i.e. those arguments which don't have an associated value), indices refer
609 /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
610 /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
611 /// index for `val` would be recorded. This is by design.
613 /// Besides the flag/option discrepancy, the primary difference between an argv index and clap
614 /// index, is that clap continues counting once all arguments have properly separated, whereas
615 /// an argv index does not.
617 /// The examples should clear this up.
619 /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first*
620 /// index. See [`ArgMatches::indices_of`].
624 /// If `id` is not a valid argument or group id.
628 /// The argv indices are listed in the comments below. See how they correspond to the clap
629 /// indices. Note that if it's not listed in a clap index, this is because it's not saved in
630 /// in an `ArgMatches` struct for querying.
633 /// # use clap_builder as clap;
634 /// # use clap::{Command, Arg, ArgAction};
635 /// let m = Command::new("myapp")
636 /// .arg(Arg::new("flag")
638 /// .action(ArgAction::SetTrue))
639 /// .arg(Arg::new("option")
641 /// .action(ArgAction::Set))
642 /// .get_matches_from(vec!["myapp", "-f", "-o", "val"]);
643 /// // ARGV indices: ^0 ^1 ^2 ^3
644 /// // clap indices: ^1 ^3
646 /// assert_eq!(m.index_of("flag"), Some(1));
647 /// assert_eq!(m.index_of("option"), Some(3));
650 /// Now notice, if we use one of the other styles of options:
653 /// # use clap_builder as clap;
654 /// # use clap::{Command, Arg, ArgAction};
655 /// let m = Command::new("myapp")
656 /// .arg(Arg::new("flag")
658 /// .action(ArgAction::SetTrue))
659 /// .arg(Arg::new("option")
661 /// .action(ArgAction::Set))
662 /// .get_matches_from(vec!["myapp", "-f", "-o=val"]);
663 /// // ARGV indices: ^0 ^1 ^2
664 /// // clap indices: ^1 ^3
666 /// assert_eq!(m.index_of("flag"), Some(1));
667 /// assert_eq!(m.index_of("option"), Some(3));
670 /// Things become much more complicated, or clear if we look at a more complex combination of
671 /// flags. Let's also throw in the final option style for good measure.
674 /// # use clap_builder as clap;
675 /// # use clap::{Command, Arg, ArgAction};
676 /// let m = Command::new("myapp")
677 /// .arg(Arg::new("flag")
679 /// .action(ArgAction::SetTrue))
680 /// .arg(Arg::new("flag2")
682 /// .action(ArgAction::SetTrue))
683 /// .arg(Arg::new("flag3")
685 /// .action(ArgAction::SetTrue))
686 /// .arg(Arg::new("option")
688 /// .action(ArgAction::Set))
689 /// .get_matches_from(vec!["myapp", "-fzF", "-oval"]);
690 /// // ARGV indices: ^0 ^1 ^2
691 /// // clap indices: ^1,2,3 ^5
693 /// // clap sees the above as 'myapp -f -z -F -o val'
694 /// // ^0 ^1 ^2 ^3 ^4 ^5
695 /// assert_eq!(m.index_of("flag"), Some(1));
696 /// assert_eq!(m.index_of("flag2"), Some(3));
697 /// assert_eq!(m.index_of("flag3"), Some(2));
698 /// assert_eq!(m.index_of("option"), Some(5));
701 /// One final combination of flags/options to see how they combine:
704 /// # use clap_builder as clap;
705 /// # use clap::{Command, Arg, ArgAction};
706 /// let m = Command::new("myapp")
707 /// .arg(Arg::new("flag")
709 /// .action(ArgAction::SetTrue))
710 /// .arg(Arg::new("flag2")
712 /// .action(ArgAction::SetTrue))
713 /// .arg(Arg::new("flag3")
715 /// .action(ArgAction::SetTrue))
716 /// .arg(Arg::new("option")
718 /// .action(ArgAction::Set))
719 /// .get_matches_from(vec!["myapp", "-fzFoval"]);
720 /// // ARGV indices: ^0 ^1
721 /// // clap indices: ^1,2,3^5
723 /// // clap sees the above as 'myapp -f -z -F -o val'
724 /// // ^0 ^1 ^2 ^3 ^4 ^5
725 /// assert_eq!(m.index_of("flag"), Some(1));
726 /// assert_eq!(m.index_of("flag2"), Some(3));
727 /// assert_eq!(m.index_of("flag3"), Some(2));
728 /// assert_eq!(m.index_of("option"), Some(5));
731 /// The last part to mention is when values are sent in multiple groups with a [delimiter].
734 /// # use clap_builder as clap;
735 /// # use clap::{Command, Arg};
736 /// let m = Command::new("myapp")
737 /// .arg(Arg::new("option")
739 /// .value_delimiter(',')
741 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
742 /// // ARGV indices: ^0 ^1
743 /// // clap indices: ^2 ^3 ^4
745 /// // clap sees the above as 'myapp -o val1 val2 val3'
746 /// // ^0 ^1 ^2 ^3 ^4
747 /// assert_eq!(m.index_of("option"), Some(2));
748 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
750 /// [delimiter]: crate::Arg::value_delimiter()
751 #[cfg_attr(debug_assertions, track_caller)]
752 pub fn index_of(&self, id
: &str) -> Option
<usize> {
753 let arg
= some
!(self.get_arg(id
));
754 let i
= some
!(arg
.get_index(0));
758 /// All indices an argument appeared at when parsing.
760 /// Indices are similar to argv indices, but are not exactly 1:1.
762 /// For flags (i.e. those arguments which don't have an associated value), indices refer
763 /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
764 /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
765 /// index for `val` would be recorded. This is by design.
767 /// *NOTE:* For more information about how clap indices compared to argv indices, see
768 /// [`ArgMatches::index_of`]
772 /// If `id` is not a valid argument or group id.
777 /// # use clap_builder as clap;
778 /// # use clap::{Command, Arg};
779 /// let m = Command::new("myapp")
780 /// .arg(Arg::new("option")
782 /// .value_delimiter(','))
783 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
784 /// // ARGV indices: ^0 ^1
785 /// // clap indices: ^2 ^3 ^4
787 /// // clap sees the above as 'myapp -o val1 val2 val3'
788 /// // ^0 ^1 ^2 ^3 ^4
789 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
792 /// Another quick example is when flags and options are used together
795 /// # use clap_builder as clap;
796 /// # use clap::{Command, Arg, ArgAction};
797 /// let m = Command::new("myapp")
798 /// .arg(Arg::new("option")
800 /// .action(ArgAction::Set)
801 /// .action(ArgAction::Append))
802 /// .arg(Arg::new("flag")
804 /// .action(ArgAction::Count))
805 /// .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]);
806 /// // ARGV indices: ^0 ^1 ^2 ^3 ^4 ^5 ^6
807 /// // clap indices: ^2 ^3 ^5 ^6
809 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
810 /// assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[6]);
813 /// One final example, which is an odd case; if we *don't* use value delimiter as we did with
814 /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they
815 /// would all be a single value of `val1,val2,val3`, in which case they'd only receive a single
819 /// # use clap_builder as clap;
820 /// # use clap::{Command, Arg, ArgAction};
821 /// let m = Command::new("myapp")
822 /// .arg(Arg::new("option")
824 /// .action(ArgAction::Set)
826 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
827 /// // ARGV indices: ^0 ^1
828 /// // clap indices: ^2
830 /// // clap sees the above as 'myapp -o "val1,val2,val3"'
832 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);
834 /// [`ArgMatches::index_of`]: ArgMatches::index_of()
835 /// [delimiter]: Arg::value_delimiter()
836 #[cfg_attr(debug_assertions, track_caller)]
837 pub fn indices_of(&self, id
: &str) -> Option
<Indices
<'_
>> {
838 let arg
= some
!(self.get_arg(id
));
849 /// The name and `ArgMatches` of the current [subcommand].
851 /// Subcommand values are put in a child [`ArgMatches`]
853 /// Returns `None` if the subcommand wasn't present at runtime,
858 /// # use clap_builder as clap;
859 /// # use clap::{Command, Arg, };
860 /// let app_m = Command::new("git")
861 /// .subcommand(Command::new("clone"))
862 /// .subcommand(Command::new("push"))
863 /// .subcommand(Command::new("commit"))
866 /// match app_m.subcommand() {
867 /// Some(("clone", sub_m)) => {}, // clone was used
868 /// Some(("push", sub_m)) => {}, // push was used
869 /// Some(("commit", sub_m)) => {}, // commit was used
870 /// _ => {}, // Either no subcommand or one not tested for...
874 /// Another useful scenario is when you want to support third party, or external, subcommands.
875 /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
876 /// with pattern matching!
879 /// # use clap_builder as clap;
880 /// # use std::ffi::OsString;
881 /// # use std::ffi::OsStr;
882 /// # use clap::Command;
883 /// // Assume there is an external subcommand named "subcmd"
884 /// let app_m = Command::new("myprog")
885 /// .allow_external_subcommands(true)
886 /// .get_matches_from(vec![
887 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
890 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
891 /// // string argument name
892 /// match app_m.subcommand() {
893 /// Some((external, sub_m)) => {
894 /// let ext_args: Vec<&OsStr> = sub_m.get_many::<OsString>("")
895 /// .unwrap().map(|s| s.as_os_str()).collect();
896 /// assert_eq!(external, "subcmd");
897 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
902 /// [subcommand]: crate::Command::subcommand
904 pub fn subcommand(&self) -> Option
<(&str, &ArgMatches
)> {
905 self.subcommand
.as_ref().map(|sc
| (&*sc
.name
, &sc
.matches
))
908 /// Return the name and `ArgMatches` of the current [subcommand].
910 /// Subcommand values are put in a child [`ArgMatches`]
912 /// Returns `None` if the subcommand wasn't present at runtime,
917 /// # use clap_builder as clap;
918 /// # use clap::{Command, Arg, };
919 /// let mut app_m = Command::new("git")
920 /// .subcommand(Command::new("clone"))
921 /// .subcommand(Command::new("push"))
922 /// .subcommand(Command::new("commit"))
923 /// .subcommand_required(true)
926 /// let (name, sub_m) = app_m.remove_subcommand().expect("required");
927 /// match (name.as_str(), sub_m) {
928 /// ("clone", sub_m) => {}, // clone was used
929 /// ("push", sub_m) => {}, // push was used
930 /// ("commit", sub_m) => {}, // commit was used
931 /// (name, _) => unimplemented!("{}", name),
935 /// Another useful scenario is when you want to support third party, or external, subcommands.
936 /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
937 /// with pattern matching!
940 /// # use clap_builder as clap;
941 /// # use std::ffi::OsString;
942 /// # use clap::Command;
943 /// // Assume there is an external subcommand named "subcmd"
944 /// let mut app_m = Command::new("myprog")
945 /// .allow_external_subcommands(true)
946 /// .get_matches_from(vec![
947 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag"
950 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
951 /// // string argument name
952 /// match app_m.remove_subcommand() {
953 /// Some((external, mut sub_m)) => {
954 /// let ext_args: Vec<OsString> = sub_m.remove_many("")
955 /// .expect("`file`is required")
957 /// assert_eq!(external, "subcmd");
958 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
963 /// [subcommand]: crate::Command::subcommand
964 pub fn remove_subcommand(&mut self) -> Option
<(String
, ArgMatches
)> {
965 self.subcommand
.take().map(|sc
| (sc
.name
, sc
.matches
))
968 /// The `ArgMatches` for the current [subcommand].
970 /// Subcommand values are put in a child [`ArgMatches`]
972 /// Returns `None` if the subcommand wasn't present at runtime,
976 /// If `id` is not a valid subcommand.
981 /// # use clap_builder as clap;
982 /// # use clap::{Command, Arg, ArgAction};
983 /// let app_m = Command::new("myprog")
984 /// .arg(Arg::new("debug")
986 /// .action(ArgAction::SetTrue)
988 /// .subcommand(Command::new("test")
989 /// .arg(Arg::new("opt")
991 /// .action(ArgAction::Set)))
992 /// .get_matches_from(vec![
993 /// "myprog", "-d", "test", "--option", "val"
996 /// // Both parent commands, and child subcommands can have arguments present at the same times
997 /// assert!(app_m.get_flag("debug"));
999 /// // Get the subcommand's ArgMatches instance
1000 /// if let Some(sub_m) = app_m.subcommand_matches("test") {
1001 /// // Use the struct like normal
1002 /// assert_eq!(sub_m.get_one::<String>("opt").map(|s| s.as_str()), Some("val"));
1006 /// [subcommand]: crate::Command::subcommand
1007 /// [`Command`]: crate::Command
1008 pub fn subcommand_matches(&self, name
: &str) -> Option
<&ArgMatches
> {
1009 self.get_subcommand(name
).map(|sc
| &sc
.matches
)
1012 /// The name of the current [subcommand].
1014 /// Returns `None` if the subcommand wasn't present at runtime,
1019 /// # use clap_builder as clap;
1020 /// # use clap::{Command, Arg, };
1021 /// let app_m = Command::new("git")
1022 /// .subcommand(Command::new("clone"))
1023 /// .subcommand(Command::new("push"))
1024 /// .subcommand(Command::new("commit"))
1027 /// match app_m.subcommand_name() {
1028 /// Some("clone") => {}, // clone was used
1029 /// Some("push") => {}, // push was used
1030 /// Some("commit") => {}, // commit was used
1031 /// _ => {}, // Either no subcommand or one not tested for...
1034 /// [subcommand]: crate::Command::subcommand
1035 /// [`Command`]: crate::Command
1037 pub fn subcommand_name(&self) -> Option
<&str> {
1038 self.subcommand
.as_ref().map(|sc
| &*sc
.name
)
1041 /// Check if a subcommand can be queried
1043 /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer
1044 /// mistakes. In some context, this doesn't work, so users can use this function to check
1045 /// before they do a query on `ArgMatches`.
1048 pub fn is_valid_subcommand(&self, _name
: &str) -> bool
{
1049 #[cfg(debug_assertions)]
1051 _name
.is_empty() || self.valid_subcommands
.iter().any(|s
| *s
== _name
)
1053 #[cfg(not(debug_assertions))]
1062 /// Non-panicking version of [`ArgMatches::get_one`]
1063 pub fn try_get_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1066 ) -> Result
<Option
<&T
>, MatchesError
> {
1067 let arg
= ok
!(self.try_get_arg_t
::<T
>(id
));
1068 let value
= match arg
.and_then(|a
| a
.first()) {
1069 Some(value
) => value
,
1075 .downcast_ref
::<T
>()
1077 .expect(INTERNAL_ERROR_MSG
)) // enforced by `try_get_arg_t`
1080 /// Non-panicking version of [`ArgMatches::get_many`]
1081 pub fn try_get_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1084 ) -> Result
<Option
<ValuesRef
<T
>>, MatchesError
> {
1085 let arg
= match ok
!(self.try_get_arg_t
::<T
>(id
)) {
1087 None
=> return Ok(None
),
1089 let len
= arg
.num_vals();
1090 let values
= arg
.vals_flatten();
1091 let values
= ValuesRef
{
1092 // enforced by `try_get_arg_t`
1093 iter
: values
.map(unwrap_downcast_ref
),
1099 /// Non-panicking version of [`ArgMatches::get_occurrences`]
1100 pub fn try_get_occurrences
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1103 ) -> Result
<Option
<OccurrencesRef
<T
>>, MatchesError
> {
1104 let arg
= match ok
!(self.try_get_arg_t
::<T
>(id
)) {
1106 None
=> return Ok(None
),
1108 let values
= arg
.vals();
1109 Ok(Some(OccurrencesRef
{
1110 iter
: values
.map(|g
| OccurrenceValuesRef
{
1111 iter
: g
.iter().map(unwrap_downcast_ref
),
1116 /// Non-panicking version of [`ArgMatches::get_raw`]
1117 pub fn try_get_raw(&self, id
: &str) -> Result
<Option
<RawValues
<'_
>>, MatchesError
> {
1118 let arg
= match ok
!(self.try_get_arg(id
)) {
1120 None
=> return Ok(None
),
1122 let len
= arg
.num_vals();
1123 let values
= arg
.raw_vals_flatten();
1124 let values
= RawValues
{
1125 iter
: values
.map(OsString
::as_os_str
),
1131 /// Non-panicking version of [`ArgMatches::get_raw_occurrences`]
1132 pub fn try_get_raw_occurrences(
1135 ) -> Result
<Option
<RawOccurrences
<'_
>>, MatchesError
> {
1136 let arg
= match ok
!(self.try_get_arg(id
)) {
1138 None
=> return Ok(None
),
1140 let values
= arg
.raw_vals();
1141 let occurrences
= RawOccurrences
{
1142 iter
: values
.map(|g
| RawOccurrenceValues
{
1143 iter
: g
.iter().map(OsString
::as_os_str
),
1146 Ok(Some(occurrences
))
1149 /// Non-panicking version of [`ArgMatches::remove_one`]
1150 pub fn try_remove_one
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1153 ) -> Result
<Option
<T
>, MatchesError
> {
1154 match ok
!(self.try_remove_arg_t
::<T
>(id
)) {
1155 Some(values
) => Ok(values
1156 .into_vals_flatten()
1157 // enforced by `try_get_arg_t`
1158 .map(unwrap_downcast_into
)
1164 /// Non-panicking version of [`ArgMatches::remove_many`]
1165 pub fn try_remove_many
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1168 ) -> Result
<Option
<Values
<T
>>, MatchesError
> {
1169 let arg
= match ok
!(self.try_remove_arg_t
::<T
>(id
)) {
1171 None
=> return Ok(None
),
1173 let len
= arg
.num_vals();
1174 let values
= arg
.into_vals_flatten();
1175 let values
= Values
{
1176 // enforced by `try_get_arg_t`
1177 iter
: values
.map(unwrap_downcast_into
),
1183 /// Non-panicking version of [`ArgMatches::remove_occurrences`]
1184 pub fn try_remove_occurrences
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(
1187 ) -> Result
<Option
<Occurrences
<T
>>, MatchesError
> {
1188 let arg
= match ok
!(self.try_remove_arg_t
::<T
>(id
)) {
1190 None
=> return Ok(None
),
1192 let values
= arg
.into_vals();
1193 let occurrences
= Occurrences
{
1194 iter
: values
.into_iter().map(|g
| OccurrenceValues
{
1195 iter
: g
.into_iter().map(unwrap_downcast_into
),
1198 Ok(Some(occurrences
))
1201 /// Non-panicking version of [`ArgMatches::contains_id`]
1202 pub fn try_contains_id(&self, id
: &str) -> Result
<bool
, MatchesError
> {
1203 ok
!(self.verify_arg(id
));
1205 let presence
= self.args
.contains_key(id
);
1213 fn try_get_arg(&self, arg
: &str) -> Result
<Option
<&MatchedArg
>, MatchesError
> {
1214 ok
!(self.verify_arg(arg
));
1215 Ok(self.args
.get(arg
))
1219 fn try_get_arg_t
<T
: Any
+ Send
+ Sync
+ '
static>(
1222 ) -> Result
<Option
<&MatchedArg
>, MatchesError
> {
1223 let arg
= match ok
!(self.try_get_arg(arg
)) {
1229 ok
!(self.verify_arg_t
::<T
>(arg
));
1234 fn try_remove_arg_t
<T
: Any
+ Send
+ Sync
+ '
static>(
1237 ) -> Result
<Option
<MatchedArg
>, MatchesError
> {
1238 ok
!(self.verify_arg(arg
));
1239 let (id
, matched
) = match self.args
.remove_entry(arg
) {
1240 Some((id
, matched
)) => (id
, matched
),
1246 let expected
= AnyValueId
::of
::<T
>();
1247 let actual
= matched
.infer_type_id(expected
);
1248 if actual
== expected
{
1251 self.args
.insert(id
, matched
);
1252 Err(MatchesError
::Downcast { actual, expected }
)
1256 fn verify_arg_t
<T
: Any
+ Send
+ Sync
+ '
static>(
1259 ) -> Result
<(), MatchesError
> {
1260 let expected
= AnyValueId
::of
::<T
>();
1261 let actual
= arg
.infer_type_id(expected
);
1262 if expected
== actual
{
1265 Err(MatchesError
::Downcast { actual, expected }
)
1270 fn verify_arg(&self, _arg
: &str) -> Result
<(), MatchesError
> {
1271 #[cfg(debug_assertions)]
1273 if _arg
== Id
::EXTERNAL
|| self.valid_args
.iter().any(|s
| *s
== _arg
) {
1276 "`{:?}` is not an id of an argument or a group.\n\
1277 Make sure you're using the name of the argument itself \
1278 and not the name of short or long flags.",
1281 return Err(MatchesError
::UnknownArgument {}
);
1288 #[cfg_attr(debug_assertions, track_caller)]
1289 fn get_arg
<'s
>(&'s
self, arg
: &str) -> Option
<&'s MatchedArg
> {
1290 #[cfg(debug_assertions)]
1292 if arg
== Id
::EXTERNAL
|| self.valid_args
.iter().any(|s
| *s
== arg
) {
1295 "`{arg:?}` is not an id of an argument or a group.\n\
1296 Make sure you're using the name of the argument itself \
1297 and not the name of short or long flags."
1306 #[cfg_attr(debug_assertions, track_caller)]
1307 fn get_subcommand(&self, name
: &str) -> Option
<&SubCommand
> {
1308 #[cfg(debug_assertions)]
1310 if name
.is_empty() || self.valid_subcommands
.iter().any(|s
| *s
== name
) {
1312 panic
!("`{name}` is not a name of a subcommand.");
1316 if let Some(ref sc
) = self.subcommand
{
1317 if sc
.name
== name
{
1326 #[derive(Debug, Clone, PartialEq, Eq)]
1327 pub(crate) struct SubCommand
{
1328 pub(crate) name
: String
,
1329 pub(crate) matches
: ArgMatches
,
1332 /// Iterate over [`Arg`][crate::Arg] and [`ArgGroup`][crate::ArgGroup] [`Id`][crate::Id]s via [`ArgMatches::ids`].
1337 /// # use clap_builder as clap;
1338 /// # use clap::{Command, arg, value_parser};
1340 /// let m = Command::new("myprog")
1341 /// .arg(arg!(--color <when>)
1342 /// .value_parser(["auto", "always", "never"]))
1343 /// .arg(arg!(--config <path>)
1344 /// .value_parser(value_parser!(std::path::PathBuf)))
1345 /// .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
1348 /// .map(|id| id.as_str())
1349 /// .collect::<Vec<_>>(),
1350 /// ["config", "color"]
1353 #[derive(Clone, Debug)]
1354 pub struct IdsRef
<'a
> {
1355 iter
: std
::slice
::Iter
<'a
, Id
>,
1358 impl<'a
> Iterator
for IdsRef
<'a
> {
1361 fn next(&mut self) -> Option
<&'a Id
> {
1364 fn size_hint(&self) -> (usize, Option
<usize>) {
1365 self.iter
.size_hint()
1369 impl<'a
> DoubleEndedIterator
for IdsRef
<'a
> {
1370 fn next_back(&mut self) -> Option
<&'a Id
> {
1371 self.iter
.next_back()
1375 impl<'a
> ExactSizeIterator
for IdsRef
<'a
> {}
1377 /// Iterate over multiple values for an argument via [`ArgMatches::remove_many`].
1382 /// # use clap_builder as clap;
1383 /// # use clap::{Command, Arg, ArgAction};
1384 /// let mut m = Command::new("myapp")
1385 /// .arg(Arg::new("output")
1387 /// .action(ArgAction::Append))
1388 /// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1390 /// let mut values = m.remove_many::<String>("output")
1393 /// assert_eq!(values.next(), Some(String::from("val1")));
1394 /// assert_eq!(values.next(), Some(String::from("val2")));
1395 /// assert_eq!(values.next(), None);
1397 #[derive(Clone, Debug)]
1398 pub struct Values
<T
> {
1399 #[allow(clippy::type_complexity)]
1400 iter
: Map
<Flatten
<std
::vec
::IntoIter
<Vec
<AnyValue
>>>, fn(AnyValue
) -> T
>,
1404 impl<T
> Iterator
for Values
<T
> {
1407 fn next(&mut self) -> Option
<Self::Item
> {
1410 fn size_hint(&self) -> (usize, Option
<usize>) {
1411 (self.len
, Some(self.len
))
1415 impl<T
> DoubleEndedIterator
for Values
<T
> {
1416 fn next_back(&mut self) -> Option
<Self::Item
> {
1417 self.iter
.next_back()
1421 impl<T
> ExactSizeIterator
for Values
<T
> {}
1423 /// Creates an empty iterator.
1424 impl<T
> Default
for Values
<T
> {
1425 fn default() -> Self {
1426 let empty
: Vec
<Vec
<AnyValue
>> = Default
::default();
1428 iter
: empty
.into_iter().flatten().map(|_
| unreachable
!()),
1434 /// Iterate over multiple values for an argument via [`ArgMatches::get_many`].
1439 /// # use clap_builder as clap;
1440 /// # use clap::{Command, Arg, ArgAction};
1441 /// let m = Command::new("myapp")
1442 /// .arg(Arg::new("output")
1444 /// .action(ArgAction::Append))
1445 /// .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1447 /// let mut values = m.get_many::<String>("output")
1449 /// .map(|s| s.as_str());
1451 /// assert_eq!(values.next(), Some("val1"));
1452 /// assert_eq!(values.next(), Some("val2"));
1453 /// assert_eq!(values.next(), None);
1455 #[derive(Clone, Debug)]
1456 pub struct ValuesRef
<'a
, T
> {
1457 #[allow(clippy::type_complexity)]
1458 iter
: Map
<Flatten
<Iter
<'a
, Vec
<AnyValue
>>>, fn(&AnyValue
) -> &T
>,
1462 impl<'a
, T
: 'a
> Iterator
for ValuesRef
<'a
, T
> {
1465 fn next(&mut self) -> Option
<Self::Item
> {
1468 fn size_hint(&self) -> (usize, Option
<usize>) {
1469 (self.len
, Some(self.len
))
1473 impl<'a
, T
: 'a
> DoubleEndedIterator
for ValuesRef
<'a
, T
> {
1474 fn next_back(&mut self) -> Option
<Self::Item
> {
1475 self.iter
.next_back()
1479 impl<'a
, T
: 'a
> ExactSizeIterator
for ValuesRef
<'a
, T
> {}
1481 /// Creates an empty iterator.
1482 impl<'a
, T
: 'a
> Default
for ValuesRef
<'a
, T
> {
1483 fn default() -> Self {
1484 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1486 iter
: EMPTY
[..].iter().flatten().map(|_
| unreachable
!()),
1492 /// Iterate over raw argument values via [`ArgMatches::get_raw`].
1497 /// # #[cfg(unix)] {
1498 /// # use clap_builder as clap;
1499 /// # use clap::{Command, arg, value_parser};
1500 /// use std::ffi::OsString;
1501 /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
1503 /// let m = Command::new("utf8")
1504 /// .arg(arg!(<arg> "some arg")
1505 /// .value_parser(value_parser!(OsString)))
1506 /// .get_matches_from(vec![OsString::from("myprog"),
1508 /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
1510 /// &*m.get_raw("arg")
1512 /// .next().unwrap()
1514 /// [b'H', b'i', b' ', 0xe9, b'!']
1518 #[derive(Clone, Debug)]
1519 pub struct RawValues
<'a
> {
1520 #[allow(clippy::type_complexity)]
1521 iter
: Map
<Flatten
<Iter
<'a
, Vec
<OsString
>>>, fn(&OsString
) -> &OsStr
>,
1525 impl<'a
> Iterator
for RawValues
<'a
> {
1526 type Item
= &'a OsStr
;
1528 fn next(&mut self) -> Option
<&'a OsStr
> {
1531 fn size_hint(&self) -> (usize, Option
<usize>) {
1532 (self.len
, Some(self.len
))
1536 impl<'a
> DoubleEndedIterator
for RawValues
<'a
> {
1537 fn next_back(&mut self) -> Option
<&'a OsStr
> {
1538 self.iter
.next_back()
1542 impl<'a
> ExactSizeIterator
for RawValues
<'a
> {}
1544 /// Creates an empty iterator.
1545 impl Default
for RawValues
<'_
> {
1546 fn default() -> Self {
1547 static EMPTY
: [Vec
<OsString
>; 0] = [];
1549 iter
: EMPTY
[..].iter().flatten().map(|_
| unreachable
!()),
1555 // The following were taken and adapted from vec_map source
1556 // repo: https://github.com/contain-rs/vec-map
1557 // commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
1558 // license: MIT - Copyright (c) 2015 The Rust Project Developers
1560 #[derive(Clone, Debug)]
1561 #[deprecated(since = "4.1.0", note = "Use Occurrences instead")]
1562 pub struct GroupedValues
<'a
> {
1563 #[allow(clippy::type_complexity)]
1564 iter
: Map
<Iter
<'a
, Vec
<AnyValue
>>, fn(&Vec
<AnyValue
>) -> Vec
<&str>>,
1568 #[allow(deprecated)]
1569 impl<'a
> Iterator
for GroupedValues
<'a
> {
1570 type Item
= Vec
<&'a
str>;
1572 fn next(&mut self) -> Option
<Self::Item
> {
1575 fn size_hint(&self) -> (usize, Option
<usize>) {
1576 (self.len
, Some(self.len
))
1580 #[allow(deprecated)]
1581 impl<'a
> DoubleEndedIterator
for GroupedValues
<'a
> {
1582 fn next_back(&mut self) -> Option
<Self::Item
> {
1583 self.iter
.next_back()
1587 #[allow(deprecated)]
1588 impl<'a
> ExactSizeIterator
for GroupedValues
<'a
> {}
1590 /// Creates an empty iterator. Used for `unwrap_or_default()`.
1591 #[allow(deprecated)]
1592 impl<'a
> Default
for GroupedValues
<'a
> {
1593 fn default() -> Self {
1594 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1596 iter
: EMPTY
[..].iter().map(|_
| unreachable
!()),
1602 #[derive(Clone, Debug)]
1603 pub struct Occurrences
<T
> {
1604 #[allow(clippy::type_complexity)]
1605 iter
: Map
<std
::vec
::IntoIter
<Vec
<AnyValue
>>, fn(Vec
<AnyValue
>) -> OccurrenceValues
<T
>>,
1608 impl<T
> Iterator
for Occurrences
<T
> {
1609 type Item
= OccurrenceValues
<T
>;
1611 fn next(&mut self) -> Option
<Self::Item
> {
1615 fn size_hint(&self) -> (usize, Option
<usize>) {
1616 self.iter
.size_hint()
1620 impl<T
> DoubleEndedIterator
for Occurrences
<T
> {
1621 fn next_back(&mut self) -> Option
<Self::Item
> {
1622 self.iter
.next_back()
1626 impl<T
> ExactSizeIterator
for Occurrences
<T
> {}
1628 impl<T
> Default
for Occurrences
<T
> {
1629 fn default() -> Self {
1630 let empty
: Vec
<Vec
<AnyValue
>> = Default
::default();
1632 iter
: empty
.into_iter().map(|_
| unreachable
!()),
1637 #[derive(Clone, Debug)]
1638 pub struct OccurrenceValues
<T
> {
1639 #[allow(clippy::type_complexity)]
1640 iter
: Map
<std
::vec
::IntoIter
<AnyValue
>, fn(AnyValue
) -> T
>,
1643 impl<T
> Iterator
for OccurrenceValues
<T
> {
1646 fn next(&mut self) -> Option
<Self::Item
> {
1650 fn size_hint(&self) -> (usize, Option
<usize>) {
1651 self.iter
.size_hint()
1655 impl<T
> DoubleEndedIterator
for OccurrenceValues
<T
> {
1656 fn next_back(&mut self) -> Option
<Self::Item
> {
1657 self.iter
.next_back()
1661 impl<T
> ExactSizeIterator
for OccurrenceValues
<T
> {}
1663 #[derive(Clone, Debug)]
1664 pub struct OccurrencesRef
<'a
, T
> {
1665 #[allow(clippy::type_complexity)]
1666 iter
: Map
<Iter
<'a
, Vec
<AnyValue
>>, fn(&Vec
<AnyValue
>) -> OccurrenceValuesRef
<'_
, T
>>,
1669 impl<'a
, T
> Iterator
for OccurrencesRef
<'a
, T
>
1673 type Item
= OccurrenceValuesRef
<'a
, T
>;
1675 fn next(&mut self) -> Option
<Self::Item
> {
1679 fn size_hint(&self) -> (usize, Option
<usize>) {
1680 self.iter
.size_hint()
1684 impl<'a
, T
> DoubleEndedIterator
for OccurrencesRef
<'a
, T
>
1688 fn next_back(&mut self) -> Option
<Self::Item
> {
1689 self.iter
.next_back()
1693 impl<'a
, T
> ExactSizeIterator
for OccurrencesRef
<'a
, T
> where Self: 'a {}
1694 impl<'a
, T
> Default
for OccurrencesRef
<'a
, T
> {
1695 fn default() -> Self {
1696 static EMPTY
: [Vec
<AnyValue
>; 0] = [];
1698 iter
: EMPTY
[..].iter().map(|_
| unreachable
!()),
1703 #[derive(Clone, Debug)]
1704 pub struct OccurrenceValuesRef
<'a
, T
> {
1705 #[allow(clippy::type_complexity)]
1706 iter
: Map
<Iter
<'a
, AnyValue
>, fn(&AnyValue
) -> &T
>,
1709 impl<'a
, T
> Iterator
for OccurrenceValuesRef
<'a
, T
>
1715 fn next(&mut self) -> Option
<Self::Item
> {
1719 fn size_hint(&self) -> (usize, Option
<usize>) {
1720 self.iter
.size_hint()
1724 impl<'a
, T
> DoubleEndedIterator
for OccurrenceValuesRef
<'a
, T
>
1728 fn next_back(&mut self) -> Option
<Self::Item
> {
1729 self.iter
.next_back()
1733 impl<'a
, T
> ExactSizeIterator
for OccurrenceValuesRef
<'a
, T
> where Self: 'a {}
1735 #[derive(Clone, Debug)]
1736 pub struct RawOccurrences
<'a
> {
1737 #[allow(clippy::type_complexity)]
1738 iter
: Map
<Iter
<'a
, Vec
<OsString
>>, fn(&Vec
<OsString
>) -> RawOccurrenceValues
<'_
>>,
1741 impl<'a
> Iterator
for RawOccurrences
<'a
> {
1742 type Item
= RawOccurrenceValues
<'a
>;
1744 fn next(&mut self) -> Option
<Self::Item
> {
1748 fn size_hint(&self) -> (usize, Option
<usize>) {
1749 self.iter
.size_hint()
1753 impl<'a
> DoubleEndedIterator
for RawOccurrences
<'a
> {
1754 fn next_back(&mut self) -> Option
<Self::Item
> {
1755 self.iter
.next_back()
1759 impl<'a
> ExactSizeIterator
for RawOccurrences
<'a
> {}
1761 impl<'a
> Default
for RawOccurrences
<'a
> {
1762 fn default() -> Self {
1763 static EMPTY
: [Vec
<OsString
>; 0] = [];
1765 iter
: EMPTY
[..].iter().map(|_
| unreachable
!()),
1770 #[derive(Clone, Debug)]
1771 pub struct RawOccurrenceValues
<'a
> {
1772 #[allow(clippy::type_complexity)]
1773 iter
: Map
<Iter
<'a
, OsString
>, fn(&OsString
) -> &OsStr
>,
1776 impl<'a
> Iterator
for RawOccurrenceValues
<'a
>
1780 type Item
= &'a OsStr
;
1782 fn next(&mut self) -> Option
<Self::Item
> {
1786 fn size_hint(&self) -> (usize, Option
<usize>) {
1787 self.iter
.size_hint()
1791 impl<'a
> DoubleEndedIterator
for RawOccurrenceValues
<'a
>
1795 fn next_back(&mut self) -> Option
<Self::Item
> {
1796 self.iter
.next_back()
1800 impl<'a
> ExactSizeIterator
for RawOccurrenceValues
<'a
> {}
1802 /// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
1807 /// # use clap_builder as clap;
1808 /// # use clap::{Command, Arg, ArgAction};
1809 /// let m = Command::new("myapp")
1810 /// .arg(Arg::new("output")
1813 /// .action(ArgAction::Set))
1814 /// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
1816 /// let mut indices = m.indices_of("output").unwrap();
1818 /// assert_eq!(indices.next(), Some(2));
1819 /// assert_eq!(indices.next(), Some(3));
1820 /// assert_eq!(indices.next(), None);
1822 /// [`ArgMatches::indices_of`]: ArgMatches::indices_of()
1823 #[derive(Clone, Debug)]
1824 pub struct Indices
<'a
> {
1825 iter
: Cloned
<Iter
<'a
, usize>>,
1829 impl<'a
> Iterator
for Indices
<'a
> {
1832 fn next(&mut self) -> Option
<usize> {
1835 fn size_hint(&self) -> (usize, Option
<usize>) {
1836 (self.len
, Some(self.len
))
1840 impl<'a
> DoubleEndedIterator
for Indices
<'a
> {
1841 fn next_back(&mut self) -> Option
<usize> {
1842 self.iter
.next_back()
1846 impl<'a
> ExactSizeIterator
for Indices
<'a
> {}
1848 /// Creates an empty iterator.
1849 impl<'a
> Default
for Indices
<'a
> {
1850 fn default() -> Self {
1851 static EMPTY
: [usize; 0] = [];
1852 // This is never called because the iterator is empty:
1854 iter
: EMPTY
[..].iter().cloned(),
1861 fn unwrap_downcast_ref
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(value
: &AnyValue
) -> &T
{
1862 value
.downcast_ref().expect(INTERNAL_ERROR_MSG
)
1866 fn unwrap_downcast_into
<T
: Any
+ Clone
+ Send
+ Sync
+ '
static>(value
: AnyValue
) -> T
{
1867 value
.downcast_into().expect(INTERNAL_ERROR_MSG
)
1874 use crate::ArgAction
;
1877 fn check_auto_traits() {
1878 static_assertions
::assert_impl_all
!(ArgMatches
: Send
, Sync
, Unpin
);
1882 fn test_default_raw_values() {
1883 let mut values
: RawValues
= Default
::default();
1884 assert_eq
!(values
.next(), None
);
1888 fn test_default_indices() {
1889 let mut indices
: Indices
= Indices
::default();
1890 assert_eq
!(indices
.next(), None
);
1894 fn test_default_indices_with_shorter_lifetime() {
1895 let matches
= ArgMatches
::default();
1896 let mut indices
= matches
.indices_of("").unwrap_or_default();
1897 assert_eq
!(indices
.next(), None
);
1901 fn values_exact_size() {
1902 let l
= crate::Command
::new("test")
1904 crate::Arg
::new("POTATO")
1905 .action(ArgAction
::Set
)
1909 .try_get_matches_from(["test", "one"])
1911 .get_many
::<String
>("POTATO")
1918 fn os_values_exact_size() {
1919 let l
= crate::Command
::new("test")
1921 crate::Arg
::new("POTATO")
1922 .action(ArgAction
::Set
)
1924 .value_parser(crate::builder
::ValueParser
::os_string())
1927 .try_get_matches_from(["test", "one"])
1929 .get_many
::<std
::ffi
::OsString
>("POTATO")
1936 fn indices_exact_size() {
1937 let l
= crate::Command
::new("test")
1939 crate::Arg
::new("POTATO")
1940 .action(ArgAction
::Set
)
1944 .try_get_matches_from(["test", "one"])
1946 .indices_of("POTATO")