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