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