• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Std
2 use std::any::Any;
3 use std::ffi::{OsStr, OsString};
4 use std::fmt::Debug;
5 use std::iter::{Cloned, Flatten, Map};
6 use std::slice::Iter;
7 
8 // Internal
9 #[cfg(debug_assertions)]
10 use crate::builder::Str;
11 use crate::parser::AnyValue;
12 use crate::parser::AnyValueId;
13 use crate::parser::MatchedArg;
14 use crate::parser::MatchesError;
15 use crate::parser::ValueSource;
16 use crate::util::FlatMap;
17 use crate::util::Id;
18 use 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)]
66 pub 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
76 impl 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)]
get_one<T: Any + Clone + Send + Sync + 'static>(&self, id: &str) -> Option<&T>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)]
get_count(&self, id: &str) -> u8141     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)]
get_flag(&self, id: &str) -> bool176     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)]
get_many<T: Any + Clone + Send + Sync + 'static>( &self, id: &str, ) -> Option<ValuesRef<T>>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)]
get_occurrences<T: Any + Clone + Send + Sync + 'static>( &self, id: &str, ) -> Option<OccurrencesRef<T>>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)]
get_raw(&self, id: &str) -> Option<RawValues<'_>>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)]
get_raw_occurrences(&self, id: &str) -> Option<RawOccurrences<'_>>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)]
remove_one<T: Any + Clone + Send + Sync + 'static>(&mut self, id: &str) -> Option<T>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)]
remove_many<T: Any + Clone + Send + Sync + 'static>( &mut self, id: &str, ) -> Option<Values<T>>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)]
remove_occurrences<T: Any + Clone + Send + Sync + 'static>( &mut self, id: &str, ) -> Option<Occurrences<T>>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()
contains_id(&self, id: &str) -> bool503     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     /// ```
ids(&self) -> IdsRef<'_>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());
args_present(&self) -> bool553     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)]
grouped_values_of(&self, id: &str) -> Option<GroupedValues>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)]
value_source(&self, id: &str) -> Option<ValueSource>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)]
index_of(&self, id: &str) -> Option<usize>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)]
indices_of(&self, id: &str) -> Option<Indices<'_>>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
872 impl 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]
subcommand(&self) -> Option<(&str, &ArgMatches)>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
remove_subcommand(&mut self) -> Option<(String, ArgMatches)>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
subcommand_matches(&self, name: &str) -> Option<&ArgMatches>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]
subcommand_name(&self) -> Option<&str>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)]
is_valid_subcommand(&self, _name: &str) -> bool1066     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
1079 impl ArgMatches {
1080     /// Non-panicking version of [`ArgMatches::get_one`]
try_get_one<T: Any + Clone + Send + Sync + 'static>( &self, id: &str, ) -> Result<Option<&T>, MatchesError>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`]
try_get_many<T: Any + Clone + Send + Sync + 'static>( &self, id: &str, ) -> Result<Option<ValuesRef<T>>, MatchesError>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`]
try_get_occurrences<T: Any + Clone + Send + Sync + 'static>( &self, id: &str, ) -> Result<Option<OccurrencesRef<T>>, MatchesError>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`]
try_get_raw(&self, id: &str) -> Result<Option<RawValues<'_>>, MatchesError>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`]
try_get_raw_occurrences( &self, id: &str, ) -> Result<Option<RawOccurrences<'_>>, MatchesError>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`]
try_remove_one<T: Any + Clone + Send + Sync + 'static>( &mut self, id: &str, ) -> Result<Option<T>, MatchesError>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`]
try_remove_many<T: Any + Clone + Send + Sync + 'static>( &mut self, id: &str, ) -> Result<Option<Values<T>>, MatchesError>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`]
try_remove_occurrences<T: Any + Clone + Send + Sync + 'static>( &mut self, id: &str, ) -> Result<Option<Occurrences<T>>, MatchesError>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`]
try_contains_id(&self, id: &str) -> Result<bool, MatchesError>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
1229 impl ArgMatches {
1230     #[inline]
try_get_arg(&self, arg: &str) -> Result<Option<&MatchedArg>, MatchesError>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]
try_get_arg_t<T: Any + Send + Sync + 'static>( &self, arg: &str, ) -> Result<Option<&MatchedArg>, MatchesError>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]
try_remove_arg_t<T: Any + Send + Sync + 'static>( &mut self, arg: &str, ) -> Result<Option<MatchedArg>, MatchesError>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 
verify_arg_t<T: Any + Send + Sync + 'static>( &self, arg: &MatchedArg, ) -> Result<(), MatchesError>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]
verify_arg(&self, _arg: &str) -> Result<(), MatchesError>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)]
get_arg<'s>(&'s self, arg: &str) -> Option<&'s MatchedArg>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)]
get_subcommand(&self, name: &str) -> Option<&SubCommand>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)]
1345 pub(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)]
1371 pub struct IdsRef<'a> {
1372     iter: std::slice::Iter<'a, Id>,
1373 }
1374 
1375 impl<'a> Iterator for IdsRef<'a> {
1376     type Item = &'a Id;
1377 
next(&mut self) -> Option<&'a Id>1378     fn next(&mut self) -> Option<&'a Id> {
1379         self.iter.next()
1380     }
size_hint(&self) -> (usize, Option<usize>)1381     fn size_hint(&self) -> (usize, Option<usize>) {
1382         self.iter.size_hint()
1383     }
1384 }
1385 
1386 impl<'a> DoubleEndedIterator for IdsRef<'a> {
next_back(&mut self) -> Option<&'a Id>1387     fn next_back(&mut self) -> Option<&'a Id> {
1388         self.iter.next_back()
1389     }
1390 }
1391 
1392 impl<'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)]
1414 pub 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 
1420 impl<T> Iterator for Values<T> {
1421     type Item = T;
1422 
next(&mut self) -> Option<Self::Item>1423     fn next(&mut self) -> Option<Self::Item> {
1424         self.iter.next()
1425     }
size_hint(&self) -> (usize, Option<usize>)1426     fn size_hint(&self) -> (usize, Option<usize>) {
1427         (self.len, Some(self.len))
1428     }
1429 }
1430 
1431 impl<T> DoubleEndedIterator for Values<T> {
next_back(&mut self) -> Option<Self::Item>1432     fn next_back(&mut self) -> Option<Self::Item> {
1433         self.iter.next_back()
1434     }
1435 }
1436 
1437 impl<T> ExactSizeIterator for Values<T> {}
1438 
1439 /// Creates an empty iterator.
1440 impl<T> Default for Values<T> {
default() -> Self1441     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)]
1471 pub 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 
1477 impl<'a, T: 'a> Iterator for ValuesRef<'a, T> {
1478     type Item = &'a T;
1479 
next(&mut self) -> Option<Self::Item>1480     fn next(&mut self) -> Option<Self::Item> {
1481         self.iter.next()
1482     }
size_hint(&self) -> (usize, Option<usize>)1483     fn size_hint(&self) -> (usize, Option<usize>) {
1484         (self.len, Some(self.len))
1485     }
1486 }
1487 
1488 impl<'a, T: 'a> DoubleEndedIterator for ValuesRef<'a, T> {
next_back(&mut self) -> Option<Self::Item>1489     fn next_back(&mut self) -> Option<Self::Item> {
1490         self.iter.next_back()
1491     }
1492 }
1493 
1494 impl<'a, T: 'a> ExactSizeIterator for ValuesRef<'a, T> {}
1495 
1496 /// Creates an empty iterator.
1497 impl<'a, T: 'a> Default for ValuesRef<'a, T> {
default() -> Self1498     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)]
1532 pub struct RawValues<'a> {
1533     #[allow(clippy::type_complexity)]
1534     iter: Map<Flatten<Iter<'a, Vec<OsString>>>, fn(&OsString) -> &OsStr>,
1535     len: usize,
1536 }
1537 
1538 impl<'a> Iterator for RawValues<'a> {
1539     type Item = &'a OsStr;
1540 
next(&mut self) -> Option<&'a OsStr>1541     fn next(&mut self) -> Option<&'a OsStr> {
1542         self.iter.next()
1543     }
size_hint(&self) -> (usize, Option<usize>)1544     fn size_hint(&self) -> (usize, Option<usize>) {
1545         (self.len, Some(self.len))
1546     }
1547 }
1548 
1549 impl<'a> DoubleEndedIterator for RawValues<'a> {
next_back(&mut self) -> Option<&'a OsStr>1550     fn next_back(&mut self) -> Option<&'a OsStr> {
1551         self.iter.next_back()
1552     }
1553 }
1554 
1555 impl<'a> ExactSizeIterator for RawValues<'a> {}
1556 
1557 /// Creates an empty iterator.
1558 impl Default for RawValues<'_> {
default() -> Self1559     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")]
1575 pub 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)]
1582 impl<'a> Iterator for GroupedValues<'a> {
1583     type Item = Vec<&'a str>;
1584 
next(&mut self) -> Option<Self::Item>1585     fn next(&mut self) -> Option<Self::Item> {
1586         self.iter.next()
1587     }
size_hint(&self) -> (usize, Option<usize>)1588     fn size_hint(&self) -> (usize, Option<usize>) {
1589         (self.len, Some(self.len))
1590     }
1591 }
1592 
1593 #[allow(deprecated)]
1594 impl<'a> DoubleEndedIterator for GroupedValues<'a> {
next_back(&mut self) -> Option<Self::Item>1595     fn next_back(&mut self) -> Option<Self::Item> {
1596         self.iter.next_back()
1597     }
1598 }
1599 
1600 #[allow(deprecated)]
1601 impl<'a> ExactSizeIterator for GroupedValues<'a> {}
1602 
1603 /// Creates an empty iterator. Used for `unwrap_or_default()`.
1604 #[allow(deprecated)]
1605 impl<'a> Default for GroupedValues<'a> {
default() -> Self1606     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)]
1616 pub struct Occurrences<T> {
1617     #[allow(clippy::type_complexity)]
1618     iter: Map<std::vec::IntoIter<Vec<AnyValue>>, fn(Vec<AnyValue>) -> OccurrenceValues<T>>,
1619 }
1620 
1621 impl<T> Iterator for Occurrences<T> {
1622     type Item = OccurrenceValues<T>;
1623 
next(&mut self) -> Option<Self::Item>1624     fn next(&mut self) -> Option<Self::Item> {
1625         self.iter.next()
1626     }
1627 
size_hint(&self) -> (usize, Option<usize>)1628     fn size_hint(&self) -> (usize, Option<usize>) {
1629         self.iter.size_hint()
1630     }
1631 }
1632 
1633 impl<T> DoubleEndedIterator for Occurrences<T> {
next_back(&mut self) -> Option<Self::Item>1634     fn next_back(&mut self) -> Option<Self::Item> {
1635         self.iter.next_back()
1636     }
1637 }
1638 
1639 impl<T> ExactSizeIterator for Occurrences<T> {}
1640 
1641 impl<T> Default for Occurrences<T> {
default() -> Self1642     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)]
1651 pub struct OccurrenceValues<T> {
1652     #[allow(clippy::type_complexity)]
1653     iter: Map<std::vec::IntoIter<AnyValue>, fn(AnyValue) -> T>,
1654 }
1655 
1656 impl<T> Iterator for OccurrenceValues<T> {
1657     type Item = T;
1658 
next(&mut self) -> Option<Self::Item>1659     fn next(&mut self) -> Option<Self::Item> {
1660         self.iter.next()
1661     }
1662 
size_hint(&self) -> (usize, Option<usize>)1663     fn size_hint(&self) -> (usize, Option<usize>) {
1664         self.iter.size_hint()
1665     }
1666 }
1667 
1668 impl<T> DoubleEndedIterator for OccurrenceValues<T> {
next_back(&mut self) -> Option<Self::Item>1669     fn next_back(&mut self) -> Option<Self::Item> {
1670         self.iter.next_back()
1671     }
1672 }
1673 
1674 impl<T> ExactSizeIterator for OccurrenceValues<T> {}
1675 
1676 #[derive(Clone, Debug)]
1677 pub struct OccurrencesRef<'a, T> {
1678     #[allow(clippy::type_complexity)]
1679     iter: Map<Iter<'a, Vec<AnyValue>>, fn(&Vec<AnyValue>) -> OccurrenceValuesRef<'_, T>>,
1680 }
1681 
1682 impl<'a, T> Iterator for OccurrencesRef<'a, T>
1683 where
1684     Self: 'a,
1685 {
1686     type Item = OccurrenceValuesRef<'a, T>;
1687 
next(&mut self) -> Option<Self::Item>1688     fn next(&mut self) -> Option<Self::Item> {
1689         self.iter.next()
1690     }
1691 
size_hint(&self) -> (usize, Option<usize>)1692     fn size_hint(&self) -> (usize, Option<usize>) {
1693         self.iter.size_hint()
1694     }
1695 }
1696 
1697 impl<'a, T> DoubleEndedIterator for OccurrencesRef<'a, T>
1698 where
1699     Self: 'a,
1700 {
next_back(&mut self) -> Option<Self::Item>1701     fn next_back(&mut self) -> Option<Self::Item> {
1702         self.iter.next_back()
1703     }
1704 }
1705 
1706 impl<'a, T> ExactSizeIterator for OccurrencesRef<'a, T> where Self: 'a {}
1707 impl<'a, T> Default for OccurrencesRef<'a, T> {
default() -> Self1708     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)]
1717 pub struct OccurrenceValuesRef<'a, T> {
1718     #[allow(clippy::type_complexity)]
1719     iter: Map<Iter<'a, AnyValue>, fn(&AnyValue) -> &T>,
1720 }
1721 
1722 impl<'a, T> Iterator for OccurrenceValuesRef<'a, T>
1723 where
1724     Self: 'a,
1725 {
1726     type Item = &'a T;
1727 
next(&mut self) -> Option<Self::Item>1728     fn next(&mut self) -> Option<Self::Item> {
1729         self.iter.next()
1730     }
1731 
size_hint(&self) -> (usize, Option<usize>)1732     fn size_hint(&self) -> (usize, Option<usize>) {
1733         self.iter.size_hint()
1734     }
1735 }
1736 
1737 impl<'a, T> DoubleEndedIterator for OccurrenceValuesRef<'a, T>
1738 where
1739     Self: 'a,
1740 {
next_back(&mut self) -> Option<Self::Item>1741     fn next_back(&mut self) -> Option<Self::Item> {
1742         self.iter.next_back()
1743     }
1744 }
1745 
1746 impl<'a, T> ExactSizeIterator for OccurrenceValuesRef<'a, T> where Self: 'a {}
1747 
1748 #[derive(Clone, Debug)]
1749 pub struct RawOccurrences<'a> {
1750     #[allow(clippy::type_complexity)]
1751     iter: Map<Iter<'a, Vec<OsString>>, fn(&Vec<OsString>) -> RawOccurrenceValues<'_>>,
1752 }
1753 
1754 impl<'a> Iterator for RawOccurrences<'a> {
1755     type Item = RawOccurrenceValues<'a>;
1756 
next(&mut self) -> Option<Self::Item>1757     fn next(&mut self) -> Option<Self::Item> {
1758         self.iter.next()
1759     }
1760 
size_hint(&self) -> (usize, Option<usize>)1761     fn size_hint(&self) -> (usize, Option<usize>) {
1762         self.iter.size_hint()
1763     }
1764 }
1765 
1766 impl<'a> DoubleEndedIterator for RawOccurrences<'a> {
next_back(&mut self) -> Option<Self::Item>1767     fn next_back(&mut self) -> Option<Self::Item> {
1768         self.iter.next_back()
1769     }
1770 }
1771 
1772 impl<'a> ExactSizeIterator for RawOccurrences<'a> {}
1773 
1774 impl<'a> Default for RawOccurrences<'a> {
default() -> Self1775     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)]
1784 pub struct RawOccurrenceValues<'a> {
1785     #[allow(clippy::type_complexity)]
1786     iter: Map<Iter<'a, OsString>, fn(&OsString) -> &OsStr>,
1787 }
1788 
1789 impl<'a> Iterator for RawOccurrenceValues<'a>
1790 where
1791     Self: 'a,
1792 {
1793     type Item = &'a OsStr;
1794 
next(&mut self) -> Option<Self::Item>1795     fn next(&mut self) -> Option<Self::Item> {
1796         self.iter.next()
1797     }
1798 
size_hint(&self) -> (usize, Option<usize>)1799     fn size_hint(&self) -> (usize, Option<usize>) {
1800         self.iter.size_hint()
1801     }
1802 }
1803 
1804 impl<'a> DoubleEndedIterator for RawOccurrenceValues<'a>
1805 where
1806     Self: 'a,
1807 {
next_back(&mut self) -> Option<Self::Item>1808     fn next_back(&mut self) -> Option<Self::Item> {
1809         self.iter.next_back()
1810     }
1811 }
1812 
1813 impl<'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)]
1836 pub struct Indices<'a> {
1837     iter: Cloned<Iter<'a, usize>>,
1838     len: usize,
1839 }
1840 
1841 impl<'a> Iterator for Indices<'a> {
1842     type Item = usize;
1843 
next(&mut self) -> Option<usize>1844     fn next(&mut self) -> Option<usize> {
1845         self.iter.next()
1846     }
size_hint(&self) -> (usize, Option<usize>)1847     fn size_hint(&self) -> (usize, Option<usize>) {
1848         (self.len, Some(self.len))
1849     }
1850 }
1851 
1852 impl<'a> DoubleEndedIterator for Indices<'a> {
next_back(&mut self) -> Option<usize>1853     fn next_back(&mut self) -> Option<usize> {
1854         self.iter.next_back()
1855     }
1856 }
1857 
1858 impl<'a> ExactSizeIterator for Indices<'a> {}
1859 
1860 /// Creates an empty iterator.
1861 impl<'a> Default for Indices<'a> {
default() -> Self1862     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")]
unwrap_string(value: &AnyValue) -> &str1875 fn 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]
unwrap_downcast_ref<T: Any + Clone + Send + Sync + 'static>(value: &AnyValue) -> &T1885 fn 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]
unwrap_downcast_into<T: Any + Clone + Send + Sync + 'static>(value: AnyValue) -> T1890 fn 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)]
1895 mod tests {
1896     use super::*;
1897 
1898     use crate::ArgAction;
1899 
1900     #[test]
check_auto_traits()1901     fn check_auto_traits() {
1902         static_assertions::assert_impl_all!(ArgMatches: Send, Sync, Unpin);
1903     }
1904 
1905     #[test]
test_default_raw_values()1906     fn test_default_raw_values() {
1907         let mut values: RawValues = Default::default();
1908         assert_eq!(values.next(), None);
1909     }
1910 
1911     #[test]
test_default_indices()1912     fn test_default_indices() {
1913         let mut indices: Indices = Indices::default();
1914         assert_eq!(indices.next(), None);
1915     }
1916 
1917     #[test]
test_default_indices_with_shorter_lifetime()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]
values_exact_size()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]
os_values_exact_size()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]
indices_exact_size()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