clap_builder/parser/matches/
arg_matches.rs

1// Std
2use std::any::Any;
3use std::ffi::{OsStr, OsString};
4use std::fmt::Debug;
5use std::iter::{Cloned, Flatten, Map};
6use std::slice::Iter;
7
8// Internal
9#[cfg(debug_assertions)]
10use crate::builder::Str;
11use crate::parser::MatchedArg;
12use crate::parser::MatchesError;
13use crate::parser::ValueSource;
14use crate::util::AnyValue;
15use crate::util::AnyValueId;
16use crate::util::FlatMap;
17use crate::util::Id;
18use crate::INTERNAL_ERROR_MSG;
19
20/// Container for parse results.
21///
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
24/// methods.
25///
26/// # Examples
27///
28/// ```no_run
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")
34///         .long("output")
35///         .required(true)
36///         .action(ArgAction::Set)
37///         .default_value("-"))
38///     .arg(Arg::new("cfg")
39///         .short('c')
40///         .action(ArgAction::Set))
41///     .get_matches(); // builds the instance of ArgMatches
42///
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}");
47/// }
48///
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());
54///
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");
60///     } else {
61///         println!("`out` is defaulted");
62///     }
63/// }
64/// ```
65/// [`Command::get_matches`]: crate::Command::get_matches()
66#[derive(Debug, Clone, Default, PartialEq, Eq)]
67pub 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>>,
74}
75
76/// # Arguments
77impl ArgMatches {
78    /// Gets the value of a specific option or positional argument.
79    ///
80    /// i.e. an argument that [takes an additional value][crate::Arg::num_args] at runtime.
81    ///
82    /// Returns an error if the wrong type was used.
83    ///
84    /// Returns `None` if the option wasn't present.
85    ///
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.
88    ///
89    /// # Panic
90    ///
91    /// If the argument definition and access mismatch.  To handle this case programmatically, see
92    /// [`ArgMatches::try_get_one`].
93    ///
94    /// # Examples
95    ///
96    /// ```rust
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)
103    ///         .required(true))
104    ///     .get_matches_from(vec!["myapp", "2020"]);
105    ///
106    /// let port: usize = *m
107    ///     .get_one("port")
108    ///     .expect("`port`is required");
109    /// assert_eq!(port, 2020);
110    /// ```
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))
116    }
117
118    /// Gets the value of a specific [`ArgAction::Count`][crate::ArgAction::Count] flag
119    ///
120    /// # Panic
121    ///
122    /// If the argument's action is not [`ArgAction::Count`][crate::ArgAction::Count]
123    ///
124    /// # Examples
125    ///
126    /// ```rust
127    /// # use clap_builder as clap;
128    /// # use clap::Command;
129    /// # use clap::Arg;
130    /// let cmd = Command::new("mycmd")
131    ///     .arg(
132    ///         Arg::new("flag")
133    ///             .long("flag")
134    ///             .action(clap::ArgAction::Count)
135    ///     );
136    ///
137    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag", "--flag"]).unwrap();
138    /// assert_eq!(
139    ///     matches.get_count("flag"),
140    ///     2
141    /// );
142    /// ```
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(|| {
146            panic!("arg `{id}`'s `ArgAction` should be `Count` which should provide a default")
147        })
148    }
149
150    /// Gets the value of a specific [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse] flag
151    ///
152    /// # Panic
153    ///
154    /// If the argument's action is not [`ArgAction::SetTrue`][crate::ArgAction::SetTrue] or [`ArgAction::SetFalse`][crate::ArgAction::SetFalse]
155    ///
156    /// # Examples
157    ///
158    /// ```rust
159    /// # use clap_builder as clap;
160    /// # use clap::Command;
161    /// # use clap::Arg;
162    /// let cmd = Command::new("mycmd")
163    ///     .arg(
164    ///         Arg::new("flag")
165    ///             .long("flag")
166    ///             .action(clap::ArgAction::SetTrue)
167    ///     );
168    ///
169    /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
170    /// assert!(matches.contains_id("flag"));
171    /// assert_eq!(
172    ///     matches.get_flag("flag"),
173    ///     true
174    /// );
175    /// ```
176    #[cfg_attr(debug_assertions, track_caller)]
177    pub fn get_flag(&self, id: &str) -> bool {
178        *self
179            .get_one::<bool>(id)
180            .unwrap_or_else(|| {
181                panic!(
182                    "arg `{id}`'s `ArgAction` should be one of `SetTrue`, `SetFalse` which should provide a default"
183                )
184            })
185    }
186
187    /// Iterate over values of a specific option or positional argument.
188    ///
189    /// i.e. an argument that takes multiple values at runtime.
190    ///
191    /// Returns an error if the wrong type was used.
192    ///
193    /// Returns `None` if the option wasn't present.
194    ///
195    /// # Panic
196    ///
197    /// If the argument definition and access mismatch.  To handle this case programmatically, see
198    /// [`ArgMatches::try_get_many`].
199    ///
200    /// # Examples
201    ///
202    /// ```rust
203    /// # use clap_builder as clap;
204    /// # use clap::{Command, Arg, value_parser, ArgAction};
205    /// let m = Command::new("myprog")
206    ///     .arg(Arg::new("ports")
207    ///         .action(ArgAction::Append)
208    ///         .value_parser(value_parser!(usize))
209    ///         .short('p')
210    ///         .required(true))
211    ///     .get_matches_from(vec![
212    ///         "myprog", "-p", "22", "-p", "80", "-p", "2020"
213    ///     ]);
214    /// let vals: Vec<usize> = m.get_many("ports")
215    ///     .expect("`port`is required")
216    ///     .copied()
217    ///     .collect();
218    /// assert_eq!(vals, [22, 80, 2020]);
219    /// ```
220    #[cfg_attr(debug_assertions, track_caller)]
221    pub fn get_many<T: Any + Clone + Send + Sync + 'static>(
222        &self,
223        id: &str,
224    ) -> Option<ValuesRef<'_, T>> {
225        MatchesError::unwrap(id, self.try_get_many(id))
226    }
227
228    /// Iterate over the values passed to each occurrence of an option.
229    ///
230    /// Each item is itself an iterator containing the arguments passed to a single occurrence
231    /// of the option.
232    ///
233    /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
234    /// the iterator will only contain a single item.
235    ///
236    /// Returns `None` if the option wasn't present.
237    ///
238    /// # Panics
239    ///
240    /// If the argument definition and access mismatch (debug builds). To handle this case programmatically, see
241    /// [`ArgMatches::try_get_occurrences`].
242    ///
243    /// # Examples
244    /// ```rust
245    /// # use clap_builder as clap;
246    /// # use clap::{Command,Arg, ArgAction, value_parser};
247    /// let m = Command::new("myprog")
248    ///     .arg(Arg::new("x")
249    ///         .short('x')
250    ///         .num_args(2)
251    ///         .action(ArgAction::Append)
252    ///         .value_parser(value_parser!(String)))
253    ///     .get_matches_from(vec![
254    ///         "myprog", "-x", "a", "b", "-x", "c", "d"]);
255    /// let vals: Vec<Vec<&String>> = m.get_occurrences("x").unwrap().map(Iterator::collect).collect();
256    /// assert_eq!(vals, [["a", "b"], ["c", "d"]]);
257    /// ```
258    #[cfg_attr(debug_assertions, track_caller)]
259    pub fn get_occurrences<T: Any + Clone + Send + Sync + 'static>(
260        &self,
261        id: &str,
262    ) -> Option<OccurrencesRef<'_, T>> {
263        MatchesError::unwrap(id, self.try_get_occurrences(id))
264    }
265
266    /// Iterate over the original argument values.
267    ///
268    /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
269    /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
270    /// filename on a Unix system as an argument value may contain invalid UTF-8.
271    ///
272    /// Returns `None` if the option wasn't present.
273    ///
274    /// # Panic
275    ///
276    /// If the argument definition and access mismatch.  To handle this case programmatically, see
277    /// [`ArgMatches::try_get_raw`].
278    ///
279    /// # Examples
280    ///
281    /// ```rust
282    /// # #[cfg(unix)] {
283    /// # use clap_builder as clap;
284    /// # use clap::{Command, arg, value_parser};
285    /// # use std::ffi::{OsStr,OsString};
286    /// # use std::os::unix::ffi::{OsStrExt,OsStringExt};
287    /// use std::path::PathBuf;
288    ///
289    /// let m = Command::new("utf8")
290    ///     .arg(arg!(<arg> ... "some arg").value_parser(value_parser!(PathBuf)))
291    ///     .get_matches_from(vec![OsString::from("myprog"),
292    ///                                 // "Hi"
293    ///                                 OsString::from_vec(vec![b'H', b'i']),
294    ///                                 // "{0xe9}!"
295    ///                                 OsString::from_vec(vec![0xe9, b'!'])]);
296    ///
297    /// let mut itr = m.get_raw("arg")
298    ///     .expect("`port`is required")
299    ///     .into_iter();
300    /// assert_eq!(itr.next(), Some(OsStr::new("Hi")));
301    /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!'])));
302    /// assert_eq!(itr.next(), None);
303    /// # }
304    /// ```
305    /// [`Iterator`]: std::iter::Iterator
306    /// [`OsSt`]: std::ffi::OsStr
307    /// [values]: OsValues
308    /// [`String`]: std::string::String
309    #[cfg_attr(debug_assertions, track_caller)]
310    pub fn get_raw(&self, id: &str) -> Option<RawValues<'_>> {
311        MatchesError::unwrap(id, self.try_get_raw(id))
312    }
313
314    /// Iterate over the original values for each occurrence of an option.
315    ///
316    /// Similar to [`ArgMatches::get_occurrences`] but returns raw values.
317    ///
318    /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
319    /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
320    /// filename on a Unix system as an argument value may contain invalid UTF-8.
321    ///
322    /// Returns `None` if the option wasn't present.
323    ///
324    /// # Panic
325    ///
326    /// If the argument definition and access mismatch.  To handle this case programmatically, see
327    /// [`ArgMatches::try_get_raw_occurrences`].
328    ///
329    /// # Examples
330    ///
331    /// ```rust
332    /// # #[cfg(unix)] {
333    /// # use clap_builder as clap;
334    /// # use clap::{Command, arg, value_parser, ArgAction, Arg};
335    /// # use std::ffi::{OsStr,OsString};
336    /// # use std::os::unix::ffi::{OsStrExt,OsStringExt};
337    /// use std::path::PathBuf;
338    ///
339    /// let m = Command::new("myprog")
340    ///     .arg(Arg::new("x")
341    ///         .short('x')
342    ///         .num_args(2)
343    ///         .action(ArgAction::Append)
344    ///         .value_parser(value_parser!(PathBuf)))
345    ///     .get_matches_from(vec![OsString::from("myprog"),
346    ///                             OsString::from("-x"),
347    ///                             OsString::from("a"), OsString::from("b"),
348    ///                             OsString::from("-x"),
349    ///                             OsString::from("c"),
350    ///                             // "{0xe9}!"
351    ///                             OsString::from_vec(vec![0xe9, b'!'])]);
352    /// let mut itr = m.get_raw_occurrences("x")
353    ///     .expect("`-x`is required")
354    ///     .map(Iterator::collect::<Vec<_>>);
355    /// assert_eq!(itr.next(), Some(vec![OsStr::new("a"), OsStr::new("b")]));
356    /// assert_eq!(itr.next(), Some(vec![OsStr::new("c"), OsStr::from_bytes(&[0xe9, b'!'])]));
357    /// assert_eq!(itr.next(), None);
358    /// # }
359    /// ```
360    /// [`Iterator`]: std::iter::Iterator
361    /// [`OsStr`]: std::ffi::OsStr
362    /// [values]: OsValues
363    /// [`String`]: std::string::String
364    #[cfg_attr(debug_assertions, track_caller)]
365    pub fn get_raw_occurrences(&self, id: &str) -> Option<RawOccurrences<'_>> {
366        MatchesError::unwrap(id, self.try_get_raw_occurrences(id))
367    }
368
369    /// Returns the value of a specific option or positional argument.
370    ///
371    /// i.e. an argument that [takes an additional value][crate::Arg::num_args] at runtime.
372    ///
373    /// Returns an error if the wrong type was used.  No item will have been removed.
374    ///
375    /// Returns `None` if the option wasn't present.
376    ///
377    /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
378    /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
379    ///
380    /// # Panic
381    ///
382    /// If the argument definition and access mismatch.  To handle this case programmatically, see
383    /// [`ArgMatches::try_remove_one`].
384    ///
385    /// # Examples
386    ///
387    /// ```rust
388    /// # use clap_builder as clap;
389    /// # use clap::{Command, Arg, value_parser, ArgAction};
390    /// let mut m = Command::new("myprog")
391    ///     .arg(Arg::new("file")
392    ///         .required(true)
393    ///         .action(ArgAction::Set))
394    ///     .get_matches_from(vec![
395    ///         "myprog", "file.txt",
396    ///     ]);
397    /// let vals: String = m.remove_one("file")
398    ///     .expect("`file`is required");
399    /// assert_eq!(vals, "file.txt");
400    /// ```
401    /// [positional]: crate::Arg::index()
402    /// [`default_value`]: crate::Arg::default_value()
403    #[cfg_attr(debug_assertions, track_caller)]
404    pub fn remove_one<T: Any + Clone + Send + Sync + 'static>(&mut self, id: &str) -> Option<T> {
405        MatchesError::unwrap(id, self.try_remove_one(id))
406    }
407
408    /// Return values of a specific option or positional argument.
409    ///
410    /// i.e. an argument that takes multiple values at runtime.
411    ///
412    /// Returns an error if the wrong type was used.  No item will have been removed.
413    ///
414    /// Returns `None` if the option wasn't present.
415    ///
416    /// # Panic
417    ///
418    /// If the argument definition and access mismatch.  To handle this case programmatically, see
419    /// [`ArgMatches::try_remove_many`].
420    ///
421    /// # Examples
422    ///
423    /// ```rust
424    /// # use clap_builder as clap;
425    /// # use clap::{Command, Arg, value_parser, ArgAction};
426    /// let mut m = Command::new("myprog")
427    ///     .arg(Arg::new("file")
428    ///         .action(ArgAction::Append)
429    ///         .num_args(1..)
430    ///         .required(true))
431    ///     .get_matches_from(vec![
432    ///         "myprog", "file1.txt", "file2.txt", "file3.txt", "file4.txt",
433    ///     ]);
434    /// let vals: Vec<String> = m.remove_many("file")
435    ///     .expect("`file`is required")
436    ///     .collect();
437    /// assert_eq!(vals, ["file1.txt", "file2.txt", "file3.txt", "file4.txt"]);
438    /// ```
439    #[cfg_attr(debug_assertions, track_caller)]
440    pub fn remove_many<T: Any + Clone + Send + Sync + 'static>(
441        &mut self,
442        id: &str,
443    ) -> Option<Values<T>> {
444        MatchesError::unwrap(id, self.try_remove_many(id))
445    }
446
447    /// Return values for each occurrence of an option.
448    ///
449    /// Each item is itself an iterator containing the arguments passed to a single occurrence of
450    /// the option.
451    ///
452    /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
453    /// the iterator will only contain a single item.
454    ///
455    /// Returns `None` if the option wasn't present.
456    ///
457    /// # Panic
458    ///
459    /// If the argument definition and access mismatch.  To handle this case programmatically, see
460    /// [`ArgMatches::try_remove_occurrences`].
461    ///
462    /// # Examples
463    ///
464    /// ```rust
465    /// # use clap_builder as clap;
466    /// # use clap::{Command, Arg, value_parser, ArgAction};
467    /// let mut m = Command::new("myprog")
468    ///     .arg(Arg::new("x")
469    ///         .short('x')
470    ///         .num_args(2)
471    ///         .action(ArgAction::Append)
472    ///         .value_parser(value_parser!(String)))
473    ///     .get_matches_from(vec![
474    ///         "myprog", "-x", "a", "b", "-x", "c", "d"]);
475    /// let vals: Vec<Vec<String>> = m.remove_occurrences("x").unwrap().map(Iterator::collect).collect();
476    /// assert_eq!(vals, [["a", "b"], ["c", "d"]]);
477    /// ```
478    #[cfg_attr(debug_assertions, track_caller)]
479    pub fn remove_occurrences<T: Any + Clone + Send + Sync + 'static>(
480        &mut self,
481        id: &str,
482    ) -> Option<Occurrences<T>> {
483        MatchesError::unwrap(id, self.try_remove_occurrences(id))
484    }
485
486    /// Check if values are present for the argument or group id
487    ///
488    /// *NOTE:* This will always return `true` if [`default_value`] has been set.
489    /// [`ArgMatches::value_source`] can be used to check if a value is present at runtime.
490    ///
491    /// # Panics
492    ///
493    /// If `id` is not a valid argument or group name (debug builds).  To handle this case programmatically, see
494    /// [`ArgMatches::try_contains_id`].
495    ///
496    /// # Examples
497    ///
498    /// ```rust
499    /// # use clap_builder as clap;
500    /// # use clap::{Command, Arg, ArgAction};
501    /// let m = Command::new("myprog")
502    ///     .arg(Arg::new("debug")
503    ///         .short('d')
504    ///         .action(ArgAction::SetTrue))
505    ///     .get_matches_from(vec![
506    ///         "myprog", "-d"
507    ///     ]);
508    ///
509    /// assert!(m.contains_id("debug"));
510    /// ```
511    ///
512    /// [`default_value`]: crate::Arg::default_value()
513    pub fn contains_id(&self, id: &str) -> bool {
514        MatchesError::unwrap(id, self.try_contains_id(id))
515    }
516
517    /// Iterate over [`Arg`][crate::Arg] and [`ArgGroup`][crate::ArgGroup] [`Id`]s via [`ArgMatches::ids`].
518    ///
519    /// # Examples
520    ///
521    /// ```rust
522    /// # use clap_builder as clap;
523    /// # use clap::{Command, arg, value_parser};
524    ///
525    /// let m = Command::new("myprog")
526    ///     .arg(arg!(--color <when>)
527    ///         .value_parser(["auto", "always", "never"]))
528    ///     .arg(arg!(--config <path>)
529    ///         .value_parser(value_parser!(std::path::PathBuf)))
530    ///     .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
531    /// assert_eq!(m.ids().len(), 2);
532    /// assert_eq!(
533    ///     m.ids()
534    ///         .map(|id| id.as_str())
535    ///         .collect::<Vec<_>>(),
536    ///     ["config", "color"]
537    /// );
538    /// ```
539    pub fn ids(&self) -> IdsRef<'_> {
540        IdsRef {
541            iter: self.args.keys(),
542        }
543    }
544
545    /// Check if any args were present on the command line
546    ///
547    /// # Examples
548    ///
549    /// ```rust
550    /// # use clap_builder as clap;
551    /// # use clap::{Command, Arg, ArgAction};
552    /// let mut cmd = Command::new("myapp")
553    ///     .arg(Arg::new("output")
554    ///         .action(ArgAction::Set));
555    ///
556    /// let m = cmd
557    ///     .try_get_matches_from_mut(vec!["myapp", "something"])
558    ///     .unwrap();
559    /// assert!(m.args_present());
560    ///
561    /// let m = cmd
562    ///     .try_get_matches_from_mut(vec!["myapp"])
563    ///     .unwrap();
564    /// assert!(! m.args_present());
565    pub fn args_present(&self) -> bool {
566        !self.args.is_empty()
567    }
568
569    /// Report where argument value came from
570    ///
571    /// # Panics
572    ///
573    /// If `id` is not a valid argument or group id (debug builds).
574    ///
575    /// # Examples
576    ///
577    /// ```rust
578    /// # use clap_builder as clap;
579    /// # use clap::{Command, Arg, ArgAction};
580    /// # use clap::parser::ValueSource;
581    /// let m = Command::new("myprog")
582    ///     .arg(Arg::new("debug")
583    ///         .short('d')
584    ///         .action(ArgAction::SetTrue))
585    ///     .get_matches_from(vec![
586    ///         "myprog", "-d"
587    ///     ]);
588    ///
589    /// assert_eq!(m.value_source("debug"), Some(ValueSource::CommandLine));
590    /// ```
591    ///
592    /// [`default_value`]: crate::Arg::default_value()
593    #[cfg_attr(debug_assertions, track_caller)]
594    pub fn value_source(&self, id: &str) -> Option<ValueSource> {
595        let value = self.get_arg(id);
596
597        value.and_then(MatchedArg::source)
598    }
599
600    /// The first index of that an argument showed up.
601    ///
602    /// Indices are similar to argv indices, but are not exactly 1:1.
603    ///
604    /// For flags (i.e. those arguments which don't have an associated value), indices refer
605    /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
606    /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
607    /// index for `val` would be recorded. This is by design.
608    ///
609    /// Besides the flag/option discrepancy, the primary difference between an argv index and clap
610    /// index, is that clap continues counting once all arguments have properly separated, whereas
611    /// an argv index does not.
612    ///
613    /// The examples should clear this up.
614    ///
615    /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first*
616    /// index.  See [`ArgMatches::indices_of`].
617    ///
618    /// # Panics
619    ///
620    /// If `id` is not a valid argument or group id (debug builds).
621    ///
622    /// # Examples
623    ///
624    /// The argv indices are listed in the comments below. See how they correspond to the clap
625    /// indices. Note that if it's not listed in a clap index, this is because it's not saved in
626    /// in an `ArgMatches` struct for querying.
627    ///
628    /// ```rust
629    /// # use clap_builder as clap;
630    /// # use clap::{Command, Arg, ArgAction};
631    /// let m = Command::new("myapp")
632    ///     .arg(Arg::new("flag")
633    ///         .short('f')
634    ///         .action(ArgAction::SetTrue))
635    ///     .arg(Arg::new("option")
636    ///         .short('o')
637    ///         .action(ArgAction::Set))
638    ///     .get_matches_from(vec!["myapp", "-f", "-o", "val"]);
639    ///            // ARGV indices: ^0       ^1    ^2    ^3
640    ///            // clap indices:          ^1          ^3
641    ///
642    /// assert_eq!(m.index_of("flag"), Some(1));
643    /// assert_eq!(m.index_of("option"), Some(3));
644    /// ```
645    ///
646    /// Now notice, if we use one of the other styles of options:
647    ///
648    /// ```rust
649    /// # use clap_builder as clap;
650    /// # use clap::{Command, Arg, ArgAction};
651    /// let m = Command::new("myapp")
652    ///     .arg(Arg::new("flag")
653    ///         .short('f')
654    ///         .action(ArgAction::SetTrue))
655    ///     .arg(Arg::new("option")
656    ///         .short('o')
657    ///         .action(ArgAction::Set))
658    ///     .get_matches_from(vec!["myapp", "-f", "-o=val"]);
659    ///            // ARGV indices: ^0       ^1    ^2
660    ///            // clap indices:          ^1       ^3
661    ///
662    /// assert_eq!(m.index_of("flag"), Some(1));
663    /// assert_eq!(m.index_of("option"), Some(3));
664    /// ```
665    ///
666    /// Things become much more complicated, or clear if we look at a more complex combination of
667    /// flags. Let's also throw in the final option style for good measure.
668    ///
669    /// ```rust
670    /// # use clap_builder as clap;
671    /// # use clap::{Command, Arg, ArgAction};
672    /// let m = Command::new("myapp")
673    ///     .arg(Arg::new("flag")
674    ///         .short('f')
675    ///         .action(ArgAction::SetTrue))
676    ///     .arg(Arg::new("flag2")
677    ///         .short('F')
678    ///         .action(ArgAction::SetTrue))
679    ///     .arg(Arg::new("flag3")
680    ///         .short('z')
681    ///         .action(ArgAction::SetTrue))
682    ///     .arg(Arg::new("option")
683    ///         .short('o')
684    ///         .action(ArgAction::Set))
685    ///     .get_matches_from(vec!["myapp", "-fzF", "-oval"]);
686    ///            // ARGV indices: ^0      ^1       ^2
687    ///            // clap indices:         ^1,2,3    ^5
688    ///            //
689    ///            // clap sees the above as 'myapp -f -z -F -o val'
690    ///            //                         ^0    ^1 ^2 ^3 ^4 ^5
691    /// assert_eq!(m.index_of("flag"), Some(1));
692    /// assert_eq!(m.index_of("flag2"), Some(3));
693    /// assert_eq!(m.index_of("flag3"), Some(2));
694    /// assert_eq!(m.index_of("option"), Some(5));
695    /// ```
696    ///
697    /// One final combination of flags/options to see how they combine:
698    ///
699    /// ```rust
700    /// # use clap_builder as clap;
701    /// # use clap::{Command, Arg, ArgAction};
702    /// let m = Command::new("myapp")
703    ///     .arg(Arg::new("flag")
704    ///         .short('f')
705    ///         .action(ArgAction::SetTrue))
706    ///     .arg(Arg::new("flag2")
707    ///         .short('F')
708    ///         .action(ArgAction::SetTrue))
709    ///     .arg(Arg::new("flag3")
710    ///         .short('z')
711    ///         .action(ArgAction::SetTrue))
712    ///     .arg(Arg::new("option")
713    ///         .short('o')
714    ///         .action(ArgAction::Set))
715    ///     .get_matches_from(vec!["myapp", "-fzFoval"]);
716    ///            // ARGV indices: ^0       ^1
717    ///            // clap indices:          ^1,2,3^5
718    ///            //
719    ///            // clap sees the above as 'myapp -f -z -F -o val'
720    ///            //                         ^0    ^1 ^2 ^3 ^4 ^5
721    /// assert_eq!(m.index_of("flag"), Some(1));
722    /// assert_eq!(m.index_of("flag2"), Some(3));
723    /// assert_eq!(m.index_of("flag3"), Some(2));
724    /// assert_eq!(m.index_of("option"), Some(5));
725    /// ```
726    ///
727    /// The last part to mention is when values are sent in multiple groups with a [delimiter].
728    ///
729    /// ```rust
730    /// # use clap_builder as clap;
731    /// # use clap::{Command, Arg};
732    /// let m = Command::new("myapp")
733    ///     .arg(Arg::new("option")
734    ///         .short('o')
735    ///         .value_delimiter(',')
736    ///         .num_args(1..))
737    ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
738    ///            // ARGV indices: ^0       ^1
739    ///            // clap indices:             ^2   ^3   ^4
740    ///            //
741    ///            // clap sees the above as 'myapp -o val1 val2 val3'
742    ///            //                         ^0    ^1 ^2   ^3   ^4
743    /// assert_eq!(m.index_of("option"), Some(2));
744    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
745    /// ```
746    /// [delimiter]: crate::Arg::value_delimiter()
747    #[cfg_attr(debug_assertions, track_caller)]
748    pub fn index_of(&self, id: &str) -> Option<usize> {
749        let arg = some!(self.get_arg(id));
750        let i = some!(arg.get_index(0));
751        Some(i)
752    }
753
754    /// All indices an argument appeared at when parsing.
755    ///
756    /// Indices are similar to argv indices, but are not exactly 1:1.
757    ///
758    /// For flags (i.e. those arguments which don't have an associated value), indices refer
759    /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
760    /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
761    /// index for `val` would be recorded. This is by design.
762    ///
763    /// *NOTE:* For more information about how clap indices compared to argv indices, see
764    /// [`ArgMatches::index_of`]
765    ///
766    /// # Panics
767    ///
768    /// If `id` is not a valid argument or group id (debug builds).
769    ///
770    /// # Examples
771    ///
772    /// ```rust
773    /// # use clap_builder as clap;
774    /// # use clap::{Command, Arg};
775    /// let m = Command::new("myapp")
776    ///     .arg(Arg::new("option")
777    ///         .short('o')
778    ///         .value_delimiter(','))
779    ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
780    ///            // ARGV indices: ^0       ^1
781    ///            // clap indices:             ^2   ^3   ^4
782    ///            //
783    ///            // clap sees the above as 'myapp -o val1 val2 val3'
784    ///            //                         ^0    ^1 ^2   ^3   ^4
785    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
786    /// ```
787    ///
788    /// Another quick example is when flags and options are used together
789    ///
790    /// ```rust
791    /// # use clap_builder as clap;
792    /// # use clap::{Command, Arg, ArgAction};
793    /// let m = Command::new("myapp")
794    ///     .arg(Arg::new("option")
795    ///         .short('o')
796    ///         .action(ArgAction::Set)
797    ///         .action(ArgAction::Append))
798    ///     .arg(Arg::new("flag")
799    ///         .short('f')
800    ///         .action(ArgAction::Count))
801    ///     .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]);
802    ///            // ARGV indices: ^0       ^1    ^2      ^3    ^4    ^5      ^6
803    ///            // clap indices:                ^2      ^3          ^5      ^6
804    ///
805    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
806    /// assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[6]);
807    /// ```
808    ///
809    /// One final example, which is an odd case; if we *don't* use  value delimiter as we did with
810    /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they
811    /// would all be a single value of `val1,val2,val3`, in which case they'd only receive a single
812    /// index.
813    ///
814    /// ```rust
815    /// # use clap_builder as clap;
816    /// # use clap::{Command, Arg, ArgAction};
817    /// let m = Command::new("myapp")
818    ///     .arg(Arg::new("option")
819    ///         .short('o')
820    ///         .action(ArgAction::Set)
821    ///         .num_args(1..))
822    ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
823    ///            // ARGV indices: ^0       ^1
824    ///            // clap indices:             ^2
825    ///            //
826    ///            // clap sees the above as 'myapp -o "val1,val2,val3"'
827    ///            //                         ^0    ^1  ^2
828    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);
829    /// ```
830    /// [`ArgMatches::index_of`]: ArgMatches::index_of()
831    /// [delimiter]: Arg::value_delimiter()
832    #[cfg_attr(debug_assertions, track_caller)]
833    pub fn indices_of(&self, id: &str) -> Option<Indices<'_>> {
834        let arg = some!(self.get_arg(id));
835        let i = Indices {
836            iter: arg.indices(),
837            len: arg.num_vals(),
838        };
839        Some(i)
840    }
841}
842
843/// # Subcommands
844impl ArgMatches {
845    /// The name and `ArgMatches` of the current [subcommand].
846    ///
847    /// Subcommand values are put in a child [`ArgMatches`]
848    ///
849    /// Returns `None` if the subcommand wasn't present at runtime,
850    ///
851    /// # Examples
852    ///
853    /// ```no_run
854    /// # use clap_builder as clap;
855    /// # use clap::{Command, Arg, };
856    ///  let app_m = Command::new("git")
857    ///      .subcommand(Command::new("clone"))
858    ///      .subcommand(Command::new("push"))
859    ///      .subcommand(Command::new("commit"))
860    ///      .get_matches();
861    ///
862    /// match app_m.subcommand() {
863    ///     Some(("clone",  sub_m)) => {}, // clone was used
864    ///     Some(("push",   sub_m)) => {}, // push was used
865    ///     Some(("commit", sub_m)) => {}, // commit was used
866    ///     _                       => {}, // Either no subcommand or one not tested for...
867    /// }
868    /// ```
869    ///
870    /// Another useful scenario is when you want to support third party, or external, subcommands.
871    /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
872    /// with pattern matching!
873    ///
874    /// ```rust
875    /// # use clap_builder as clap;
876    /// # use std::ffi::OsString;
877    /// # use std::ffi::OsStr;
878    /// # use clap::Command;
879    /// // Assume there is an external subcommand named "subcmd"
880    /// let app_m = Command::new("myprog")
881    ///     .allow_external_subcommands(true)
882    ///     .get_matches_from(vec![
883    ///         "myprog", "subcmd", "--option", "value", "-fff", "--flag"
884    ///     ]);
885    ///
886    /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
887    /// // string argument name
888    /// match app_m.subcommand() {
889    ///     Some((external, sub_m)) => {
890    ///          let ext_args: Vec<&OsStr> = sub_m.get_many::<OsString>("")
891    ///             .unwrap().map(|s| s.as_os_str()).collect();
892    ///          assert_eq!(external, "subcmd");
893    ///          assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
894    ///     },
895    ///     _ => {},
896    /// }
897    /// ```
898    /// [subcommand]: crate::Command::subcommand
899    #[inline]
900    pub fn subcommand(&self) -> Option<(&str, &ArgMatches)> {
901        self.subcommand.as_ref().map(|sc| (&*sc.name, &sc.matches))
902    }
903
904    /// Return the name and `ArgMatches` of the current [subcommand].
905    ///
906    /// Subcommand values are put in a child [`ArgMatches`]
907    ///
908    /// Returns `None` if the subcommand wasn't present at runtime,
909    ///
910    /// # Examples
911    ///
912    /// ```no_run
913    /// # use clap_builder as clap;
914    /// # use clap::{Command, Arg, };
915    ///  let mut app_m = Command::new("git")
916    ///      .subcommand(Command::new("clone"))
917    ///      .subcommand(Command::new("push"))
918    ///      .subcommand(Command::new("commit"))
919    ///      .subcommand_required(true)
920    ///      .get_matches();
921    ///
922    /// let (name, sub_m) = app_m.remove_subcommand().expect("required");
923    /// match (name.as_str(), sub_m) {
924    ///     ("clone",  sub_m) => {}, // clone was used
925    ///     ("push",   sub_m) => {}, // push was used
926    ///     ("commit", sub_m) => {}, // commit was used
927    ///     (name, _)         => unimplemented!("{name}"),
928    /// }
929    /// ```
930    ///
931    /// Another useful scenario is when you want to support third party, or external, subcommands.
932    /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
933    /// with pattern matching!
934    ///
935    /// ```rust
936    /// # use clap_builder as clap;
937    /// # use std::ffi::OsString;
938    /// # use clap::Command;
939    /// // Assume there is an external subcommand named "subcmd"
940    /// let mut app_m = Command::new("myprog")
941    ///     .allow_external_subcommands(true)
942    ///     .get_matches_from(vec![
943    ///         "myprog", "subcmd", "--option", "value", "-fff", "--flag"
944    ///     ]);
945    ///
946    /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
947    /// // string argument name
948    /// match app_m.remove_subcommand() {
949    ///     Some((external, mut sub_m)) => {
950    ///          let ext_args: Vec<OsString> = sub_m.remove_many("")
951    ///             .expect("`file`is required")
952    ///             .collect();
953    ///          assert_eq!(external, "subcmd");
954    ///          assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
955    ///     },
956    ///     _ => {},
957    /// }
958    /// ```
959    /// [subcommand]: crate::Command::subcommand
960    pub fn remove_subcommand(&mut self) -> Option<(String, ArgMatches)> {
961        self.subcommand.take().map(|sc| (sc.name, sc.matches))
962    }
963
964    /// The `ArgMatches` for the current [subcommand].
965    ///
966    /// Subcommand values are put in a child [`ArgMatches`]
967    ///
968    /// Returns `None` if the subcommand wasn't present at runtime,
969    ///
970    /// # Panics
971    ///
972    /// If `id` is not a valid subcommand (debug builds).
973    ///
974    /// # Examples
975    ///
976    /// ```rust
977    /// # use clap_builder as clap;
978    /// # use clap::{Command, Arg, ArgAction};
979    /// let app_m = Command::new("myprog")
980    ///     .arg(Arg::new("debug")
981    ///         .short('d')
982    ///         .action(ArgAction::SetTrue)
983    ///     )
984    ///     .subcommand(Command::new("test")
985    ///         .arg(Arg::new("opt")
986    ///             .long("option")
987    ///             .action(ArgAction::Set)))
988    ///     .get_matches_from(vec![
989    ///         "myprog", "-d", "test", "--option", "val"
990    ///     ]);
991    ///
992    /// // Both parent commands, and child subcommands can have arguments present at the same times
993    /// assert!(app_m.get_flag("debug"));
994    ///
995    /// // Get the subcommand's ArgMatches instance
996    /// if let Some(sub_m) = app_m.subcommand_matches("test") {
997    ///     // Use the struct like normal
998    ///     assert_eq!(sub_m.get_one::<String>("opt").map(|s| s.as_str()), Some("val"));
999    /// }
1000    /// ```
1001    ///
1002    /// [subcommand]: crate::Command::subcommand
1003    /// [`Command`]: crate::Command
1004    pub fn subcommand_matches(&self, name: &str) -> Option<&ArgMatches> {
1005        self.get_subcommand(name).map(|sc| &sc.matches)
1006    }
1007
1008    /// The name of the current [subcommand].
1009    ///
1010    /// Returns `None` if the subcommand wasn't present at runtime,
1011    ///
1012    /// # Examples
1013    ///
1014    /// ```no_run
1015    /// # use clap_builder as clap;
1016    /// # use clap::{Command, Arg, };
1017    ///  let app_m = Command::new("git")
1018    ///      .subcommand(Command::new("clone"))
1019    ///      .subcommand(Command::new("push"))
1020    ///      .subcommand(Command::new("commit"))
1021    ///      .get_matches();
1022    ///
1023    /// match app_m.subcommand_name() {
1024    ///     Some("clone")  => {}, // clone was used
1025    ///     Some("push")   => {}, // push was used
1026    ///     Some("commit") => {}, // commit was used
1027    ///     _              => {}, // Either no subcommand or one not tested for...
1028    /// }
1029    /// ```
1030    /// [subcommand]: crate::Command::subcommand
1031    /// [`Command`]: crate::Command
1032    #[inline]
1033    pub fn subcommand_name(&self) -> Option<&str> {
1034        self.subcommand.as_ref().map(|sc| &*sc.name)
1035    }
1036
1037    /// Check if a subcommand can be queried
1038    ///
1039    /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer
1040    /// mistakes.  In some context, this doesn't work, so users can use this function to check
1041    /// before they do a query on `ArgMatches`.
1042    #[inline]
1043    #[doc(hidden)]
1044    pub fn is_valid_subcommand(&self, _name: &str) -> bool {
1045        #[cfg(debug_assertions)]
1046        {
1047            _name.is_empty() || self.valid_subcommands.iter().any(|s| *s == _name)
1048        }
1049        #[cfg(not(debug_assertions))]
1050        {
1051            true
1052        }
1053    }
1054}
1055
1056/// # Advanced
1057impl ArgMatches {
1058    /// Non-panicking version of [`ArgMatches::get_one`]
1059    pub fn try_get_one<T: Any + Clone + Send + Sync + 'static>(
1060        &self,
1061        id: &str,
1062    ) -> Result<Option<&T>, MatchesError> {
1063        let arg = ok!(self.try_get_arg_t::<T>(id));
1064        let value = match arg.and_then(|a| a.first()) {
1065            Some(value) => value,
1066            None => {
1067                return Ok(None);
1068            }
1069        };
1070        Ok(value
1071            .downcast_ref::<T>()
1072            .map(Some)
1073            .expect(INTERNAL_ERROR_MSG)) // enforced by `try_get_arg_t`
1074    }
1075
1076    /// Non-panicking version of [`ArgMatches::get_many`]
1077    pub fn try_get_many<T: Any + Clone + Send + Sync + 'static>(
1078        &self,
1079        id: &str,
1080    ) -> Result<Option<ValuesRef<'_, T>>, MatchesError> {
1081        let arg = match ok!(self.try_get_arg_t::<T>(id)) {
1082            Some(arg) => arg,
1083            None => return Ok(None),
1084        };
1085        let len = arg.num_vals();
1086        let values = arg.vals_flatten();
1087        let values = ValuesRef {
1088            // enforced by `try_get_arg_t`
1089            iter: values.map(unwrap_downcast_ref),
1090            len,
1091        };
1092        Ok(Some(values))
1093    }
1094
1095    /// Non-panicking version of [`ArgMatches::get_occurrences`]
1096    pub fn try_get_occurrences<T: Any + Clone + Send + Sync + 'static>(
1097        &self,
1098        id: &str,
1099    ) -> Result<Option<OccurrencesRef<'_, T>>, MatchesError> {
1100        let arg = match ok!(self.try_get_arg_t::<T>(id)) {
1101            Some(arg) => arg,
1102            None => return Ok(None),
1103        };
1104        let values = arg.vals();
1105        Ok(Some(OccurrencesRef {
1106            iter: values.map(|g| OccurrenceValuesRef {
1107                iter: g.iter().map(unwrap_downcast_ref),
1108            }),
1109        }))
1110    }
1111
1112    /// Non-panicking version of [`ArgMatches::get_raw`]
1113    pub fn try_get_raw(&self, id: &str) -> Result<Option<RawValues<'_>>, MatchesError> {
1114        let arg = match ok!(self.try_get_arg(id)) {
1115            Some(arg) => arg,
1116            None => return Ok(None),
1117        };
1118        let len = arg.num_vals();
1119        let values = arg.raw_vals_flatten();
1120        let values = RawValues {
1121            iter: values.map(OsString::as_os_str),
1122            len,
1123        };
1124        Ok(Some(values))
1125    }
1126
1127    /// Non-panicking version of [`ArgMatches::get_raw_occurrences`]
1128    pub fn try_get_raw_occurrences(
1129        &self,
1130        id: &str,
1131    ) -> Result<Option<RawOccurrences<'_>>, MatchesError> {
1132        let arg = match ok!(self.try_get_arg(id)) {
1133            Some(arg) => arg,
1134            None => return Ok(None),
1135        };
1136        let values = arg.raw_vals();
1137        let occurrences = RawOccurrences {
1138            iter: values.map(|g| RawOccurrenceValues {
1139                iter: g.iter().map(OsString::as_os_str),
1140            }),
1141        };
1142        Ok(Some(occurrences))
1143    }
1144
1145    /// Non-panicking version of [`ArgMatches::remove_one`]
1146    pub fn try_remove_one<T: Any + Clone + Send + Sync + 'static>(
1147        &mut self,
1148        id: &str,
1149    ) -> Result<Option<T>, MatchesError> {
1150        match ok!(self.try_remove_arg_t::<T>(id)) {
1151            Some(values) => Ok(values
1152                .into_vals_flatten()
1153                // enforced by `try_get_arg_t`
1154                .map(unwrap_downcast_into)
1155                .next()),
1156            None => Ok(None),
1157        }
1158    }
1159
1160    /// Non-panicking version of [`ArgMatches::remove_many`]
1161    pub fn try_remove_many<T: Any + Clone + Send + Sync + 'static>(
1162        &mut self,
1163        id: &str,
1164    ) -> Result<Option<Values<T>>, MatchesError> {
1165        let arg = match ok!(self.try_remove_arg_t::<T>(id)) {
1166            Some(arg) => arg,
1167            None => return Ok(None),
1168        };
1169        let len = arg.num_vals();
1170        let values = arg.into_vals_flatten();
1171        let values = Values {
1172            // enforced by `try_get_arg_t`
1173            iter: values.map(unwrap_downcast_into),
1174            len,
1175        };
1176        Ok(Some(values))
1177    }
1178
1179    /// Non-panicking version of [`ArgMatches::remove_occurrences`]
1180    pub fn try_remove_occurrences<T: Any + Clone + Send + Sync + 'static>(
1181        &mut self,
1182        id: &str,
1183    ) -> Result<Option<Occurrences<T>>, MatchesError> {
1184        let arg = match ok!(self.try_remove_arg_t::<T>(id)) {
1185            Some(arg) => arg,
1186            None => return Ok(None),
1187        };
1188        let values = arg.into_vals();
1189        let occurrences = Occurrences {
1190            iter: values.into_iter().map(|g| OccurrenceValues {
1191                iter: g.into_iter().map(unwrap_downcast_into),
1192            }),
1193        };
1194        Ok(Some(occurrences))
1195    }
1196
1197    /// Non-panicking version of [`ArgMatches::contains_id`]
1198    pub fn try_contains_id(&self, id: &str) -> Result<bool, MatchesError> {
1199        ok!(self.verify_arg(id));
1200
1201        let presence = self.args.contains_key(id);
1202        Ok(presence)
1203    }
1204}
1205
1206// Private methods
1207impl ArgMatches {
1208    #[inline]
1209    fn try_get_arg(&self, arg: &str) -> Result<Option<&MatchedArg>, MatchesError> {
1210        ok!(self.verify_arg(arg));
1211        Ok(self.args.get(arg))
1212    }
1213
1214    #[inline]
1215    fn try_get_arg_t<T: Any + Send + Sync + 'static>(
1216        &self,
1217        arg: &str,
1218    ) -> Result<Option<&MatchedArg>, MatchesError> {
1219        let arg = match ok!(self.try_get_arg(arg)) {
1220            Some(arg) => arg,
1221            None => {
1222                return Ok(None);
1223            }
1224        };
1225        ok!(self.verify_arg_t::<T>(arg));
1226        Ok(Some(arg))
1227    }
1228
1229    #[inline]
1230    fn try_remove_arg_t<T: Any + Send + Sync + 'static>(
1231        &mut self,
1232        arg: &str,
1233    ) -> Result<Option<MatchedArg>, MatchesError> {
1234        ok!(self.verify_arg(arg));
1235        let (id, matched) = match self.args.remove_entry(arg) {
1236            Some((id, matched)) => (id, matched),
1237            None => {
1238                return Ok(None);
1239            }
1240        };
1241
1242        let expected = AnyValueId::of::<T>();
1243        let actual = matched.infer_type_id(expected);
1244        if actual == expected {
1245            Ok(Some(matched))
1246        } else {
1247            self.args.insert(id, matched);
1248            Err(MatchesError::Downcast { actual, expected })
1249        }
1250    }
1251
1252    fn verify_arg_t<T: Any + Send + Sync + 'static>(
1253        &self,
1254        arg: &MatchedArg,
1255    ) -> Result<(), MatchesError> {
1256        let expected = AnyValueId::of::<T>();
1257        let actual = arg.infer_type_id(expected);
1258        if expected == actual {
1259            Ok(())
1260        } else {
1261            Err(MatchesError::Downcast { actual, expected })
1262        }
1263    }
1264
1265    #[inline]
1266    fn verify_arg(&self, _arg: &str) -> Result<(), MatchesError> {
1267        #[cfg(debug_assertions)]
1268        {
1269            if _arg == Id::EXTERNAL || self.valid_args.iter().any(|s| *s == _arg) {
1270            } else {
1271                debug!(
1272                    "`{:?}` is not an id of an argument or a group.\n\
1273                     Make sure you're using the name of the argument itself \
1274                     and not the name of short or long flags.",
1275                    _arg
1276                );
1277                return Err(MatchesError::UnknownArgument {});
1278            }
1279        }
1280        Ok(())
1281    }
1282
1283    #[inline]
1284    #[cfg_attr(debug_assertions, track_caller)]
1285    fn get_arg<'s>(&'s self, arg: &str) -> Option<&'s MatchedArg> {
1286        #[cfg(debug_assertions)]
1287        {
1288            if arg == Id::EXTERNAL || self.valid_args.iter().any(|s| *s == arg) {
1289            } else {
1290                panic!(
1291                    "`{arg:?}` is not an id of an argument or a group.\n\
1292                     Make sure you're using the name of the argument itself \
1293                     and not the name of short or long flags."
1294                );
1295            }
1296        }
1297
1298        self.args.get(arg)
1299    }
1300
1301    #[inline]
1302    #[cfg_attr(debug_assertions, track_caller)]
1303    fn get_subcommand(&self, name: &str) -> Option<&SubCommand> {
1304        #[cfg(debug_assertions)]
1305        {
1306            if name.is_empty() || self.valid_subcommands.iter().any(|s| *s == name) {
1307            } else {
1308                panic!("`{name}` is not a name of a subcommand.");
1309            }
1310        }
1311
1312        if let Some(ref sc) = self.subcommand {
1313            if sc.name == name {
1314                return Some(sc);
1315            }
1316        }
1317
1318        None
1319    }
1320}
1321
1322#[derive(Debug, Clone, PartialEq, Eq)]
1323pub(crate) struct SubCommand {
1324    pub(crate) name: String,
1325    pub(crate) matches: ArgMatches,
1326}
1327
1328/// Iterate over [`Arg`][crate::Arg] and [`ArgGroup`][crate::ArgGroup] [`Id`]s via [`ArgMatches::ids`].
1329///
1330/// # Examples
1331///
1332/// ```rust
1333/// # use clap_builder as clap;
1334/// # use clap::{Command, arg, value_parser};
1335///
1336/// let m = Command::new("myprog")
1337///     .arg(arg!(--color <when>)
1338///         .value_parser(["auto", "always", "never"]))
1339///     .arg(arg!(--config <path>)
1340///         .value_parser(value_parser!(std::path::PathBuf)))
1341///     .get_matches_from(["myprog", "--config=config.toml", "--color=auto"]);
1342/// assert_eq!(
1343///     m.ids()
1344///         .map(|id| id.as_str())
1345///         .collect::<Vec<_>>(),
1346///     ["config", "color"]
1347/// );
1348/// ```
1349#[derive(Clone, Debug)]
1350pub struct IdsRef<'a> {
1351    iter: Iter<'a, Id>,
1352}
1353
1354impl<'a> Iterator for IdsRef<'a> {
1355    type Item = &'a Id;
1356
1357    fn next(&mut self) -> Option<&'a Id> {
1358        self.iter.next()
1359    }
1360    fn size_hint(&self) -> (usize, Option<usize>) {
1361        self.iter.size_hint()
1362    }
1363}
1364
1365impl<'a> DoubleEndedIterator for IdsRef<'a> {
1366    fn next_back(&mut self) -> Option<&'a Id> {
1367        self.iter.next_back()
1368    }
1369}
1370
1371impl<'a> ExactSizeIterator for IdsRef<'a> {}
1372
1373/// Iterate over multiple values for an argument via [`ArgMatches::remove_many`].
1374///
1375/// # Examples
1376///
1377/// ```rust
1378/// # use clap_builder as clap;
1379/// # use clap::{Command, Arg, ArgAction};
1380/// let mut m = Command::new("myapp")
1381///     .arg(Arg::new("output")
1382///         .short('o')
1383///         .action(ArgAction::Append))
1384///     .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1385///
1386/// let mut values = m.remove_many::<String>("output")
1387///     .unwrap();
1388///
1389/// assert_eq!(values.next(), Some(String::from("val1")));
1390/// assert_eq!(values.next(), Some(String::from("val2")));
1391/// assert_eq!(values.next(), None);
1392/// ```
1393#[derive(Clone, Debug)]
1394pub struct Values<T> {
1395    #[allow(clippy::type_complexity)]
1396    iter: Map<Flatten<std::vec::IntoIter<Vec<AnyValue>>>, fn(AnyValue) -> T>,
1397    len: usize,
1398}
1399
1400impl<T> Iterator for Values<T> {
1401    type Item = T;
1402
1403    fn next(&mut self) -> Option<Self::Item> {
1404        if let Some(next) = self.iter.next() {
1405            self.len -= 1;
1406            Some(next)
1407        } else {
1408            None
1409        }
1410    }
1411    fn size_hint(&self) -> (usize, Option<usize>) {
1412        (self.len, Some(self.len))
1413    }
1414}
1415
1416impl<T> DoubleEndedIterator for Values<T> {
1417    fn next_back(&mut self) -> Option<Self::Item> {
1418        if let Some(next) = self.iter.next_back() {
1419            self.len -= 1;
1420            Some(next)
1421        } else {
1422            None
1423        }
1424    }
1425}
1426
1427impl<T> ExactSizeIterator for Values<T> {}
1428
1429/// Creates an empty iterator.
1430impl<T> Default for Values<T> {
1431    fn default() -> Self {
1432        let empty: Vec<Vec<AnyValue>> = Default::default();
1433        Values {
1434            iter: empty.into_iter().flatten().map(|_| unreachable!()),
1435            len: 0,
1436        }
1437    }
1438}
1439
1440/// Iterate over multiple values for an argument via [`ArgMatches::get_many`].
1441///
1442/// # Examples
1443///
1444/// ```rust
1445/// # use clap_builder as clap;
1446/// # use clap::{Command, Arg, ArgAction};
1447/// let m = Command::new("myapp")
1448///     .arg(Arg::new("output")
1449///         .short('o')
1450///         .action(ArgAction::Append))
1451///     .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1452///
1453/// let mut values = m.get_many::<String>("output")
1454///     .unwrap()
1455///     .map(|s| s.as_str());
1456///
1457/// assert_eq!(values.next(), Some("val1"));
1458/// assert_eq!(values.next(), Some("val2"));
1459/// assert_eq!(values.next(), None);
1460/// ```
1461#[derive(Clone, Debug)]
1462pub struct ValuesRef<'a, T> {
1463    #[allow(clippy::type_complexity)]
1464    iter: Map<Flatten<Iter<'a, Vec<AnyValue>>>, fn(&AnyValue) -> &T>,
1465    len: usize,
1466}
1467
1468impl<'a, T: 'a> Iterator for ValuesRef<'a, T> {
1469    type Item = &'a T;
1470
1471    fn next(&mut self) -> Option<Self::Item> {
1472        if let Some(next) = self.iter.next() {
1473            self.len -= 1;
1474            Some(next)
1475        } else {
1476            None
1477        }
1478    }
1479    fn size_hint(&self) -> (usize, Option<usize>) {
1480        (self.len, Some(self.len))
1481    }
1482}
1483
1484impl<'a, T: 'a> DoubleEndedIterator for ValuesRef<'a, T> {
1485    fn next_back(&mut self) -> Option<Self::Item> {
1486        if let Some(next) = self.iter.next_back() {
1487            self.len -= 1;
1488            Some(next)
1489        } else {
1490            None
1491        }
1492    }
1493}
1494
1495impl<'a, T: 'a> ExactSizeIterator for ValuesRef<'a, T> {}
1496
1497/// Creates an empty iterator.
1498impl<'a, T: 'a> Default for ValuesRef<'a, T> {
1499    fn default() -> Self {
1500        static EMPTY: [Vec<AnyValue>; 0] = [];
1501        ValuesRef {
1502            iter: EMPTY[..].iter().flatten().map(|_| unreachable!()),
1503            len: 0,
1504        }
1505    }
1506}
1507
1508/// Iterate over raw argument values via [`ArgMatches::get_raw`].
1509///
1510/// # Examples
1511///
1512/// ```rust
1513/// # #[cfg(unix)] {
1514/// # use clap_builder as clap;
1515/// # use clap::{Command, arg, value_parser};
1516/// use std::ffi::OsString;
1517/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
1518///
1519/// let m = Command::new("utf8")
1520///     .arg(arg!(<arg> "some arg")
1521///         .value_parser(value_parser!(OsString)))
1522///     .get_matches_from(vec![OsString::from("myprog"),
1523///                             // "Hi {0xe9}!"
1524///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
1525/// assert_eq!(
1526///     &*m.get_raw("arg")
1527///         .unwrap()
1528///         .next().unwrap()
1529///         .as_bytes(),
1530///     [b'H', b'i', b' ', 0xe9, b'!']
1531/// );
1532/// # }
1533/// ```
1534#[derive(Clone, Debug)]
1535pub struct RawValues<'a> {
1536    #[allow(clippy::type_complexity)]
1537    iter: Map<Flatten<Iter<'a, Vec<OsString>>>, fn(&OsString) -> &OsStr>,
1538    len: usize,
1539}
1540
1541impl<'a> Iterator for RawValues<'a> {
1542    type Item = &'a OsStr;
1543
1544    fn next(&mut self) -> Option<&'a OsStr> {
1545        if let Some(next) = self.iter.next() {
1546            self.len -= 1;
1547            Some(next)
1548        } else {
1549            None
1550        }
1551    }
1552    fn size_hint(&self) -> (usize, Option<usize>) {
1553        (self.len, Some(self.len))
1554    }
1555}
1556
1557impl<'a> DoubleEndedIterator for RawValues<'a> {
1558    fn next_back(&mut self) -> Option<&'a OsStr> {
1559        if let Some(next) = self.iter.next_back() {
1560            self.len -= 1;
1561            Some(next)
1562        } else {
1563            None
1564        }
1565    }
1566}
1567
1568impl<'a> ExactSizeIterator for RawValues<'a> {}
1569
1570/// Creates an empty iterator.
1571impl Default for RawValues<'_> {
1572    fn default() -> Self {
1573        static EMPTY: [Vec<OsString>; 0] = [];
1574        RawValues {
1575            iter: EMPTY[..].iter().flatten().map(|_| unreachable!()),
1576            len: 0,
1577        }
1578    }
1579}
1580
1581// The following were taken and adapted from vec_map source
1582// repo: https://github.com/contain-rs/vec-map
1583// commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
1584// license: MIT - Copyright (c) 2015 The Rust Project Developers
1585
1586#[derive(Clone, Debug)]
1587#[deprecated(since = "4.1.0", note = "Use Occurrences instead")]
1588pub(crate) struct GroupedValues<'a> {
1589    #[allow(clippy::type_complexity)]
1590    iter: Map<Iter<'a, Vec<AnyValue>>, fn(&Vec<AnyValue>) -> Vec<&str>>,
1591    len: usize,
1592}
1593
1594#[allow(deprecated)]
1595impl<'a> Iterator for GroupedValues<'a> {
1596    type Item = Vec<&'a str>;
1597
1598    fn next(&mut self) -> Option<Self::Item> {
1599        if let Some(next) = self.iter.next() {
1600            self.len -= 1;
1601            Some(next)
1602        } else {
1603            None
1604        }
1605    }
1606    fn size_hint(&self) -> (usize, Option<usize>) {
1607        (self.len, Some(self.len))
1608    }
1609}
1610
1611#[allow(deprecated)]
1612impl<'a> DoubleEndedIterator for GroupedValues<'a> {
1613    fn next_back(&mut self) -> Option<Self::Item> {
1614        if let Some(next) = self.iter.next_back() {
1615            self.len -= 1;
1616            Some(next)
1617        } else {
1618            None
1619        }
1620    }
1621}
1622
1623#[allow(deprecated)]
1624impl<'a> ExactSizeIterator for GroupedValues<'a> {}
1625
1626/// Creates an empty iterator. Used for `unwrap_or_default()`.
1627#[allow(deprecated)]
1628impl<'a> Default for GroupedValues<'a> {
1629    fn default() -> Self {
1630        static EMPTY: [Vec<AnyValue>; 0] = [];
1631        GroupedValues {
1632            iter: EMPTY[..].iter().map(|_| unreachable!()),
1633            len: 0,
1634        }
1635    }
1636}
1637
1638#[derive(Clone, Debug)]
1639pub struct Occurrences<T> {
1640    #[allow(clippy::type_complexity)]
1641    iter: Map<std::vec::IntoIter<Vec<AnyValue>>, fn(Vec<AnyValue>) -> OccurrenceValues<T>>,
1642}
1643
1644impl<T> Iterator for Occurrences<T> {
1645    type Item = OccurrenceValues<T>;
1646
1647    fn next(&mut self) -> Option<Self::Item> {
1648        self.iter.next()
1649    }
1650
1651    fn size_hint(&self) -> (usize, Option<usize>) {
1652        self.iter.size_hint()
1653    }
1654}
1655
1656impl<T> DoubleEndedIterator for Occurrences<T> {
1657    fn next_back(&mut self) -> Option<Self::Item> {
1658        self.iter.next_back()
1659    }
1660}
1661
1662impl<T> ExactSizeIterator for Occurrences<T> {}
1663
1664impl<T> Default for Occurrences<T> {
1665    fn default() -> Self {
1666        let empty: Vec<Vec<AnyValue>> = Default::default();
1667        Occurrences {
1668            iter: empty.into_iter().map(|_| unreachable!()),
1669        }
1670    }
1671}
1672
1673#[derive(Clone, Debug)]
1674pub struct OccurrenceValues<T> {
1675    #[allow(clippy::type_complexity)]
1676    iter: Map<std::vec::IntoIter<AnyValue>, fn(AnyValue) -> T>,
1677}
1678
1679impl<T> Iterator for OccurrenceValues<T> {
1680    type Item = T;
1681
1682    fn next(&mut self) -> Option<Self::Item> {
1683        self.iter.next()
1684    }
1685
1686    fn size_hint(&self) -> (usize, Option<usize>) {
1687        self.iter.size_hint()
1688    }
1689}
1690
1691impl<T> DoubleEndedIterator for OccurrenceValues<T> {
1692    fn next_back(&mut self) -> Option<Self::Item> {
1693        self.iter.next_back()
1694    }
1695}
1696
1697impl<T> ExactSizeIterator for OccurrenceValues<T> {}
1698
1699#[derive(Clone, Debug)]
1700pub struct OccurrencesRef<'a, T> {
1701    #[allow(clippy::type_complexity)]
1702    iter: Map<Iter<'a, Vec<AnyValue>>, fn(&Vec<AnyValue>) -> OccurrenceValuesRef<'_, T>>,
1703}
1704
1705impl<'a, T> Iterator for OccurrencesRef<'a, T>
1706where
1707    Self: 'a,
1708{
1709    type Item = OccurrenceValuesRef<'a, T>;
1710
1711    fn next(&mut self) -> Option<Self::Item> {
1712        self.iter.next()
1713    }
1714
1715    fn size_hint(&self) -> (usize, Option<usize>) {
1716        self.iter.size_hint()
1717    }
1718}
1719
1720impl<'a, T> DoubleEndedIterator for OccurrencesRef<'a, T>
1721where
1722    Self: 'a,
1723{
1724    fn next_back(&mut self) -> Option<Self::Item> {
1725        self.iter.next_back()
1726    }
1727}
1728
1729impl<'a, T> ExactSizeIterator for OccurrencesRef<'a, T> where Self: 'a {}
1730impl<'a, T> Default for OccurrencesRef<'a, T> {
1731    fn default() -> Self {
1732        static EMPTY: [Vec<AnyValue>; 0] = [];
1733        OccurrencesRef {
1734            iter: EMPTY[..].iter().map(|_| unreachable!()),
1735        }
1736    }
1737}
1738
1739#[derive(Clone, Debug)]
1740pub struct OccurrenceValuesRef<'a, T> {
1741    #[allow(clippy::type_complexity)]
1742    iter: Map<Iter<'a, AnyValue>, fn(&AnyValue) -> &T>,
1743}
1744
1745impl<'a, T> Iterator for OccurrenceValuesRef<'a, T>
1746where
1747    Self: 'a,
1748{
1749    type Item = &'a T;
1750
1751    fn next(&mut self) -> Option<Self::Item> {
1752        self.iter.next()
1753    }
1754
1755    fn size_hint(&self) -> (usize, Option<usize>) {
1756        self.iter.size_hint()
1757    }
1758}
1759
1760impl<'a, T> DoubleEndedIterator for OccurrenceValuesRef<'a, T>
1761where
1762    Self: 'a,
1763{
1764    fn next_back(&mut self) -> Option<Self::Item> {
1765        self.iter.next_back()
1766    }
1767}
1768
1769impl<'a, T> ExactSizeIterator for OccurrenceValuesRef<'a, T> where Self: 'a {}
1770
1771#[derive(Clone, Debug)]
1772pub struct RawOccurrences<'a> {
1773    #[allow(clippy::type_complexity)]
1774    iter: Map<Iter<'a, Vec<OsString>>, fn(&Vec<OsString>) -> RawOccurrenceValues<'_>>,
1775}
1776
1777impl<'a> Iterator for RawOccurrences<'a> {
1778    type Item = RawOccurrenceValues<'a>;
1779
1780    fn next(&mut self) -> Option<Self::Item> {
1781        self.iter.next()
1782    }
1783
1784    fn size_hint(&self) -> (usize, Option<usize>) {
1785        self.iter.size_hint()
1786    }
1787}
1788
1789impl<'a> DoubleEndedIterator for RawOccurrences<'a> {
1790    fn next_back(&mut self) -> Option<Self::Item> {
1791        self.iter.next_back()
1792    }
1793}
1794
1795impl<'a> ExactSizeIterator for RawOccurrences<'a> {}
1796
1797impl<'a> Default for RawOccurrences<'a> {
1798    fn default() -> Self {
1799        static EMPTY: [Vec<OsString>; 0] = [];
1800        RawOccurrences {
1801            iter: EMPTY[..].iter().map(|_| unreachable!()),
1802        }
1803    }
1804}
1805
1806#[derive(Clone, Debug)]
1807pub struct RawOccurrenceValues<'a> {
1808    #[allow(clippy::type_complexity)]
1809    iter: Map<Iter<'a, OsString>, fn(&OsString) -> &OsStr>,
1810}
1811
1812impl<'a> Iterator for RawOccurrenceValues<'a>
1813where
1814    Self: 'a,
1815{
1816    type Item = &'a OsStr;
1817
1818    fn next(&mut self) -> Option<Self::Item> {
1819        self.iter.next()
1820    }
1821
1822    fn size_hint(&self) -> (usize, Option<usize>) {
1823        self.iter.size_hint()
1824    }
1825}
1826
1827impl<'a> DoubleEndedIterator for RawOccurrenceValues<'a>
1828where
1829    Self: 'a,
1830{
1831    fn next_back(&mut self) -> Option<Self::Item> {
1832        self.iter.next_back()
1833    }
1834}
1835
1836impl<'a> ExactSizeIterator for RawOccurrenceValues<'a> {}
1837
1838/// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
1839///
1840/// # Examples
1841///
1842/// ```rust
1843/// # use clap_builder as clap;
1844/// # use clap::{Command, Arg, ArgAction};
1845/// let m = Command::new("myapp")
1846///     .arg(Arg::new("output")
1847///         .short('o')
1848///         .num_args(1..)
1849///         .action(ArgAction::Set))
1850///     .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
1851///
1852/// let mut indices = m.indices_of("output").unwrap();
1853///
1854/// assert_eq!(indices.next(), Some(2));
1855/// assert_eq!(indices.next(), Some(3));
1856/// assert_eq!(indices.next(), None);
1857/// ```
1858/// [`ArgMatches::indices_of`]: ArgMatches::indices_of()
1859#[derive(Clone, Debug)]
1860pub struct Indices<'a> {
1861    iter: Cloned<Iter<'a, usize>>,
1862    len: usize,
1863}
1864
1865impl<'a> Iterator for Indices<'a> {
1866    type Item = usize;
1867
1868    fn next(&mut self) -> Option<usize> {
1869        if let Some(next) = self.iter.next() {
1870            self.len -= 1;
1871            Some(next)
1872        } else {
1873            None
1874        }
1875    }
1876    fn size_hint(&self) -> (usize, Option<usize>) {
1877        (self.len, Some(self.len))
1878    }
1879}
1880
1881impl<'a> DoubleEndedIterator for Indices<'a> {
1882    fn next_back(&mut self) -> Option<usize> {
1883        if let Some(next) = self.iter.next_back() {
1884            self.len -= 1;
1885            Some(next)
1886        } else {
1887            None
1888        }
1889    }
1890}
1891
1892impl<'a> ExactSizeIterator for Indices<'a> {}
1893
1894/// Creates an empty iterator.
1895impl<'a> Default for Indices<'a> {
1896    fn default() -> Self {
1897        static EMPTY: [usize; 0] = [];
1898        // This is never called because the iterator is empty:
1899        Indices {
1900            iter: EMPTY[..].iter().cloned(),
1901            len: 0,
1902        }
1903    }
1904}
1905
1906#[track_caller]
1907fn unwrap_downcast_ref<T: Any + Clone + Send + Sync + 'static>(value: &AnyValue) -> &T {
1908    value.downcast_ref().expect(INTERNAL_ERROR_MSG)
1909}
1910
1911#[track_caller]
1912fn unwrap_downcast_into<T: Any + Clone + Send + Sync + 'static>(value: AnyValue) -> T {
1913    value.downcast_into().expect(INTERNAL_ERROR_MSG)
1914}
1915
1916#[cfg(test)]
1917mod tests {
1918    use super::*;
1919
1920    use crate::ArgAction;
1921
1922    #[test]
1923    fn check_auto_traits() {
1924        static_assertions::assert_impl_all!(ArgMatches: Send, Sync, Unpin);
1925    }
1926
1927    #[test]
1928    fn test_default_raw_values() {
1929        let mut values: RawValues<'_> = Default::default();
1930        assert_eq!(values.next(), None);
1931    }
1932
1933    #[test]
1934    fn test_default_indices() {
1935        let mut indices: Indices<'_> = Indices::default();
1936        assert_eq!(indices.next(), None);
1937    }
1938
1939    #[test]
1940    fn test_default_indices_with_shorter_lifetime() {
1941        let matches = ArgMatches::default();
1942        let mut indices = matches.indices_of("").unwrap_or_default();
1943        assert_eq!(indices.next(), None);
1944    }
1945
1946    #[test]
1947    fn values_exact_size() {
1948        let l = crate::Command::new("test")
1949            .arg(
1950                crate::Arg::new("POTATO")
1951                    .action(ArgAction::Set)
1952                    .num_args(1..)
1953                    .required(true),
1954            )
1955            .try_get_matches_from(["test", "one"])
1956            .unwrap()
1957            .get_many::<String>("POTATO")
1958            .expect("present")
1959            .count();
1960        assert_eq!(l, 1);
1961    }
1962
1963    #[test]
1964    fn os_values_exact_size() {
1965        let l = crate::Command::new("test")
1966            .arg(
1967                crate::Arg::new("POTATO")
1968                    .action(ArgAction::Set)
1969                    .num_args(1..)
1970                    .value_parser(crate::builder::ValueParser::os_string())
1971                    .required(true),
1972            )
1973            .try_get_matches_from(["test", "one"])
1974            .unwrap()
1975            .get_many::<OsString>("POTATO")
1976            .expect("present")
1977            .count();
1978        assert_eq!(l, 1);
1979    }
1980
1981    #[test]
1982    fn indices_exact_size() {
1983        let l = crate::Command::new("test")
1984            .arg(
1985                crate::Arg::new("POTATO")
1986                    .action(ArgAction::Set)
1987                    .num_args(1..)
1988                    .required(true),
1989            )
1990            .try_get_matches_from(["test", "one"])
1991            .unwrap()
1992            .indices_of("POTATO")
1993            .expect("present")
1994            .len();
1995        assert_eq!(l, 1);
1996    }
1997
1998    #[test]
1999    fn rev_iter() {
2000        let mut matches = crate::Command::new("myprog")
2001            .arg(crate::Arg::new("a").short('a').action(ArgAction::Append))
2002            .arg(crate::Arg::new("b").short('b').action(ArgAction::Append))
2003            .try_get_matches_from(vec!["myprog", "-a1", "-b1", "-b3"])
2004            .unwrap();
2005
2006        let a_index = matches
2007            .indices_of("a")
2008            .expect("missing aopt indices")
2009            .collect::<Vec<_>>();
2010        dbg!(&a_index);
2011        let a_value = matches
2012            .remove_many::<String>("a")
2013            .expect("missing aopt values");
2014        dbg!(&a_value);
2015        let a = a_index.into_iter().zip(a_value).rev().collect::<Vec<_>>();
2016        dbg!(a);
2017
2018        let b_index = matches
2019            .indices_of("b")
2020            .expect("missing aopt indices")
2021            .collect::<Vec<_>>();
2022        dbg!(&b_index);
2023        let b_value = matches
2024            .remove_many::<String>("b")
2025            .expect("missing aopt values");
2026        dbg!(&b_value);
2027        let b = b_index.into_iter().zip(b_value).rev().collect::<Vec<_>>();
2028        dbg!(b);
2029    }
2030}