clap/args/
arg_matches.rs

1// Std
2use std::borrow::Cow;
3use std::collections::HashMap;
4use std::ffi::{OsStr, OsString};
5use std::iter::Map;
6use std::slice::Iter;
7
8// Internal
9use INVALID_UTF8;
10use args::MatchedArg;
11use args::SubCommand;
12
13/// Used to get information about the arguments that where supplied to the program at runtime by
14/// the user. New instances of this struct are obtained by using the [`App::get_matches`] family of
15/// methods.
16///
17/// # Examples
18///
19/// ```no_run
20/// # use clap::{App, Arg};
21/// let matches = App::new("MyApp")
22///     .arg(Arg::with_name("out")
23///         .long("output")
24///         .required(true)
25///         .takes_value(true))
26///     .arg(Arg::with_name("debug")
27///         .short("d")
28///         .multiple(true))
29///     .arg(Arg::with_name("cfg")
30///         .short("c")
31///         .takes_value(true))
32///     .get_matches(); // builds the instance of ArgMatches
33///
34/// // to get information about the "cfg" argument we created, such as the value supplied we use
35/// // various ArgMatches methods, such as ArgMatches::value_of
36/// if let Some(c) = matches.value_of("cfg") {
37///     println!("Value for -c: {}", c);
38/// }
39///
40/// // The ArgMatches::value_of method returns an Option because the user may not have supplied
41/// // that argument at runtime. But if we specified that the argument was "required" as we did
42/// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually
43/// // used at runtime.
44/// println!("Value for --output: {}", matches.value_of("out").unwrap());
45///
46/// // You can check the presence of an argument
47/// if matches.is_present("out") {
48///     // Another way to check if an argument was present, or if it occurred multiple times is to
49///     // use occurrences_of() which returns 0 if an argument isn't found at runtime, or the
50///     // number of times that it occurred, if it was. To allow an argument to appear more than
51///     // once, you must use the .multiple(true) method, otherwise it will only return 1 or 0.
52///     if matches.occurrences_of("debug") > 2 {
53///         println!("Debug mode is REALLY on, don't be crazy");
54///     } else {
55///         println!("Debug mode kind of on");
56///     }
57/// }
58/// ```
59/// [`App::get_matches`]: ./struct.App.html#method.get_matches
60#[derive(Debug, Clone)]
61pub struct ArgMatches<'a> {
62    #[doc(hidden)] pub args: HashMap<&'a str, MatchedArg>,
63    #[doc(hidden)] pub subcommand: Option<Box<SubCommand<'a>>>,
64    #[doc(hidden)] pub usage: Option<String>,
65}
66
67impl<'a> Default for ArgMatches<'a> {
68    fn default() -> Self {
69        ArgMatches {
70            args: HashMap::new(),
71            subcommand: None,
72            usage: None,
73        }
74    }
75}
76
77impl<'a> ArgMatches<'a> {
78    #[doc(hidden)]
79    pub fn new() -> Self {
80        ArgMatches {
81            ..Default::default()
82        }
83    }
84
85    /// Gets the value of a specific [option] or [positional] argument (i.e. an argument that takes
86    /// an additional value at runtime). If the option wasn't present at runtime
87    /// it returns `None`.
88    ///
89    /// *NOTE:* If getting a value for an option or positional argument that allows multiples,
90    /// prefer [`ArgMatches::values_of`] as `ArgMatches::value_of` will only return the *first*
91    /// value.
92    ///
93    /// # Panics
94    ///
95    /// This method will [`panic!`] if the value contains invalid UTF-8 code points.
96    ///
97    /// # Examples
98    ///
99    /// ```rust
100    /// # use clap::{App, Arg};
101    /// let m = App::new("myapp")
102    ///     .arg(Arg::with_name("output")
103    ///         .takes_value(true))
104    ///     .get_matches_from(vec!["myapp", "something"]);
105    ///
106    /// assert_eq!(m.value_of("output"), Some("something"));
107    /// ```
108    /// [option]: ./struct.Arg.html#method.takes_value
109    /// [positional]: ./struct.Arg.html#method.index
110    /// [`ArgMatches::values_of`]: ./struct.ArgMatches.html#method.values_of
111    /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html
112    pub fn value_of<S: AsRef<str>>(&self, name: S) -> Option<&str> {
113        if let Some(arg) = self.args.get(name.as_ref()) {
114            if let Some(v) = arg.vals.get(0) {
115                return Some(v.to_str().expect(INVALID_UTF8));
116            }
117        }
118        None
119    }
120
121    /// Gets the lossy value of a specific argument. If the argument wasn't present at runtime
122    /// it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those
123    /// invalid points will be replaced with `\u{FFFD}`
124    ///
125    /// *NOTE:* If getting a value for an option or positional argument that allows multiples,
126    /// prefer [`Arg::values_of_lossy`] as `value_of_lossy()` will only return the *first* value.
127    ///
128    /// # Examples
129    ///
130    #[cfg_attr(not(unix), doc = " ```ignore")]
131    #[cfg_attr(unix, doc = " ```")]
132    /// # use clap::{App, Arg};
133    /// use std::ffi::OsString;
134    /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
135    ///
136    /// let m = App::new("utf8")
137    ///     .arg(Arg::from_usage("<arg> 'some arg'"))
138    ///     .get_matches_from(vec![OsString::from("myprog"),
139    ///                             // "Hi {0xe9}!"
140    ///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
141    /// assert_eq!(&*m.value_of_lossy("arg").unwrap(), "Hi \u{FFFD}!");
142    /// ```
143    /// [`Arg::values_of_lossy`]: ./struct.ArgMatches.html#method.values_of_lossy
144    pub fn value_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Cow<'a, str>> {
145        if let Some(arg) = self.args.get(name.as_ref()) {
146            if let Some(v) = arg.vals.get(0) {
147                return Some(v.to_string_lossy());
148            }
149        }
150        None
151    }
152
153    /// Gets the OS version of a string value of a specific argument. If the option wasn't present
154    /// at runtime it returns `None`. An OS value on Unix-like systems is any series of bytes,
155    /// regardless of whether or not they contain valid UTF-8 code points. Since [`String`]s in
156    /// Rust are guaranteed to be valid UTF-8, a valid filename on a Unix system as an argument
157    /// value may contain invalid UTF-8 code points.
158    ///
159    /// *NOTE:* If getting a value for an option or positional argument that allows multiples,
160    /// prefer [`ArgMatches::values_of_os`] as `Arg::value_of_os` will only return the *first*
161    /// value.
162    ///
163    /// # Examples
164    ///
165    #[cfg_attr(not(unix), doc = " ```ignore")]
166    #[cfg_attr(unix, doc = " ```")]
167    /// # use clap::{App, Arg};
168    /// use std::ffi::OsString;
169    /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
170    ///
171    /// let m = App::new("utf8")
172    ///     .arg(Arg::from_usage("<arg> 'some arg'"))
173    ///     .get_matches_from(vec![OsString::from("myprog"),
174    ///                             // "Hi {0xe9}!"
175    ///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
176    /// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']);
177    /// ```
178    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
179    /// [`ArgMatches::values_of_os`]: ./struct.ArgMatches.html#method.values_of_os
180    pub fn value_of_os<S: AsRef<str>>(&self, name: S) -> Option<&OsStr> {
181        self.args
182            .get(name.as_ref())
183            .and_then(|arg| arg.vals.get(0).map(|v| v.as_os_str()))
184    }
185
186    /// Gets a [`Values`] struct which implements [`Iterator`] for values of a specific argument
187    /// (i.e. an argument that takes multiple values at runtime). If the option wasn't present at
188    /// runtime it returns `None`
189    ///
190    /// # Panics
191    ///
192    /// This method will panic if any of the values contain invalid UTF-8 code points.
193    ///
194    /// # Examples
195    ///
196    /// ```rust
197    /// # use clap::{App, Arg};
198    /// let m = App::new("myprog")
199    ///     .arg(Arg::with_name("output")
200    ///         .multiple(true)
201    ///         .short("o")
202    ///         .takes_value(true))
203    ///     .get_matches_from(vec![
204    ///         "myprog", "-o", "val1", "val2", "val3"
205    ///     ]);
206    /// let vals: Vec<&str> = m.values_of("output").unwrap().collect();
207    /// assert_eq!(vals, ["val1", "val2", "val3"]);
208    /// ```
209    /// [`Values`]: ./struct.Values.html
210    /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
211    pub fn values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Values<'a>> {
212        if let Some(arg) = self.args.get(name.as_ref()) {
213            fn to_str_slice(o: &OsString) -> &str { o.to_str().expect(INVALID_UTF8) }
214            let to_str_slice: fn(&OsString) -> &str = to_str_slice; // coerce to fn pointer
215            return Some(Values {
216                iter: arg.vals.iter().map(to_str_slice),
217            });
218        }
219        None
220    }
221
222    /// Gets the lossy values of a specific argument. If the option wasn't present at runtime
223    /// it returns `None`. A lossy value is one where if it contains invalid UTF-8 code points,
224    /// those invalid points will be replaced with `\u{FFFD}`
225    ///
226    /// # Examples
227    ///
228    #[cfg_attr(not(unix), doc = " ```ignore")]
229    #[cfg_attr(unix, doc = " ```")]
230    /// # use clap::{App, Arg};
231    /// use std::ffi::OsString;
232    /// use std::os::unix::ffi::OsStringExt;
233    ///
234    /// let m = App::new("utf8")
235    ///     .arg(Arg::from_usage("<arg>... 'some arg'"))
236    ///     .get_matches_from(vec![OsString::from("myprog"),
237    ///                             // "Hi"
238    ///                             OsString::from_vec(vec![b'H', b'i']),
239    ///                             // "{0xe9}!"
240    ///                             OsString::from_vec(vec![0xe9, b'!'])]);
241    /// let mut itr = m.values_of_lossy("arg").unwrap().into_iter();
242    /// assert_eq!(&itr.next().unwrap()[..], "Hi");
243    /// assert_eq!(&itr.next().unwrap()[..], "\u{FFFD}!");
244    /// assert_eq!(itr.next(), None);
245    /// ```
246    pub fn values_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> {
247        if let Some(arg) = self.args.get(name.as_ref()) {
248            return Some(
249                arg.vals
250                    .iter()
251                    .map(|v| v.to_string_lossy().into_owned())
252                    .collect(),
253            );
254        }
255        None
256    }
257
258    /// Gets a [`OsValues`] struct which is implements [`Iterator`] for [`OsString`] values of a
259    /// specific argument. If the option wasn't present at runtime it returns `None`. An OS value
260    /// on Unix-like systems is any series of bytes, regardless of whether or not they contain
261    /// valid UTF-8 code points. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
262    /// filename as an argument value on Linux (for example) may contain invalid UTF-8 code points.
263    ///
264    /// # Examples
265    ///
266    #[cfg_attr(not(unix), doc = " ```ignore")]
267    #[cfg_attr(unix, doc = " ```")]
268    /// # use clap::{App, Arg};
269    /// use std::ffi::{OsStr,OsString};
270    /// use std::os::unix::ffi::{OsStrExt,OsStringExt};
271    ///
272    /// let m = App::new("utf8")
273    ///     .arg(Arg::from_usage("<arg>... 'some arg'"))
274    ///     .get_matches_from(vec![OsString::from("myprog"),
275    ///                                 // "Hi"
276    ///                                 OsString::from_vec(vec![b'H', b'i']),
277    ///                                 // "{0xe9}!"
278    ///                                 OsString::from_vec(vec![0xe9, b'!'])]);
279    ///
280    /// let mut itr = m.values_of_os("arg").unwrap().into_iter();
281    /// assert_eq!(itr.next(), Some(OsStr::new("Hi")));
282    /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!'])));
283    /// assert_eq!(itr.next(), None);
284    /// ```
285    /// [`OsValues`]: ./struct.OsValues.html
286    /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
287    /// [`OsString`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html
288    /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
289    pub fn values_of_os<S: AsRef<str>>(&'a self, name: S) -> Option<OsValues<'a>> {
290        fn to_str_slice(o: &OsString) -> &OsStr { &*o }
291        let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer
292        if let Some(arg) = self.args.get(name.as_ref()) {
293            return Some(OsValues {
294                iter: arg.vals.iter().map(to_str_slice),
295            });
296        }
297        None
298    }
299
300    /// Returns `true` if an argument was present at runtime, otherwise `false`.
301    ///
302    /// # Examples
303    ///
304    /// ```rust
305    /// # use clap::{App, Arg};
306    /// let m = App::new("myprog")
307    ///     .arg(Arg::with_name("debug")
308    ///         .short("d"))
309    ///     .get_matches_from(vec![
310    ///         "myprog", "-d"
311    ///     ]);
312    ///
313    /// assert!(m.is_present("debug"));
314    /// ```
315    pub fn is_present<S: AsRef<str>>(&self, name: S) -> bool {
316        if let Some(ref sc) = self.subcommand {
317            if sc.name == name.as_ref() {
318                return true;
319            }
320        }
321        self.args.contains_key(name.as_ref())
322    }
323
324    /// Returns the number of times an argument was used at runtime. If an argument isn't present
325    /// it will return `0`.
326    ///
327    /// **NOTE:** This returns the number of times the argument was used, *not* the number of
328    /// values. For example, `-o val1 val2 val3 -o val4` would return `2` (2 occurrences, but 4
329    /// values).
330    ///
331    /// # Examples
332    ///
333    /// ```rust
334    /// # use clap::{App, Arg};
335    /// let m = App::new("myprog")
336    ///     .arg(Arg::with_name("debug")
337    ///         .short("d")
338    ///         .multiple(true))
339    ///     .get_matches_from(vec![
340    ///         "myprog", "-d", "-d", "-d"
341    ///     ]);
342    ///
343    /// assert_eq!(m.occurrences_of("debug"), 3);
344    /// ```
345    ///
346    /// This next example shows that counts actual uses of the argument, not just `-`'s
347    ///
348    /// ```rust
349    /// # use clap::{App, Arg};
350    /// let m = App::new("myprog")
351    ///     .arg(Arg::with_name("debug")
352    ///         .short("d")
353    ///         .multiple(true))
354    ///     .arg(Arg::with_name("flag")
355    ///         .short("f"))
356    ///     .get_matches_from(vec![
357    ///         "myprog", "-ddfd"
358    ///     ]);
359    ///
360    /// assert_eq!(m.occurrences_of("debug"), 3);
361    /// assert_eq!(m.occurrences_of("flag"), 1);
362    /// ```
363    pub fn occurrences_of<S: AsRef<str>>(&self, name: S) -> u64 {
364        self.args.get(name.as_ref()).map_or(0, |a| a.occurs)
365    }
366
367    /// Gets the starting index of the argument in respect to all other arguments. Indices are
368    /// similar to argv indices, but are not exactly 1:1.
369    ///
370    /// For flags (i.e. those arguments which don't have an associated value), indices refer
371    /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
372    /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
373    /// index for `val` would be recorded. This is by design.
374    ///
375    /// Besides the flag/option descrepancy, the primary difference between an argv index and clap
376    /// index, is that clap continues counting once all arguments have properly seperated, whereas
377    /// an argv index does not.
378    ///
379    /// The examples should clear this up.
380    ///
381    /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first*
382    /// index.
383    ///
384    /// # Examples
385    ///
386    /// The argv indices are listed in the comments below. See how they correspond to the clap
387    /// indices. Note that if it's not listed in a clap index, this is becuase it's not saved in
388    /// in an `ArgMatches` struct for querying.
389    ///
390    /// ```rust
391    /// # use clap::{App, Arg};
392    /// let m = App::new("myapp")
393    ///     .arg(Arg::with_name("flag")
394    ///         .short("f"))
395    ///     .arg(Arg::with_name("option")
396    ///         .short("o")
397    ///         .takes_value(true))
398    ///     .get_matches_from(vec!["myapp", "-f", "-o", "val"]);
399    ///             // ARGV idices: ^0       ^1    ^2    ^3
400    ///             // clap idices:          ^1          ^3
401    ///
402    /// assert_eq!(m.index_of("flag"), Some(1));
403    /// assert_eq!(m.index_of("option"), Some(3));
404    /// ```
405    ///
406    /// Now notice, if we use one of the other styles of options:
407    ///
408    /// ```rust
409    /// # use clap::{App, Arg};
410    /// let m = App::new("myapp")
411    ///     .arg(Arg::with_name("flag")
412    ///         .short("f"))
413    ///     .arg(Arg::with_name("option")
414    ///         .short("o")
415    ///         .takes_value(true))
416    ///     .get_matches_from(vec!["myapp", "-f", "-o=val"]);
417    ///             // ARGV idices: ^0       ^1    ^2
418    ///             // clap idices:          ^1       ^3
419    ///
420    /// assert_eq!(m.index_of("flag"), Some(1));
421    /// assert_eq!(m.index_of("option"), Some(3));
422    /// ```
423    ///
424    /// Things become much more complicated, or clear if we look at a more complex combination of
425    /// flags. Let's also throw in the final option style for good measure.
426    ///
427    /// ```rust
428    /// # use clap::{App, Arg};
429    /// let m = App::new("myapp")
430    ///     .arg(Arg::with_name("flag")
431    ///         .short("f"))
432    ///     .arg(Arg::with_name("flag2")
433    ///         .short("F"))
434    ///     .arg(Arg::with_name("flag3")
435    ///         .short("z"))
436    ///     .arg(Arg::with_name("option")
437    ///         .short("o")
438    ///         .takes_value(true))
439    ///     .get_matches_from(vec!["myapp", "-fzF", "-oval"]);
440    ///             // ARGV idices: ^0      ^1       ^2
441    ///             // clap idices:         ^1,2,3    ^5
442    ///             //
443    ///             // clap sees the above as 'myapp -f -z -F -o val'
444    ///             //                         ^0    ^1 ^2 ^3 ^4 ^5
445    /// assert_eq!(m.index_of("flag"), Some(1));
446    /// assert_eq!(m.index_of("flag2"), Some(3));
447    /// assert_eq!(m.index_of("flag3"), Some(2));
448    /// assert_eq!(m.index_of("option"), Some(5));
449    /// ```
450    ///
451    /// One final combination of flags/options to see how they combine:
452    ///
453    /// ```rust
454    /// # use clap::{App, Arg};
455    /// let m = App::new("myapp")
456    ///     .arg(Arg::with_name("flag")
457    ///         .short("f"))
458    ///     .arg(Arg::with_name("flag2")
459    ///         .short("F"))
460    ///     .arg(Arg::with_name("flag3")
461    ///         .short("z"))
462    ///     .arg(Arg::with_name("option")
463    ///         .short("o")
464    ///         .takes_value(true)
465    ///         .multiple(true))
466    ///     .get_matches_from(vec!["myapp", "-fzFoval"]);
467    ///             // ARGV idices: ^0       ^1
468    ///             // clap idices:          ^1,2,3^5
469    ///             //
470    ///             // clap sees the above as 'myapp -f -z -F -o val'
471    ///             //                         ^0    ^1 ^2 ^3 ^4 ^5
472    /// assert_eq!(m.index_of("flag"), Some(1));
473    /// assert_eq!(m.index_of("flag2"), Some(3));
474    /// assert_eq!(m.index_of("flag3"), Some(2));
475    /// assert_eq!(m.index_of("option"), Some(5));
476    /// ```
477    ///
478    /// The last part to mention is when values are sent in multiple groups with a [delimiter].
479    ///
480    /// ```rust
481    /// # use clap::{App, Arg};
482    /// let m = App::new("myapp")
483    ///     .arg(Arg::with_name("option")
484    ///         .short("o")
485    ///         .takes_value(true)
486    ///         .multiple(true))
487    ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
488    ///             // ARGV idices: ^0       ^1
489    ///             // clap idices:             ^2   ^3   ^4
490    ///             //
491    ///             // clap sees the above as 'myapp -o val1 val2 val3'
492    ///             //                         ^0    ^1 ^2   ^3   ^4
493    /// assert_eq!(m.index_of("option"), Some(2));
494    /// ```
495    /// [`ArgMatches`]: ./struct.ArgMatches.html
496    /// [delimiter]: ./struct.Arg.html#method.value_delimiter
497    pub fn index_of<S: AsRef<str>>(&self, name: S) -> Option<usize> {
498        if let Some(arg) = self.args.get(name.as_ref()) {
499            if let Some(i) = arg.indices.get(0) {
500                return Some(*i);
501            }
502        }
503        None
504    }
505
506    /// Gets all indices of the argument in respect to all other arguments. Indices are
507    /// similar to argv indices, but are not exactly 1:1.
508    ///
509    /// For flags (i.e. those arguments which don't have an associated value), indices refer
510    /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices
511    /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the
512    /// index for `val` would be recorded. This is by design.
513    ///
514    /// *NOTE:* For more information about how clap indices compare to argv indices, see
515    /// [`ArgMatches::index_of`]
516    ///
517    /// # Examples
518    ///
519    /// ```rust
520    /// # use clap::{App, Arg};
521    /// let m = App::new("myapp")
522    ///     .arg(Arg::with_name("option")
523    ///         .short("o")
524    ///         .takes_value(true)
525    ///         .use_delimiter(true)
526    ///         .multiple(true))
527    ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
528    ///             // ARGV idices: ^0       ^1
529    ///             // clap idices:             ^2   ^3   ^4
530    ///             //
531    ///             // clap sees the above as 'myapp -o val1 val2 val3'
532    ///             //                         ^0    ^1 ^2   ^3   ^4
533    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]);
534    /// ```
535    ///
536    /// Another quick example is when flags and options are used together
537    ///
538    /// ```rust
539    /// # use clap::{App, Arg};
540    /// let m = App::new("myapp")
541    ///     .arg(Arg::with_name("option")
542    ///         .short("o")
543    ///         .takes_value(true)
544    ///         .multiple(true))
545    ///     .arg(Arg::with_name("flag")
546    ///         .short("f")
547    ///         .multiple(true))
548    ///     .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]);
549    ///             // ARGV idices: ^0       ^1    ^2      ^3    ^4    ^5      ^6
550    ///             // clap idices:                ^2      ^3          ^5      ^6
551    ///
552    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]);
553    /// assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[3, 6]);
554    /// ```
555    ///
556    /// One final example, which is an odd case; if we *don't* use  value delimiter as we did with
557    /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they
558    /// would all be a single value of `val1,val2,val3`, in which case case they'd only receive a
559    /// single index.
560    ///
561    /// ```rust
562    /// # use clap::{App, Arg};
563    /// let m = App::new("myapp")
564    ///     .arg(Arg::with_name("option")
565    ///         .short("o")
566    ///         .takes_value(true)
567    ///         .multiple(true))
568    ///     .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]);
569    ///             // ARGV idices: ^0       ^1
570    ///             // clap idices:             ^2
571    ///             //
572    ///             // clap sees the above as 'myapp -o "val1,val2,val3"'
573    ///             //                         ^0    ^1  ^2
574    /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]);
575    /// ```
576    /// [`ArgMatches`]: ./struct.ArgMatches.html
577    /// [`ArgMatches::index_of`]: ./struct.ArgMatches.html#method.index_of
578    /// [delimiter]: ./struct.Arg.html#method.value_delimiter
579    pub fn indices_of<S: AsRef<str>>(&'a self, name: S) -> Option<Indices<'a>> {
580        if let Some(arg) = self.args.get(name.as_ref()) {
581            fn to_usize(i: &usize) -> usize { *i }
582            let to_usize: fn(&usize) -> usize = to_usize; // coerce to fn pointer
583            return Some(Indices {
584                iter: arg.indices.iter().map(to_usize),
585            });
586        }
587        None
588    }
589
590    /// Because [`Subcommand`]s are essentially "sub-[`App`]s" they have their own [`ArgMatches`]
591    /// as well. This method returns the [`ArgMatches`] for a particular subcommand or `None` if
592    /// the subcommand wasn't present at runtime.
593    ///
594    /// # Examples
595    ///
596    /// ```rust
597    /// # use clap::{App, Arg, SubCommand};
598    /// let app_m = App::new("myprog")
599    ///     .arg(Arg::with_name("debug")
600    ///         .short("d"))
601    ///     .subcommand(SubCommand::with_name("test")
602    ///         .arg(Arg::with_name("opt")
603    ///             .long("option")
604    ///             .takes_value(true)))
605    ///     .get_matches_from(vec![
606    ///         "myprog", "-d", "test", "--option", "val"
607    ///     ]);
608    ///
609    /// // Both parent commands, and child subcommands can have arguments present at the same times
610    /// assert!(app_m.is_present("debug"));
611    ///
612    /// // Get the subcommand's ArgMatches instance
613    /// if let Some(sub_m) = app_m.subcommand_matches("test") {
614    ///     // Use the struct like normal
615    ///     assert_eq!(sub_m.value_of("opt"), Some("val"));
616    /// }
617    /// ```
618    /// [`Subcommand`]: ./struct.SubCommand.html
619    /// [`App`]: ./struct.App.html
620    /// [`ArgMatches`]: ./struct.ArgMatches.html
621    pub fn subcommand_matches<S: AsRef<str>>(&self, name: S) -> Option<&ArgMatches<'a>> {
622        if let Some(ref s) = self.subcommand {
623            if s.name == name.as_ref() {
624                return Some(&s.matches);
625            }
626        }
627        None
628    }
629
630    /// Because [`Subcommand`]s are essentially "sub-[`App`]s" they have their own [`ArgMatches`]
631    /// as well.But simply getting the sub-[`ArgMatches`] doesn't help much if we don't also know
632    /// which subcommand was actually used. This method returns the name of the subcommand that was
633    /// used at runtime, or `None` if one wasn't.
634    ///
635    /// *NOTE*: Subcommands form a hierarchy, where multiple subcommands can be used at runtime,
636    /// but only a single subcommand from any group of sibling commands may used at once.
637    ///
638    /// An ASCII art depiction may help explain this better...Using a fictional version of `git` as
639    /// the demo subject. Imagine the following are all subcommands of `git` (note, the author is
640    /// aware these aren't actually all subcommands in the real `git` interface, but it makes
641    /// explanation easier)
642    ///
643    /// ```notrust
644    ///              Top Level App (git)                         TOP
645    ///                              |
646    ///       -----------------------------------------
647    ///      /             |                \          \
648    ///   clone          push              add       commit      LEVEL 1
649    ///     |           /    \            /    \       |
650    ///    url      origin   remote    ref    name   message     LEVEL 2
651    ///             /                  /\
652    ///          path            remote  local                   LEVEL 3
653    /// ```
654    ///
655    /// Given the above fictional subcommand hierarchy, valid runtime uses would be (not an all
656    /// inclusive list, and not including argument options per command for brevity and clarity):
657    ///
658    /// ```sh
659    /// $ git clone url
660    /// $ git push origin path
661    /// $ git add ref local
662    /// $ git commit message
663    /// ```
664    ///
665    /// Notice only one command per "level" may be used. You could not, for example, do `$ git
666    /// clone url push origin path`
667    ///
668    /// # Examples
669    ///
670    /// ```no_run
671    /// # use clap::{App, Arg, SubCommand};
672    ///  let app_m = App::new("git")
673    ///      .subcommand(SubCommand::with_name("clone"))
674    ///      .subcommand(SubCommand::with_name("push"))
675    ///      .subcommand(SubCommand::with_name("commit"))
676    ///      .get_matches();
677    ///
678    /// match app_m.subcommand_name() {
679    ///     Some("clone")  => {}, // clone was used
680    ///     Some("push")   => {}, // push was used
681    ///     Some("commit") => {}, // commit was used
682    ///     _              => {}, // Either no subcommand or one not tested for...
683    /// }
684    /// ```
685    /// [`Subcommand`]: ./struct.SubCommand.html
686    /// [`App`]: ./struct.App.html
687    /// [`ArgMatches`]: ./struct.ArgMatches.html
688    pub fn subcommand_name(&self) -> Option<&str> {
689        self.subcommand.as_ref().map(|sc| &sc.name[..])
690    }
691
692    /// This brings together [`ArgMatches::subcommand_matches`] and [`ArgMatches::subcommand_name`]
693    /// by returning a tuple with both pieces of information.
694    ///
695    /// # Examples
696    ///
697    /// ```no_run
698    /// # use clap::{App, Arg, SubCommand};
699    ///  let app_m = App::new("git")
700    ///      .subcommand(SubCommand::with_name("clone"))
701    ///      .subcommand(SubCommand::with_name("push"))
702    ///      .subcommand(SubCommand::with_name("commit"))
703    ///      .get_matches();
704    ///
705    /// match app_m.subcommand() {
706    ///     ("clone",  Some(sub_m)) => {}, // clone was used
707    ///     ("push",   Some(sub_m)) => {}, // push was used
708    ///     ("commit", Some(sub_m)) => {}, // commit was used
709    ///     _                       => {}, // Either no subcommand or one not tested for...
710    /// }
711    /// ```
712    ///
713    /// Another useful scenario is when you want to support third party, or external, subcommands.
714    /// In these cases you can't know the subcommand name ahead of time, so use a variable instead
715    /// with pattern matching!
716    ///
717    /// ```rust
718    /// # use clap::{App, AppSettings};
719    /// // Assume there is an external subcommand named "subcmd"
720    /// let app_m = App::new("myprog")
721    ///     .setting(AppSettings::AllowExternalSubcommands)
722    ///     .get_matches_from(vec![
723    ///         "myprog", "subcmd", "--option", "value", "-fff", "--flag"
724    ///     ]);
725    ///
726    /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty
727    /// // string argument name
728    /// match app_m.subcommand() {
729    ///     (external, Some(sub_m)) => {
730    ///          let ext_args: Vec<&str> = sub_m.values_of("").unwrap().collect();
731    ///          assert_eq!(external, "subcmd");
732    ///          assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]);
733    ///     },
734    ///     _ => {},
735    /// }
736    /// ```
737    /// [`ArgMatches::subcommand_matches`]: ./struct.ArgMatches.html#method.subcommand_matches
738    /// [`ArgMatches::subcommand_name`]: ./struct.ArgMatches.html#method.subcommand_name
739    pub fn subcommand(&self) -> (&str, Option<&ArgMatches<'a>>) {
740        self.subcommand
741            .as_ref()
742            .map_or(("", None), |sc| (&sc.name[..], Some(&sc.matches)))
743    }
744
745    /// Returns a string slice of the usage statement for the [`App`] or [`SubCommand`]
746    ///
747    /// # Examples
748    ///
749    /// ```no_run
750    /// # use clap::{App, Arg, SubCommand};
751    /// let app_m = App::new("myprog")
752    ///     .subcommand(SubCommand::with_name("test"))
753    ///     .get_matches();
754    ///
755    /// println!("{}", app_m.usage());
756    /// ```
757    /// [`Subcommand`]: ./struct.SubCommand.html
758    /// [`App`]: ./struct.App.html
759    pub fn usage(&self) -> &str { self.usage.as_ref().map_or("", |u| &u[..]) }
760}
761
762
763// The following were taken and adapated from vec_map source
764// repo: https://github.com/contain-rs/vec-map
765// commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
766// license: MIT - Copyright (c) 2015 The Rust Project Developers
767
768/// An iterator for getting multiple values out of an argument via the [`ArgMatches::values_of`]
769/// method.
770///
771/// # Examples
772///
773/// ```rust
774/// # use clap::{App, Arg};
775/// let m = App::new("myapp")
776///     .arg(Arg::with_name("output")
777///         .short("o")
778///         .multiple(true)
779///         .takes_value(true))
780///     .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
781///
782/// let mut values = m.values_of("output").unwrap();
783///
784/// assert_eq!(values.next(), Some("val1"));
785/// assert_eq!(values.next(), Some("val2"));
786/// assert_eq!(values.next(), None);
787/// ```
788/// [`ArgMatches::values_of`]: ./struct.ArgMatches.html#method.values_of
789#[derive(Debug, Clone)]
790pub struct Values<'a> {
791    iter: Map<Iter<'a, OsString>, fn(&'a OsString) -> &'a str>,
792}
793
794impl<'a> Iterator for Values<'a> {
795    type Item = &'a str;
796
797    fn next(&mut self) -> Option<&'a str> { self.iter.next() }
798    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
799}
800
801impl<'a> DoubleEndedIterator for Values<'a> {
802    fn next_back(&mut self) -> Option<&'a str> { self.iter.next_back() }
803}
804
805impl<'a> ExactSizeIterator for Values<'a> {}
806
807/// Creates an empty iterator.
808impl<'a> Default for Values<'a> {
809    fn default() -> Self {
810        static EMPTY: [OsString; 0] = [];
811        // This is never called because the iterator is empty:
812        fn to_str_slice(_: &OsString) -> &str { unreachable!() };
813        Values {
814            iter: EMPTY[..].iter().map(to_str_slice),
815        }
816    }
817}
818
819/// An iterator for getting multiple values out of an argument via the [`ArgMatches::values_of_os`]
820/// method. Usage of this iterator allows values which contain invalid UTF-8 code points unlike
821/// [`Values`].
822///
823/// # Examples
824///
825#[cfg_attr(not(unix), doc = " ```ignore")]
826#[cfg_attr(unix, doc = " ```")]
827/// # use clap::{App, Arg};
828/// use std::ffi::OsString;
829/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
830///
831/// let m = App::new("utf8")
832///     .arg(Arg::from_usage("<arg> 'some arg'"))
833///     .get_matches_from(vec![OsString::from("myprog"),
834///                             // "Hi {0xe9}!"
835///                             OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]);
836/// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']);
837/// ```
838/// [`ArgMatches::values_of_os`]: ./struct.ArgMatches.html#method.values_of_os
839/// [`Values`]: ./struct.Values.html
840#[derive(Debug, Clone)]
841pub struct OsValues<'a> {
842    iter: Map<Iter<'a, OsString>, fn(&'a OsString) -> &'a OsStr>,
843}
844
845impl<'a> Iterator for OsValues<'a> {
846    type Item = &'a OsStr;
847
848    fn next(&mut self) -> Option<&'a OsStr> { self.iter.next() }
849    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
850}
851
852impl<'a> DoubleEndedIterator for OsValues<'a> {
853    fn next_back(&mut self) -> Option<&'a OsStr> { self.iter.next_back() }
854}
855
856impl<'a> ExactSizeIterator for OsValues<'a> {}
857
858/// Creates an empty iterator.
859impl<'a> Default for OsValues<'a> {
860    fn default() -> Self {
861        static EMPTY: [OsString; 0] = [];
862        // This is never called because the iterator is empty:
863        fn to_str_slice(_: &OsString) -> &OsStr { unreachable!() };
864        OsValues {
865            iter: EMPTY[..].iter().map(to_str_slice),
866        }
867    }
868}
869
870/// An iterator for getting multiple indices out of an argument via the [`ArgMatches::indices_of`]
871/// method.
872///
873/// # Examples
874///
875/// ```rust
876/// # use clap::{App, Arg};
877/// let m = App::new("myapp")
878///     .arg(Arg::with_name("output")
879///         .short("o")
880///         .multiple(true)
881///         .takes_value(true))
882///     .get_matches_from(vec!["myapp", "-o", "val1", "val2"]);
883///
884/// let mut indices = m.indices_of("output").unwrap();
885///
886/// assert_eq!(indices.next(), Some(2));
887/// assert_eq!(indices.next(), Some(3));
888/// assert_eq!(indices.next(), None);
889/// ```
890/// [`ArgMatches::indices_of`]: ./struct.ArgMatches.html#method.indices_of
891#[derive(Debug, Clone)]
892pub struct Indices<'a> { // would rather use '_, but: https://github.com/rust-lang/rust/issues/48469
893    iter: Map<Iter<'a, usize>, fn(&'a usize) -> usize>,
894}
895
896impl<'a> Iterator for Indices<'a> {
897    type Item = usize;
898
899    fn next(&mut self) -> Option<usize> { self.iter.next() }
900    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
901}
902
903impl<'a> DoubleEndedIterator for Indices<'a> {
904    fn next_back(&mut self) -> Option<usize> { self.iter.next_back() }
905}
906
907impl<'a> ExactSizeIterator for Indices<'a> {}
908
909/// Creates an empty iterator.
910impl<'a> Default for Indices<'a> {
911    fn default() -> Self {
912        static EMPTY: [usize; 0] = [];
913        // This is never called because the iterator is empty:
914        fn to_usize(_: &usize) -> usize { unreachable!() };
915        Indices {
916            iter: EMPTY[..].iter().map(to_usize),
917        }
918    }
919}
920
921#[cfg(test)]
922mod tests {
923    use super::*;
924
925    #[test]
926    fn test_default_values() {
927        let mut values: Values = Values::default();
928        assert_eq!(values.next(), None);
929    }
930
931    #[test]
932    fn test_default_values_with_shorter_lifetime() {
933        let matches = ArgMatches::new();
934        let mut values = matches.values_of("").unwrap_or_default();
935        assert_eq!(values.next(), None);
936    }
937
938    #[test]
939    fn test_default_osvalues() {
940        let mut values: OsValues = OsValues::default();
941        assert_eq!(values.next(), None);
942    }
943
944    #[test]
945    fn test_default_osvalues_with_shorter_lifetime() {
946        let matches = ArgMatches::new();
947        let mut values = matches.values_of_os("").unwrap_or_default();
948        assert_eq!(values.next(), None);
949    }
950
951    #[test]
952    fn test_default_indices() {
953        let mut indices: Indices = Indices::default();
954        assert_eq!(indices.next(), None);
955    }
956
957    #[test]
958    fn test_default_indices_with_shorter_lifetime() {
959        let matches = ArgMatches::new();
960        let mut indices = matches.indices_of("").unwrap_or_default();
961        assert_eq!(indices.next(), None);
962    }
963}