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