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