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