1 // Std
2 use std::{
3     borrow::Cow,
4     ffi::{OsStr, OsString},
5     fmt::{Debug, Display},
6     iter::{Cloned, Flatten, Map},
7     slice::Iter,
8     str::FromStr,
9 };
10 
11 // Third Party
12 use indexmap::IndexMap;
13 
14 // Internal
15 use crate::{
16     parse::MatchedArg,
17     util::{Id, Key},
18     {Error, INVALID_UTF8},
19 };
20 
21 /// Container for parse results.
22 ///
23 /// Used to get information about the arguments that were supplied to the program at runtime by
24 /// the user. New instances of this struct are obtained by using the [`App::get_matches`] family of
25 /// methods.
26 ///
27 /// # Examples
28 ///
29 /// ```no_run
30 /// # use clap::{App, Arg};
31 /// let matches = App::new("MyApp")
32 ///     .arg(Arg::new("out")
33 ///         .long("output")
34 ///         .required(true)
35 ///         .takes_value(true))
36 ///     .arg(Arg::new("debug")
37 ///         .short('d')
38 ///         .multiple_occurrences(true))
39 ///     .arg(Arg::new("cfg")
40 ///         .short('c')
41 ///         .takes_value(true))
42 ///     .get_matches(); // builds the instance of ArgMatches
43 ///
44 /// // to get information about the "cfg" argument we created, such as the value supplied we use
45 /// // various ArgMatches methods, such as ArgMatches::value_of
46 /// if let Some(c) = matches.value_of("cfg") {
47 ///     println!("Value for -c: {}", c);
48 /// }
49 ///
50 /// // The ArgMatches::value_of method returns an Option because the user may not have supplied
51 /// // that argument at runtime. But if we specified that the argument was "required" as we did
52 /// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually
53 /// // used at runtime.
54 /// println!("Value for --output: {}", matches.value_of("out").unwrap());
55 ///
56 /// // You can check the presence of an argument
57 /// if matches.is_present("out") {
58 ///     // Another way to check if an argument was present, or if it occurred multiple times is to
59 ///     // use occurrences_of() which returns 0 if an argument isn't found at runtime, or the
60 ///     // number of times that it occurred, if it was. To allow an argument to appear more than
61 ///     // once, you must use the .multiple_occurrences(true) method, otherwise it will only return 1 or 0.
62 ///     if matches.occurrences_of("debug") > 2 {
63 ///         println!("Debug mode is REALLY on, don't be crazy");
64 ///     } else {
65 ///         println!("Debug mode kind of on");
66 ///     }
67 /// }
68 /// ```
69 /// [`App::get_matches`]: crate::App::get_matches()
70 #[derive(Debug, Clone, Default, PartialEq, Eq)]
71 pub struct ArgMatches {
72     #[cfg(debug_assertions)]
73     pub(crate) valid_args: Vec<Id>,
74     #[cfg(debug_assertions)]
75     pub(crate) valid_subcommands: Vec<Id>,
76     #[cfg(debug_assertions)]
77     pub(crate) disable_asserts: bool,
78     pub(crate) args: IndexMap<Id, MatchedArg>,
79     pub(crate) subcommand: Option<Box<SubCommand>>,
80 }
81 
82 impl ArgMatches {
83     /// Check if any args were present on the command line
84     ///
85     /// # Examples
86     ///
87     /// ```rust
88     /// # use clap::{App, Arg};
89     /// let mut app = App::new("myapp")
90     ///     .arg(Arg::new("output")
91     ///         .takes_value(true));
92     ///
93     /// let m = app
94     ///     .try_get_matches_from_mut(vec!["myapp", "something"])
95     ///     .unwrap();
96     /// assert!(m.args_present());
97     ///
98     /// let m = app
99     ///     .try_get_matches_from_mut(vec!["myapp"])
100     ///     .unwrap();
101     /// assert!(! m.args_present());
args_present(&self) -> bool102     pub fn args_present(&self) -> bool {
103         !self.args.is_empty()
104     }
105 
106     /// Gets the value of a specific option or positional argument.
107     ///
108     /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime.
109     ///
110     /// Returns `None` if the option wasn't present.
111     ///
112     /// *NOTE:* Prefer [`ArgMatches::values_of`] if getting a value for an option or positional
113     /// argument that allows multiples as `ArgMatches::value_of` will only return the *first*
114     /// value.
115     ///
116     /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
117     /// [`occurrences_of`] can be used to check if a value is present at runtime.
118     ///
119     /// # Panics
120     ///
121     /// If the value is invalid UTF-8.  See
122     /// [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
123     ///
124     /// If `id` is is not a valid argument or group name.
125     ///
126     /// # Examples
127     ///
128     /// ```rust
129     /// # use clap::{App, Arg};
130     /// let m = App::new("myapp")
131     ///     .arg(Arg::new("output")
132     ///         .takes_value(true))
133     ///     .get_matches_from(vec!["myapp", "something"]);
134     ///
135     /// assert_eq!(m.value_of("output"), Some("something"));
136     /// ```
137     /// [option]: crate::Arg::takes_value()
138     /// [positional]: crate::Arg::index()
139     /// [`ArgMatches::values_of`]: ArgMatches::values_of()
140     /// [`default_value`]: crate::Arg::default_value()
141     /// [`occurrences_of`]: crate::ArgMatches::occurrences_of()
value_of<T: Key>(&self, id: T) -> Option<&str>142     pub fn value_of<T: Key>(&self, id: T) -> Option<&str> {
143         let id = Id::from(id);
144         let arg = self.get_arg(&id)?;
145         assert_utf8_validation(arg, &id);
146         let v = arg.first()?;
147         Some(v.to_str().expect(INVALID_UTF8))
148     }
149 
150     /// Gets the lossy value of a specific option or positional argument.
151     ///
152     /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime.
153     ///
154     /// A lossy value is one which contains invalid UTF-8, those invalid points will be replaced
155     /// with `\u{FFFD}`
156     ///
157     /// Returns `None` if the option wasn't present.
158     ///
159     /// *NOTE:* Recommend having set [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
160     ///
161     /// *NOTE:* Prefer [`ArgMatches::values_of_lossy`] if getting a value for an option or positional
162     /// argument that allows multiples as `ArgMatches::value_of_lossy` will only return the *first*
163     /// value.
164     ///
165     /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
166     /// [`occurrences_of`] can be used to check if a value is present at runtime.
167     ///
168     /// # Panics
169     ///
170     /// If `id` is is not a valid argument or group name.
171     ///
172     /// # Examples
173     ///
174     #[cfg_attr(not(unix), doc = " ```ignore")]
175     #[cfg_attr(unix, doc = " ```")]
176     /// # use clap::{App, arg};
177     /// use std::ffi::OsString;
178     /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
179     ///
180     /// let m = App::new("utf8")
181     ///     .arg(arg!(<arg> "some arg")
182     ///         .allow_invalid_utf8(true))
183     ///     .get_matches_from(vec![OsString::from("myprog"),
184     ///                             // "Hi {0xe9}!"
185     ///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
186     /// assert_eq!(&*m.value_of_lossy("arg").unwrap(), "Hi \u{FFFD}!");
187     /// ```
188     /// [`default_value`]: crate::Arg::default_value()
189     /// [`occurrences_of`]: ArgMatches::occurrences_of()
190     /// [`Arg::values_of_lossy`]: ArgMatches::values_of_lossy()
191     #[cfg_attr(debug_assertions, track_caller)]
value_of_lossy<T: Key>(&self, id: T) -> Option<Cow<'_, str>>192     pub fn value_of_lossy<T: Key>(&self, id: T) -> Option<Cow<'_, str>> {
193         let id = Id::from(id);
194         let arg = self.get_arg(&id)?;
195         assert_no_utf8_validation(arg, &id);
196         let v = arg.first()?;
197         Some(v.to_string_lossy())
198     }
199 
200     /// Get the `OsStr` value of a specific option or positional argument.
201     ///
202     /// i.e. an argument that [takes an additional value][crate::Arg::takes_value] at runtime.
203     ///
204     /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
205     /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
206     /// filename on a Unix system as an argument value may contain invalid UTF-8.
207     ///
208     /// Returns `None` if the option wasn't present.
209     ///
210     /// *NOTE:* Recommend having set [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
211     ///
212     /// *NOTE:* Prefer [`ArgMatches::values_of_os`] if getting a value for an option or positional
213     /// argument that allows multiples as `ArgMatches::value_of_os` will only return the *first*
214     /// value.
215     ///
216     /// *NOTE:* This will always return `Some(value)` if [`default_value`] has been set.
217     /// [`occurrences_of`] can be used to check if a value is present at runtime.
218     ///
219     /// # Panics
220     ///
221     /// If `id` is is not a valid argument or group name.
222     ///
223     /// # Examples
224     ///
225     #[cfg_attr(not(unix), doc = " ```ignore")]
226     #[cfg_attr(unix, doc = " ```")]
227     /// # use clap::{App, arg};
228     /// use std::ffi::OsString;
229     /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
230     ///
231     /// let m = App::new("utf8")
232     ///     .arg(arg!(<arg> "some arg")
233     ///         .allow_invalid_utf8(true))
234     ///     .get_matches_from(vec![OsString::from("myprog"),
235     ///                             // "Hi {0xe9}!"
236     ///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
237     /// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']);
238     /// ```
239     /// [`default_value`]: crate::Arg::default_value()
240     /// [`occurrences_of`]: ArgMatches::occurrences_of()
241     /// [`ArgMatches::values_of_os`]: ArgMatches::values_of_os()
242     #[cfg_attr(debug_assertions, track_caller)]
value_of_os<T: Key>(&self, id: T) -> Option<&OsStr>243     pub fn value_of_os<T: Key>(&self, id: T) -> Option<&OsStr> {
244         let id = Id::from(id);
245         let arg = self.get_arg(&id)?;
246         assert_no_utf8_validation(arg, &id);
247         let v = arg.first()?;
248         Some(v.as_os_str())
249     }
250 
251     /// Get an [`Iterator`] over [values] of a specific option or positional argument.
252     ///
253     /// i.e. an argument that takes multiple values at runtime.
254     ///
255     /// Returns `None` if the option wasn't present.
256     ///
257     /// # Panics
258     ///
259     /// If the value is invalid UTF-8.  See
260     /// [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
261     ///
262     /// If `id` is is not a valid argument or group name.
263     ///
264     /// # Examples
265     ///
266     /// ```rust
267     /// # use clap::{App, Arg};
268     /// let m = App::new("myprog")
269     ///     .arg(Arg::new("output")
270     ///         .multiple_occurrences(true)
271     ///         .short('o')
272     ///         .takes_value(true))
273     ///     .get_matches_from(vec![
274     ///         "myprog", "-o", "val1", "-o", "val2", "-o", "val3"
275     ///     ]);
276     /// let vals: Vec<&str> = m.values_of("output").unwrap().collect();
277     /// assert_eq!(vals, ["val1", "val2", "val3"]);
278     /// ```
279     /// [values]: Values
280     /// [`Iterator`]: std::iter::Iterator
values_of<T: Key>(&self, id: T) -> Option<Values>281     pub fn values_of<T: Key>(&self, id: T) -> Option<Values> {
282         let id = Id::from(id);
283         let arg = self.get_arg(&id)?;
284         assert_utf8_validation(arg, &id);
285         fn to_str_slice(o: &OsString) -> &str {
286             o.to_str().expect(INVALID_UTF8)
287         }
288         let v = Values {
289             iter: arg.vals_flatten().map(to_str_slice),
290             len: arg.num_vals(),
291         };
292         Some(v)
293     }
294 
295     /// Placeholder documentation.
296     #[cfg(feature = "unstable-grouped")]
grouped_values_of<T: Key>(&self, id: T) -> Option<GroupedValues>297     pub fn grouped_values_of<T: Key>(&self, id: T) -> Option<GroupedValues> {
298         let id = Id::from(id);
299         let arg = self.get_arg(&id)?;
300         assert_utf8_validation(arg, &id);
301         let v = GroupedValues {
302             iter: arg
303                 .vals()
304                 .map(|g| g.iter().map(|x| x.to_str().expect(INVALID_UTF8)).collect()),
305             len: arg.vals().len(),
306         };
307         Some(v)
308     }
309 
310     /// Get the lossy values of a specific option or positional argument.
311     ///
312     /// i.e. an argument that takes multiple values at runtime.
313     ///
314     /// A lossy value is one which contains invalid UTF-8, those invalid points will be replaced
315     /// with `\u{FFFD}`
316     ///
317     /// Returns `None` if the option wasn't present.
318     ///
319     /// *NOTE:* Recommend having set [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
320     ///
321     /// # Panics
322     ///
323     /// If `id` is is not a valid argument or group name.
324     ///
325     /// # Examples
326     ///
327     #[cfg_attr(not(unix), doc = " ```ignore")]
328     #[cfg_attr(unix, doc = " ```")]
329     /// # use clap::{App, arg};
330     /// use std::ffi::OsString;
331     /// use std::os::unix::ffi::OsStringExt;
332     ///
333     /// let m = App::new("utf8")
334     ///     .arg(arg!(<arg> ... "some arg")
335     ///         .allow_invalid_utf8(true))
336     ///     .get_matches_from(vec![OsString::from("myprog"),
337     ///                             // "Hi"
338     ///                             OsString::from_vec(vec![b'H', b'i']),
339     ///                             // "{0xe9}!"
340     ///                             OsString::from_vec(vec![0xe9, b'!'])]);
341     /// let mut itr = m.values_of_lossy("arg").unwrap().into_iter();
342     /// assert_eq!(&itr.next().unwrap()[..], "Hi");
343     /// assert_eq!(&itr.next().unwrap()[..], "\u{FFFD}!");
344     /// assert_eq!(itr.next(), None);
345     /// ```
346     #[cfg_attr(debug_assertions, track_caller)]
values_of_lossy<T: Key>(&self, id: T) -> Option<Vec<String>>347     pub fn values_of_lossy<T: Key>(&self, id: T) -> Option<Vec<String>> {
348         let id = Id::from(id);
349         let arg = self.get_arg(&id)?;
350         assert_no_utf8_validation(arg, &id);
351         let v = arg
352             .vals_flatten()
353             .map(|v| v.to_string_lossy().into_owned())
354             .collect();
355         Some(v)
356     }
357 
358     /// Get an [`Iterator`] over [`OsStr`] [values] of a specific option or positional argument.
359     ///
360     /// i.e. an argument that takes multiple values at runtime.
361     ///
362     /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
363     /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
364     /// filename on a Unix system as an argument value may contain invalid UTF-8.
365     ///
366     /// Returns `None` if the option wasn't present.
367     ///
368     /// *NOTE:* Recommend having set [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
369     ///
370     /// # Panics
371     ///
372     /// If `id` is is not a valid argument or group name.
373     ///
374     /// # Examples
375     ///
376     #[cfg_attr(not(unix), doc = " ```ignore")]
377     #[cfg_attr(unix, doc = " ```")]
378     /// # use clap::{App, arg};
379     /// use std::ffi::{OsStr,OsString};
380     /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
381     ///
382     /// let m = App::new("utf8")
383     ///     .arg(arg!(<arg> ... "some arg")
384     ///         .allow_invalid_utf8(true))
385     ///     .get_matches_from(vec![OsString::from("myprog"),
386     ///                                 // "Hi"
387     ///                                 OsString::from_vec(vec![b'H', b'i']),
388     ///                                 // "{0xe9}!"
389     ///                                 OsString::from_vec(vec![0xe9, b'!'])]);
390     ///
391     /// let mut itr = m.values_of_os("arg").unwrap().into_iter();
392     /// assert_eq!(itr.next(), Some(OsStr::new("Hi")));
393     /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!'])));
394     /// assert_eq!(itr.next(), None);
395     /// ```
396     /// [`Iterator`]: std::iter::Iterator
397     /// [`OsSt`]: std::ffi::OsStr
398     /// [values]: OsValues
399     /// [`String`]: std::string::String
400     #[cfg_attr(debug_assertions, track_caller)]
values_of_os<T: Key>(&self, id: T) -> Option<OsValues>401     pub fn values_of_os<T: Key>(&self, id: T) -> Option<OsValues> {
402         let id = Id::from(id);
403         let arg = self.get_arg(&id)?;
404         assert_no_utf8_validation(arg, &id);
405         fn to_str_slice(o: &OsString) -> &OsStr {
406             o
407         }
408         let v = OsValues {
409             iter: arg.vals_flatten().map(to_str_slice),
410             len: arg.num_vals(),
411         };
412         Some(v)
413     }
414 
415     /// Parse the value (with [`FromStr`]) of a specific option or positional argument.
416     ///
417     /// There are two types of errors, parse failures and those where the argument wasn't present
418     /// (such as a non-required argument). Check [`ErrorKind`] to distinguish them.
419     ///
420     /// *NOTE:* If getting a value for an option or positional argument that allows multiples,
421     /// prefer [`ArgMatches::values_of_t`] as this method will only return the *first*
422     /// value.
423     ///
424     /// # Panics
425     ///
426     /// If the value is invalid UTF-8.  See
427     /// [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
428     ///
429     /// If `id` is is not a valid argument or group name.
430     ///
431     /// # Examples
432     ///
433     /// ```
434     /// # use clap::{App, arg};
435     /// let matches = App::new("myapp")
436     ///               .arg(arg!([length] "Set the length to use as a pos whole num i.e. 20"))
437     ///               .get_matches_from(&["test", "12"]);
438     ///
439     /// // Specify the type explicitly (or use turbofish)
440     /// let len: u32 = matches.value_of_t("length").unwrap_or_else(|e| e.exit());
441     /// assert_eq!(len, 12);
442     ///
443     /// // You can often leave the type for rustc to figure out
444     /// let also_len = matches.value_of_t("length").unwrap_or_else(|e| e.exit());
445     /// // Something that expects u32
446     /// let _: u32 = also_len;
447     /// ```
448     ///
449     /// [`FromStr]: std::str::FromStr
450     /// [`ArgMatches::values_of_t`]: ArgMatches::values_of_t()
451     /// [`ErrorKind`]: crate::ErrorKind
value_of_t<R>(&self, name: &str) -> Result<R, Error> where R: FromStr, <R as FromStr>::Err: Display,452     pub fn value_of_t<R>(&self, name: &str) -> Result<R, Error>
453     where
454         R: FromStr,
455         <R as FromStr>::Err: Display,
456     {
457         let v = self
458             .value_of(name)
459             .ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?;
460         v.parse::<R>().map_err(|e| {
461             let message = format!(
462                 "The argument '{}' isn't a valid value for '{}': {}",
463                 v, name, e
464             );
465 
466             Error::value_validation_without_app(name.to_string(), v.to_string(), message.into())
467         })
468     }
469 
470     /// Parse the value (with [`FromStr`]) of a specific option or positional argument.
471     ///
472     /// If either the value is not present or parsing failed, exits the program.
473     ///
474     /// # Panics
475     ///
476     /// If the value is invalid UTF-8.  See
477     /// [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
478     ///
479     /// If `id` is is not a valid argument or group name.
480     ///
481     /// # Examples
482     ///
483     /// ```
484     /// # use clap::{App, arg};
485     /// let matches = App::new("myapp")
486     ///               .arg(arg!([length] "Set the length to use as a pos whole num i.e. 20"))
487     ///               .get_matches_from(&["test", "12"]);
488     ///
489     /// // Specify the type explicitly (or use turbofish)
490     /// let len: u32 = matches.value_of_t_or_exit("length");
491     /// assert_eq!(len, 12);
492     ///
493     /// // You can often leave the type for rustc to figure out
494     /// let also_len = matches.value_of_t_or_exit("length");
495     /// // Something that expects u32
496     /// let _: u32 = also_len;
497     /// ```
498     ///
499     /// [`FromStr][std::str::FromStr]
value_of_t_or_exit<R>(&self, name: &str) -> R where R: FromStr, <R as FromStr>::Err: Display,500     pub fn value_of_t_or_exit<R>(&self, name: &str) -> R
501     where
502         R: FromStr,
503         <R as FromStr>::Err: Display,
504     {
505         self.value_of_t(name).unwrap_or_else(|e| e.exit())
506     }
507 
508     /// Parse the values (with [`FromStr`]) of a specific option or positional argument.
509     ///
510     /// There are two types of errors, parse failures and those where the argument wasn't present
511     /// (such as a non-required argument). Check [`ErrorKind`] to distinguish them.
512     ///
513     /// *NOTE:* If getting a value for an option or positional argument that allows multiples,
514     /// prefer [`ArgMatches::values_of_t`] as this method will only return the *first*
515     /// value.
516     ///
517     /// # Panics
518     ///
519     /// If the value is invalid UTF-8.  See
520     /// [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
521     ///
522     /// If `id` is is not a valid argument or group name.
523     ///
524     /// # Examples
525     ///
526     /// ```
527     /// # use clap::{App, arg};
528     /// let matches = App::new("myapp")
529     ///               .arg(arg!([length] ... "A sequence of integers because integers are neat!"))
530     ///               .get_matches_from(&["test", "12", "77", "40"]);
531     ///
532     /// // Specify the type explicitly (or use turbofish)
533     /// let len: Vec<u32> = matches.values_of_t("length").unwrap_or_else(|e| e.exit());
534     /// assert_eq!(len, vec![12, 77, 40]);
535     ///
536     /// // You can often leave the type for rustc to figure out
537     /// let also_len = matches.values_of_t("length").unwrap_or_else(|e| e.exit());
538     /// // Something that expects Vec<u32>
539     /// let _: Vec<u32> = also_len;
540     /// ```
541     /// [`ErrorKind`]: crate::ErrorKind
values_of_t<R>(&self, name: &str) -> Result<Vec<R>, Error> where R: FromStr, <R as FromStr>::Err: Display,542     pub fn values_of_t<R>(&self, name: &str) -> Result<Vec<R>, Error>
543     where
544         R: FromStr,
545         <R as FromStr>::Err: Display,
546     {
547         let v = self
548             .values_of(name)
549             .ok_or_else(|| Error::argument_not_found_auto(name.to_string()))?;
550         v.map(|v| {
551             v.parse::<R>().map_err(|e| {
552                 let message = format!("The argument '{}' isn't a valid value: {}", v, e);
553 
554                 Error::value_validation_without_app(name.to_string(), v.to_string(), message.into())
555             })
556         })
557         .collect()
558     }
559 
560     /// Parse the values (with [`FromStr`]) of a specific option or positional argument.
561     ///
562     /// If parsing (of any value) has failed, exits the program.
563     ///
564     /// # Panics
565     ///
566     /// If the value is invalid UTF-8.  See
567     /// [`Arg::allow_invalid_utf8`][crate::Arg::allow_invalid_utf8].
568     ///
569     /// If `id` is is not a valid argument or group name.
570     ///
571     /// # Examples
572     ///
573     /// ```
574     /// # use clap::{App, arg};
575     /// let matches = App::new("myapp")
576     ///               .arg(arg!([length] ... "A sequence of integers because integers are neat!"))
577     ///               .get_matches_from(&["test", "12", "77", "40"]);
578     ///
579     /// // Specify the type explicitly (or use turbofish)
580     /// let len: Vec<u32> = matches.values_of_t_or_exit("length");
581     /// assert_eq!(len, vec![12, 77, 40]);
582     ///
583     /// // You can often leave the type for rustc to figure out
584     /// let also_len = matches.values_of_t_or_exit("length");
585     /// // Something that expects Vec<u32>
586     /// let _: Vec<u32> = also_len;
587     /// ```
values_of_t_or_exit<R>(&self, name: &str) -> Vec<R> where R: FromStr, <R as FromStr>::Err: Display,588     pub fn values_of_t_or_exit<R>(&self, name: &str) -> Vec<R>
589     where
590         R: FromStr,
591         <R as FromStr>::Err: Display,
592     {
593         self.values_of_t(name).unwrap_or_else(|e| e.exit())
594     }
595 
596     /// Check if an argument was present at runtime.
597     ///
598     /// *NOTE:* This will always return `true` if [`default_value`] has been set.
599     /// [`occurrences_of`] can be used to check if a value is present at runtime.
600     ///
601     /// # Panics
602     ///
603     /// If `id` is is not a valid argument or group name.
604     ///
605     /// # Examples
606     ///
607     /// ```rust
608     /// # use clap::{App, Arg};
609     /// let m = App::new("myprog")
610     ///     .arg(Arg::new("debug")
611     ///         .short('d'))
612     ///     .get_matches_from(vec![
613     ///         "myprog", "-d"
614     ///     ]);
615     ///
616     /// assert!(m.is_present("debug"));
617     /// ```
618     ///
619     /// [`default_value`]: crate::Arg::default_value()
620     /// [`occurrences_of`]: ArgMatches::occurrences_of()
is_present<T: Key>(&self, id: T) -> bool621     pub fn is_present<T: Key>(&self, id: T) -> bool {
622         let id = Id::from(id);
623 
624         #[cfg(debug_assertions)]
625         self.get_arg(&id);
626 
627         self.args.contains_key(&id)
628     }
629 
630     /// The number of times an argument was used at runtime.
631     ///
632     /// If an argument isn't present it will return `0`.
633     ///
634     /// **NOTE:** This returns the number of times the argument was used, *not* the number of
635     /// values. For example, `-o val1 val2 val3 -o val4` would return `2` (2 occurrences, but 4
636     /// values).  See [Arg::multiple_occurrences][crate::Arg::multiple_occurrences].
637     ///
638     /// # Panics
639     ///
640     /// If `id` is is not a valid argument or group name.
641     ///
642     /// # Examples
643     ///
644     /// ```rust
645     /// # use clap::{App, Arg};
646     /// let m = App::new("myprog")
647     ///     .arg(Arg::new("debug")
648     ///         .short('d')
649     ///         .multiple_occurrences(true))
650     ///     .get_matches_from(vec![
651     ///         "myprog", "-d", "-d", "-d"
652     ///     ]);
653     ///
654     /// assert_eq!(m.occurrences_of("debug"), 3);
655     /// ```
656     ///
657     /// This next example shows that counts actual uses of the argument, not just `-`'s
658     ///
659     /// ```rust
660     /// # use clap::{App, Arg};
661     /// let m = App::new("myprog")
662     ///     .arg(Arg::new("debug")
663     ///         .short('d')
664     ///         .multiple_occurrences(true))
665     ///     .arg(Arg::new("flag")
666     ///         .short('f'))
667     ///     .get_matches_from(vec![
668     ///         "myprog", "-ddfd"
669     ///     ]);
670     ///
671     /// assert_eq!(m.occurrences_of("debug"), 3);
672     /// assert_eq!(m.occurrences_of("flag"), 1);
673     /// ```
occurrences_of<T: Key>(&self, id: T) -> u64674     pub fn occurrences_of<T: Key>(&self, id: T) -> u64 {
675         self.get_arg(&Id::from(id))
676             .map_or(0, |a| a.get_occurrences())
677     }
678 
679     /// The first index of that an argument showed up.
680     ///
681     /// Indices are similar to argv indices, but are not exactly 1:1.
682     ///
683     /// For flags (i.e. those arguments which don't have an associated value), indices refer
684     /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
685     /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
686     /// index for `val` would be recorded. This is by design.
687     ///
688     /// Besides the flag/option discrepancy, the primary difference between an argv index and clap
689     /// index, is that clap continues counting once all arguments have properly separated, whereas
690     /// an argv index does not.
691     ///
692     /// The examples should clear this up.
693     ///
694     /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first*
695     /// index.  See [`ArgMatches::indices_of`].
696     ///
697     /// # Panics
698     ///
699     /// If `id` is is not a valid argument or group name.
700     ///
701     /// # Examples
702     ///
703     /// The argv indices are listed in the comments below. See how they correspond to the clap
704     /// indices. Note that if it's not listed in a clap index, this is because it's not saved in
705     /// in an `ArgMatches` struct for querying.
706     ///
707     /// ```rust
708     /// # use clap::{App, Arg};
709     /// let m = App::new("myapp")
710     ///     .arg(Arg::new("flag")
711     ///         .short('f'))
712     ///     .arg(Arg::new("option")
713     ///         .short('o')
714     ///         .takes_value(true))
715     ///     .get_matches_from(vec!["myapp", "-f", "-o", "val"]);
716     ///            // ARGV indices: ^0       ^1    ^2    ^3
717     ///            // clap indices:          ^1          ^3
718     ///
719     /// assert_eq!(m.index_of("flag"), Some(1));
720     /// assert_eq!(m.index_of("option"), Some(3));
721     /// ```
722     ///
723     /// Now notice, if we use one of the other styles of options:
724     ///
725     /// ```rust
726     /// # use clap::{App, Arg};
727     /// let m = App::new("myapp")
728     ///     .arg(Arg::new("flag")
729     ///         .short('f'))
730     ///     .arg(Arg::new("option")
731     ///         .short('o')
732     ///         .takes_value(true))
733     ///     .get_matches_from(vec!["myapp", "-f", "-o=val"]);
734     ///            // ARGV indices: ^0       ^1    ^2
735     ///            // clap indices:          ^1       ^3
736     ///
737     /// assert_eq!(m.index_of("flag"), Some(1));
738     /// assert_eq!(m.index_of("option"), Some(3));
739     /// ```
740     ///
741     /// Things become much more complicated, or clear if we look at a more complex combination of
742     /// flags. Let's also throw in the final option style for good measure.
743     ///
744     /// ```rust
745     /// # use clap::{App, Arg};
746     /// let m = App::new("myapp")
747     ///     .arg(Arg::new("flag")
748     ///         .short('f'))
749     ///     .arg(Arg::new("flag2")
750     ///         .short('F'))
751     ///     .arg(Arg::new("flag3")
752     ///         .short('z'))
753     ///     .arg(Arg::new("option")
754     ///         .short('o')
755     ///         .takes_value(true))
756     ///     .get_matches_from(vec!["myapp", "-fzF", "-oval"]);
757     ///            // ARGV indices: ^0      ^1       ^2
758     ///            // clap indices:         ^1,2,3    ^5
759     ///            //
760     ///            // clap sees the above as 'myapp -f -z -F -o val'
761     ///            //                         ^0    ^1 ^2 ^3 ^4 ^5
762     /// assert_eq!(m.index_of("flag"), Some(1));
763     /// assert_eq!(m.index_of("flag2"), Some(3));
764     /// assert_eq!(m.index_of("flag3"), Some(2));
765     /// assert_eq!(m.index_of("option"), Some(5));
766     /// ```
767     ///
768     /// One final combination of flags/options to see how they combine:
769     ///
770     /// ```rust
771     /// # use clap::{App, Arg};
772     /// let m = App::new("myapp")
773     ///     .arg(Arg::new("flag")
774     ///         .short('f'))
775     ///     .arg(Arg::new("flag2")
776     ///         .short('F'))
777     ///     .arg(Arg::new("flag3")
778     ///         .short('z'))
779     ///     .arg(Arg::new("option")
780     ///         .short('o')
781     ///         .takes_value(true))
782     ///     .get_matches_from(vec!["myapp", "-fzFoval"]);
783     ///            // ARGV indices: ^0       ^1
784     ///            // clap indices:          ^1,2,3^5
785     ///            //
786     ///            // clap sees the above as 'myapp -f -z -F -o val'
787     ///            //                         ^0    ^1 ^2 ^3 ^4 ^5
788     /// assert_eq!(m.index_of("flag"), Some(1));
789     /// assert_eq!(m.index_of("flag2"), Some(3));
790     /// assert_eq!(m.index_of("flag3"), Some(2));
791     /// assert_eq!(m.index_of("option"), Some(5));
792     /// ```
793     ///
794     /// The last part to mention is when values are sent in multiple groups with a [delimiter].
795     ///
796     /// ```rust
797     /// # use clap::{App, Arg};
798     /// let m = App::new("myapp")
799     ///     .arg(Arg::new("option")
800     ///         .short('o')
801     ///         .use_delimiter(true)
802     ///         .multiple_values(true))
803     ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
804     ///            // ARGV indices: ^0       ^1
805     ///            // clap indices:             ^2   ^3   ^4
806     ///            //
807     ///            // clap sees the above as 'myapp -o val1 val2 val3'
808     ///            //                         ^0    ^1 ^2   ^3   ^4
809     /// assert_eq!(m.index_of("option"), Some(2));
810     /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
811     /// ```
812     /// [delimiter]: crate::Arg::value_delimiter()
index_of<T: Key>(&self, id: T) -> Option<usize>813     pub fn index_of<T: Key>(&self, id: T) -> Option<usize> {
814         let arg = self.get_arg(&Id::from(id))?;
815         let i = arg.get_index(0)?;
816         Some(i)
817     }
818 
819     /// All indices an argument appeared at when parsing.
820     ///
821     /// Indices are similar to argv indices, but are not exactly 1:1.
822     ///
823     /// For flags (i.e. those arguments which don't have an associated value), indices refer
824     /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
825     /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
826     /// index for `val` would be recorded. This is by design.
827     ///
828     /// *NOTE:* For more information about how clap indices compared to argv indices, see
829     /// [`ArgMatches::index_of`]
830     ///
831     /// # Panics
832     ///
833     /// If `id` is is not a valid argument or group name.
834     ///
835     /// # Examples
836     ///
837     /// ```rust
838     /// # use clap::{App, Arg};
839     /// let m = App::new("myapp")
840     ///     .arg(Arg::new("option")
841     ///         .short('o')
842     ///         .use_delimiter(true)
843     ///         .multiple_values(true))
844     ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
845     ///            // ARGV indices: ^0       ^1
846     ///            // clap indices:             ^2   ^3   ^4
847     ///            //
848     ///            // clap sees the above as 'myapp -o val1 val2 val3'
849     ///            //                         ^0    ^1 ^2   ^3   ^4
850     /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
851     /// ```
852     ///
853     /// Another quick example is when flags and options are used together
854     ///
855     /// ```rust
856     /// # use clap::{App, Arg};
857     /// let m = App::new("myapp")
858     ///     .arg(Arg::new("option")
859     ///         .short('o')
860     ///         .takes_value(true)
861     ///         .multiple_occurrences(true))
862     ///     .arg(Arg::new("flag")
863     ///         .short('f')
864     ///         .multiple_occurrences(true))
865     ///     .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]);
866     ///            // ARGV indices: ^0       ^1    ^2      ^3    ^4    ^5      ^6
867     ///            // clap indices:                ^2      ^3          ^5      ^6
868     ///
869     /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
870     /// assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[3, 6]);
871     /// ```
872     ///
873     /// One final example, which is an odd case; if we *don't* use  value delimiter as we did with
874     /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they
875     /// would all be a single value of `val1,val2,val3`, in which case they'd only receive a single
876     /// index.
877     ///
878     /// ```rust
879     /// # use clap::{App, Arg};
880     /// let m = App::new("myapp")
881     ///     .arg(Arg::new("option")
882     ///         .short('o')
883     ///         .takes_value(true)
884     ///         .multiple_values(true))
885     ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
886     ///            // ARGV indices: ^0       ^1
887     ///            // clap indices:             ^2
888     ///            //
889     ///            // clap sees the above as 'myapp -o "val1,val2,val3"'
890     ///            //                         ^0    ^1  ^2
891     /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);
892     /// ```
893     /// [`ArgMatches::index_of`]: ArgMatches::index_of()
894     /// [delimiter]: Arg::value_delimiter()
indices_of<T: Key>(&self, id: T) -> Option<Indices<'_>>895     pub fn indices_of<T: Key>(&self, id: T) -> Option<Indices<'_>> {
896         let arg = self.get_arg(&Id::from(id))?;
897         let i = Indices {
898             iter: arg.indices(),
899             len: arg.num_vals(),
900         };
901         Some(i)
902     }
903 
904     /// The name and `ArgMatches` of the current [subcommand].
905     ///
906     /// Subcommand values are put in a child [`ArgMatches`]
907     ///
908     /// Returns `None` if the subcommand wasn't present at runtime,
909     ///
910     /// # Examples
911     ///
912     /// ```no_run
913     /// # use clap::{App, Arg, };
914     ///  let app_m = App::new("git")
915     ///      .subcommand(App::new("clone"))
916     ///      .subcommand(App::new("push"))
917     ///      .subcommand(App::new("commit"))
918     ///      .get_matches();
919     ///
920     /// match app_m.subcommand() {
921     ///     Some(("clone",  sub_m)) => {}, // clone was used
922     ///     Some(("push",   sub_m)) => {}, // push was used
923     ///     Some(("commit", sub_m)) => {}, // commit was used
924     ///     _                       => {}, // Either no subcommand or one not tested for...
925     /// }
926     /// ```
927     ///
928     /// Another useful scenario is when you want to support third party, or external, subcommands.
929     /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
930     /// with pattern matching!
931     ///
932     /// ```rust
933     /// # use clap::{App, AppSettings};
934     /// // Assume there is an external subcommand named "subcmd"
935     /// let app_m = App::new("myprog")
936     ///     .setting(AppSettings::AllowExternalSubcommands)
937     ///     .get_matches_from(vec![
938     ///         "myprog", "subcmd", "--option", "value", "-fff", "--flag"
939     ///     ]);
940     ///
941     /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
942     /// // string argument name
943     /// match app_m.subcommand() {
944     ///     Some((external, sub_m)) => {
945     ///          let ext_args: Vec<&str> = sub_m.values_of("").unwrap().collect();
946     ///          assert_eq!(external, "subcmd");
947     ///          assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
948     ///     },
949     ///     _ => {},
950     /// }
951     /// ```
952     /// [subcommand]: crate::App::subcommand
953     #[inline]
subcommand(&self) -> Option<(&str, &ArgMatches)>954     pub fn subcommand(&self) -> Option<(&str, &ArgMatches)> {
955         self.subcommand.as_ref().map(|sc| (&*sc.name, &sc.matches))
956     }
957 
958     /// The `ArgMatches` for the current [subcommand].
959     ///
960     /// Subcommand values are put in a child [`ArgMatches`]
961     ///
962     /// Returns `None` if the subcommand wasn't present at runtime,
963     ///
964     /// # Panics
965     ///
966     /// If `id` is is not a valid subcommand.
967     ///
968     /// # Examples
969     ///
970     /// ```rust
971     /// # use clap::{App, Arg, };
972     /// let app_m = App::new("myprog")
973     ///     .arg(Arg::new("debug")
974     ///         .short('d'))
975     ///     .subcommand(App::new("test")
976     ///         .arg(Arg::new("opt")
977     ///             .long("option")
978     ///             .takes_value(true)))
979     ///     .get_matches_from(vec![
980     ///         "myprog", "-d", "test", "--option", "val"
981     ///     ]);
982     ///
983     /// // Both parent commands, and child subcommands can have arguments present at the same times
984     /// assert!(app_m.is_present("debug"));
985     ///
986     /// // Get the subcommand's ArgMatches instance
987     /// if let Some(sub_m) = app_m.subcommand_matches("test") {
988     ///     // Use the struct like normal
989     ///     assert_eq!(sub_m.value_of("opt"), Some("val"));
990     /// }
991     /// ```
992     ///
993     /// [subcommand]: crate::App::subcommand
994     /// [`App`]: crate::App
subcommand_matches<T: Key>(&self, id: T) -> Option<&ArgMatches>995     pub fn subcommand_matches<T: Key>(&self, id: T) -> Option<&ArgMatches> {
996         self.get_subcommand(&id.into()).map(|sc| &sc.matches)
997     }
998 
999     /// The name of the current [subcommand].
1000     ///
1001     /// Returns `None` if the subcommand wasn't present at runtime,
1002     ///
1003     /// # Examples
1004     ///
1005     /// ```no_run
1006     /// # use clap::{App, Arg, };
1007     ///  let app_m = App::new("git")
1008     ///      .subcommand(App::new("clone"))
1009     ///      .subcommand(App::new("push"))
1010     ///      .subcommand(App::new("commit"))
1011     ///      .get_matches();
1012     ///
1013     /// match app_m.subcommand_name() {
1014     ///     Some("clone")  => {}, // clone was used
1015     ///     Some("push")   => {}, // push was used
1016     ///     Some("commit") => {}, // commit was used
1017     ///     _              => {}, // Either no subcommand or one not tested for...
1018     /// }
1019     /// ```
1020     /// [subcommand]: crate::App::subcommand
1021     /// [`App`]: crate::App
1022     #[inline]
subcommand_name(&self) -> Option<&str>1023     pub fn subcommand_name(&self) -> Option<&str> {
1024         self.subcommand.as_ref().map(|sc| &*sc.name)
1025     }
1026 
1027     /// Check if an arg can be queried
1028     ///
1029     /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer
1030     /// mistakes.  In some context, this doesn't work, so users can use this function to check
1031     /// before they do a query on `ArgMatches`.
1032     #[inline]
1033     #[doc(hidden)]
is_valid_arg(&self, _id: impl Key) -> bool1034     pub fn is_valid_arg(&self, _id: impl Key) -> bool {
1035         #[cfg(debug_assertions)]
1036         {
1037             let id = Id::from(_id);
1038             self.disable_asserts || id == Id::empty_hash() || self.valid_args.contains(&id)
1039         }
1040         #[cfg(not(debug_assertions))]
1041         {
1042             true
1043         }
1044     }
1045 
1046     /// Check if a subcommand can be queried
1047     ///
1048     /// By default, `ArgMatches` functions assert on undefined `Id`s to help catch programmer
1049     /// mistakes.  In some context, this doesn't work, so users can use this function to check
1050     /// before they do a query on `ArgMatches`.
1051     #[inline]
1052     #[doc(hidden)]
is_valid_subcommand(&self, _id: impl Key) -> bool1053     pub fn is_valid_subcommand(&self, _id: impl Key) -> bool {
1054         #[cfg(debug_assertions)]
1055         {
1056             let id = Id::from(_id);
1057             self.disable_asserts || id == Id::empty_hash() || self.valid_subcommands.contains(&id)
1058         }
1059         #[cfg(not(debug_assertions))]
1060         {
1061             true
1062         }
1063     }
1064 }
1065 
1066 // Private methods
1067 impl ArgMatches {
1068     #[inline]
1069     #[cfg_attr(debug_assertions, track_caller)]
get_arg(&self, arg: &Id) -> Option<&MatchedArg>1070     fn get_arg(&self, arg: &Id) -> Option<&MatchedArg> {
1071         #[cfg(debug_assertions)]
1072         {
1073             if self.disable_asserts || *arg == Id::empty_hash() || self.valid_args.contains(arg) {
1074             } else if self.valid_subcommands.contains(arg) {
1075                 panic!(
1076                     "Subcommand `{:?}` used where an argument or group name was expected.",
1077                     arg
1078                 );
1079             } else {
1080                 panic!(
1081                     "`{:?}` is not a name of an argument or a group.\n\
1082                      Make sure you're using the name of the argument itself \
1083                      and not the name of short or long flags.",
1084                     arg
1085                 );
1086             }
1087         }
1088 
1089         self.args.get(arg)
1090     }
1091 
1092     #[inline]
1093     #[cfg_attr(debug_assertions, track_caller)]
get_subcommand(&self, id: &Id) -> Option<&SubCommand>1094     fn get_subcommand(&self, id: &Id) -> Option<&SubCommand> {
1095         #[cfg(debug_assertions)]
1096         {
1097             if self.disable_asserts
1098                 || *id == Id::empty_hash()
1099                 || self.valid_subcommands.contains(id)
1100             {
1101             } else if self.valid_args.contains(id) {
1102                 panic!(
1103                     "Argument or group `{:?}` used where a subcommand name was expected.",
1104                     id
1105                 );
1106             } else {
1107                 panic!("`{:?}` is not a name of a subcommand.", id);
1108             }
1109         }
1110 
1111         if let Some(ref sc) = self.subcommand {
1112             if sc.id == *id {
1113                 return Some(sc);
1114             }
1115         }
1116 
1117         None
1118     }
1119 }
1120 
1121 #[derive(Debug, Clone, PartialEq, Eq)]
1122 pub(crate) struct SubCommand {
1123     pub(crate) id: Id,
1124     pub(crate) name: String,
1125     pub(crate) matches: ArgMatches,
1126 }
1127 
1128 // The following were taken and adapted from vec_map source
1129 // repo: https://github.com/contain-rs/vec-map
1130 // commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
1131 // license: MIT - Copyright (c) 2015 The Rust Project Developers
1132 
1133 /// Iterate over multiple values for an argument via [`ArgMatches::values_of`].
1134 ///
1135 /// # Examples
1136 ///
1137 /// ```rust
1138 /// # use clap::{App, Arg};
1139 /// let m = App::new("myapp")
1140 ///     .arg(Arg::new("output")
1141 ///         .short('o')
1142 ///         .multiple_occurrences(true)
1143 ///         .takes_value(true))
1144 ///     .get_matches_from(vec!["myapp", "-o", "val1", "-o", "val2"]);
1145 ///
1146 /// let mut values = m.values_of("output").unwrap();
1147 ///
1148 /// assert_eq!(values.next(), Some("val1"));
1149 /// assert_eq!(values.next(), Some("val2"));
1150 /// assert_eq!(values.next(), None);
1151 /// ```
1152 /// [`ArgMatches::values_of`]: ArgMatches::values_of()
1153 #[derive(Clone)]
1154 #[allow(missing_debug_implementations)]
1155 pub struct Values<'a> {
1156     #[allow(clippy::type_complexity)]
1157     iter: Map<Flatten<Iter<'a, Vec<OsString>>>, for<'r> fn(&'r OsString) -> &'r str>,
1158     len: usize,
1159 }
1160 
1161 impl<'a> Iterator for Values<'a> {
1162     type Item = &'a str;
1163 
next(&mut self) -> Option<&'a str>1164     fn next(&mut self) -> Option<&'a str> {
1165         self.iter.next()
1166     }
size_hint(&self) -> (usize, Option<usize>)1167     fn size_hint(&self) -> (usize, Option<usize>) {
1168         (self.len, Some(self.len))
1169     }
1170 }
1171 
1172 impl<'a> DoubleEndedIterator for Values<'a> {
next_back(&mut self) -> Option<&'a str>1173     fn next_back(&mut self) -> Option<&'a str> {
1174         self.iter.next_back()
1175     }
1176 }
1177 
1178 impl<'a> ExactSizeIterator for Values<'a> {}
1179 
1180 /// Creates an empty iterator.
1181 impl<'a> Default for Values<'a> {
default() -> Self1182     fn default() -> Self {
1183         static EMPTY: [Vec<OsString>; 0] = [];
1184         Values {
1185             iter: EMPTY[..].iter().flatten().map(|_| unreachable!()),
1186             len: 0,
1187         }
1188     }
1189 }
1190 
1191 #[derive(Clone)]
1192 #[allow(missing_debug_implementations)]
1193 pub struct GroupedValues<'a> {
1194     #[allow(clippy::type_complexity)]
1195     iter: Map<Iter<'a, Vec<OsString>>, fn(&Vec<OsString>) -> Vec<&str>>,
1196     len: usize,
1197 }
1198 
1199 impl<'a> Iterator for GroupedValues<'a> {
1200     type Item = Vec<&'a str>;
1201 
next(&mut self) -> Option<Self::Item>1202     fn next(&mut self) -> Option<Self::Item> {
1203         self.iter.next()
1204     }
size_hint(&self) -> (usize, Option<usize>)1205     fn size_hint(&self) -> (usize, Option<usize>) {
1206         (self.len, Some(self.len))
1207     }
1208 }
1209 
1210 impl<'a> DoubleEndedIterator for GroupedValues<'a> {
next_back(&mut self) -> Option<Self::Item>1211     fn next_back(&mut self) -> Option<Self::Item> {
1212         self.iter.next_back()
1213     }
1214 }
1215 
1216 impl<'a> ExactSizeIterator for GroupedValues<'a> {}
1217 
1218 /// Creates an empty iterator. Used for `unwrap_or_default()`.
1219 impl<'a> Default for GroupedValues<'a> {
default() -> Self1220     fn default() -> Self {
1221         static EMPTY: [Vec<OsString>; 0] = [];
1222         GroupedValues {
1223             iter: EMPTY[..].iter().map(|_| unreachable!()),
1224             len: 0,
1225         }
1226     }
1227 }
1228 
1229 /// Iterate over multiple values for an argument via [`ArgMatches::values_of_os`].
1230 ///
1231 /// # Examples
1232 ///
1233 #[cfg_attr(not(unix), doc = " ```ignore")]
1234 #[cfg_attr(unix, doc = " ```")]
1235 /// # use clap::{App, arg};
1236 /// use std::ffi::OsString;
1237 /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
1238 ///
1239 /// let m = App::new("utf8")
1240 ///     .arg(arg!(<arg> "some arg")
1241 ///         .allow_invalid_utf8(true))
1242 ///     .get_matches_from(vec![OsString::from("myprog"),
1243 ///                             // "Hi {0xe9}!"
1244 ///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
1245 /// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']);
1246 /// ```
1247 /// [`ArgMatches::values_of_os`]: ArgMatches::values_of_os()
1248 #[derive(Clone)]
1249 #[allow(missing_debug_implementations)]
1250 pub struct OsValues<'a> {
1251     #[allow(clippy::type_complexity)]
1252     iter: Map<Flatten<Iter<'a, Vec<OsString>>>, fn(&OsString) -> &OsStr>,
1253     len: usize,
1254 }
1255 
1256 impl<'a> Iterator for OsValues<'a> {
1257     type Item = &'a OsStr;
1258 
next(&mut self) -> Option<&'a OsStr>1259     fn next(&mut self) -> Option<&'a OsStr> {
1260         self.iter.next()
1261     }
size_hint(&self) -> (usize, Option<usize>)1262     fn size_hint(&self) -> (usize, Option<usize>) {
1263         (self.len, Some(self.len))
1264     }
1265 }
1266 
1267 impl<'a> DoubleEndedIterator for OsValues<'a> {
next_back(&mut self) -> Option<&'a OsStr>1268     fn next_back(&mut self) -> Option<&'a OsStr> {
1269         self.iter.next_back()
1270     }
1271 }
1272 
1273 impl<'a> ExactSizeIterator for OsValues<'a> {}
1274 
1275 /// Creates an empty iterator.
1276 impl Default for OsValues<'_> {
default() -> Self1277     fn default() -> Self {
1278         static EMPTY: [Vec<OsString>; 0] = [];
1279         OsValues {
1280             iter: EMPTY[..].iter().flatten().map(|_| unreachable!()),
1281             len: 0,
1282         }
1283     }
1284 }
1285 
1286 /// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
1287 ///
1288 /// # Examples
1289 ///
1290 /// ```rust
1291 /// # use clap::{App, Arg};
1292 /// let m = App::new("myapp")
1293 ///     .arg(Arg::new("output")
1294 ///         .short('o')
1295 ///         .multiple_values(true)
1296 ///         .takes_value(true))
1297 ///     .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
1298 ///
1299 /// let mut indices = m.indices_of("output").unwrap();
1300 ///
1301 /// assert_eq!(indices.next(), Some(2));
1302 /// assert_eq!(indices.next(), Some(3));
1303 /// assert_eq!(indices.next(), None);
1304 /// ```
1305 /// [`ArgMatches::indices_of`]: ArgMatches::indices_of()
1306 #[derive(Clone)]
1307 #[allow(missing_debug_implementations)]
1308 pub struct Indices<'a> {
1309     iter: Cloned<Iter<'a, usize>>,
1310     len: usize,
1311 }
1312 
1313 impl<'a> Iterator for Indices<'a> {
1314     type Item = usize;
1315 
next(&mut self) -> Option<usize>1316     fn next(&mut self) -> Option<usize> {
1317         self.iter.next()
1318     }
size_hint(&self) -> (usize, Option<usize>)1319     fn size_hint(&self) -> (usize, Option<usize>) {
1320         (self.len, Some(self.len))
1321     }
1322 }
1323 
1324 impl<'a> DoubleEndedIterator for Indices<'a> {
next_back(&mut self) -> Option<usize>1325     fn next_back(&mut self) -> Option<usize> {
1326         self.iter.next_back()
1327     }
1328 }
1329 
1330 impl<'a> ExactSizeIterator for Indices<'a> {}
1331 
1332 /// Creates an empty iterator.
1333 impl<'a> Default for Indices<'a> {
default() -> Self1334     fn default() -> Self {
1335         static EMPTY: [usize; 0] = [];
1336         // This is never called because the iterator is empty:
1337         Indices {
1338             iter: EMPTY[..].iter().cloned(),
1339             len: 0,
1340         }
1341     }
1342 }
1343 
1344 #[cfg_attr(debug_assertions, track_caller)]
1345 #[inline]
assert_utf8_validation(arg: &MatchedArg, id: &Id)1346 fn assert_utf8_validation(arg: &MatchedArg, id: &Id) {
1347     debug_assert!(
1348         matches!(arg.is_invalid_utf8_allowed(), None | Some(false)),
1349         "Must use `_os` lookups with `Arg::allow_invalid_utf8` at `{:?}`",
1350         id
1351     );
1352 }
1353 
1354 #[cfg_attr(debug_assertions, track_caller)]
1355 #[inline]
assert_no_utf8_validation(arg: &MatchedArg, id: &Id)1356 fn assert_no_utf8_validation(arg: &MatchedArg, id: &Id) {
1357     debug_assert!(
1358         matches!(arg.is_invalid_utf8_allowed(), None | Some(true)),
1359         "Must use `Arg::allow_invalid_utf8` with `_os` lookups at `{:?}`",
1360         id
1361     );
1362 }
1363 
1364 #[cfg(test)]
1365 mod tests {
1366     use super::*;
1367 
1368     #[test]
test_default_values()1369     fn test_default_values() {
1370         let mut values: Values = Values::default();
1371         assert_eq!(values.next(), None);
1372     }
1373 
1374     #[test]
test_default_values_with_shorter_lifetime()1375     fn test_default_values_with_shorter_lifetime() {
1376         let matches = ArgMatches::default();
1377         let mut values = matches.values_of("").unwrap_or_default();
1378         assert_eq!(values.next(), None);
1379     }
1380 
1381     #[test]
test_default_osvalues()1382     fn test_default_osvalues() {
1383         let mut values: OsValues = OsValues::default();
1384         assert_eq!(values.next(), None);
1385     }
1386 
1387     #[test]
test_default_osvalues_with_shorter_lifetime()1388     fn test_default_osvalues_with_shorter_lifetime() {
1389         let matches = ArgMatches::default();
1390         let mut values = matches.values_of_os("").unwrap_or_default();
1391         assert_eq!(values.next(), None);
1392     }
1393 
1394     #[test]
test_default_indices()1395     fn test_default_indices() {
1396         let mut indices: Indices = Indices::default();
1397         assert_eq!(indices.next(), None);
1398     }
1399 
1400     #[test]
test_default_indices_with_shorter_lifetime()1401     fn test_default_indices_with_shorter_lifetime() {
1402         let matches = ArgMatches::default();
1403         let mut indices = matches.indices_of("").unwrap_or_default();
1404         assert_eq!(indices.next(), None);
1405     }
1406 
1407     #[test]
values_exact_size()1408     fn values_exact_size() {
1409         let l = crate::App::new("test")
1410             .arg(
1411                 crate::Arg::new("POTATO")
1412                     .takes_value(true)
1413                     .multiple_values(true)
1414                     .required(true),
1415             )
1416             .try_get_matches_from(["test", "one"])
1417             .unwrap()
1418             .values_of("POTATO")
1419             .expect("present")
1420             .len();
1421         assert_eq!(l, 1);
1422     }
1423 
1424     #[test]
os_values_exact_size()1425     fn os_values_exact_size() {
1426         let l = crate::App::new("test")
1427             .arg(
1428                 crate::Arg::new("POTATO")
1429                     .takes_value(true)
1430                     .multiple_values(true)
1431                     .allow_invalid_utf8(true)
1432                     .required(true),
1433             )
1434             .try_get_matches_from(["test", "one"])
1435             .unwrap()
1436             .values_of_os("POTATO")
1437             .expect("present")
1438             .len();
1439         assert_eq!(l, 1);
1440     }
1441 
1442     #[test]
indices_exact_size()1443     fn indices_exact_size() {
1444         let l = crate::App::new("test")
1445             .arg(
1446                 crate::Arg::new("POTATO")
1447                     .takes_value(true)
1448                     .multiple_values(true)
1449                     .required(true),
1450             )
1451             .try_get_matches_from(["test", "one"])
1452             .unwrap()
1453             .indices_of("POTATO")
1454             .expect("present")
1455             .len();
1456         assert_eq!(l, 1);
1457     }
1458 }
1459