clap_builder/parser/matches/
arg_matches.rs

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