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