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