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