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