1 // Std 2 use std::borrow::Cow; 3 use std::collections::HashMap; 4 use std::ffi::{OsStr, OsString}; 5 use std::iter::Map; 6 use std::slice::Iter; 7 8 // Internal 9 use args::MatchedArg; 10 use args::SubCommand; 11 use INVALID_UTF8; 12 13 /// Used to get information about the arguments that were supplied to the program at runtime by 14 /// the user. New instances of this struct are obtained by using the [`App::get_matches`] family of 15 /// methods. 16 /// 17 /// # Examples 18 /// 19 /// ```no_run 20 /// # use clap::{App, Arg}; 21 /// let matches = App::new("MyApp") 22 /// .arg(Arg::with_name("out") 23 /// .long("output") 24 /// .required(true) 25 /// .takes_value(true)) 26 /// .arg(Arg::with_name("debug") 27 /// .short("d") 28 /// .multiple(true)) 29 /// .arg(Arg::with_name("cfg") 30 /// .short("c") 31 /// .takes_value(true)) 32 /// .get_matches(); // builds the instance of ArgMatches 33 /// 34 /// // to get information about the "cfg" argument we created, such as the value supplied we use 35 /// // various ArgMatches methods, such as ArgMatches::value_of 36 /// if let Some(c) = matches.value_of("cfg") { 37 /// println!("Value for -c: {}", c); 38 /// } 39 /// 40 /// // The ArgMatches::value_of method returns an Option because the user may not have supplied 41 /// // that argument at runtime. But if we specified that the argument was "required" as we did 42 /// // with the "out" argument, we can safely unwrap because `clap` verifies that was actually 43 /// // used at runtime. 44 /// println!("Value for --output: {}", matches.value_of("out").unwrap()); 45 /// 46 /// // You can check the presence of an argument 47 /// if matches.is_present("out") { 48 /// // Another way to check if an argument was present, or if it occurred multiple times is to 49 /// // use occurrences_of() which returns 0 if an argument isn't found at runtime, or the 50 /// // number of times that it occurred, if it was. To allow an argument to appear more than 51 /// // once, you must use the .multiple(true) method, otherwise it will only return 1 or 0. 52 /// if matches.occurrences_of("debug") > 2 { 53 /// println!("Debug mode is REALLY on, don't be crazy"); 54 /// } else { 55 /// println!("Debug mode kind of on"); 56 /// } 57 /// } 58 /// ``` 59 /// [`App::get_matches`]: ./struct.App.html#method.get_matches 60 #[derive(Debug, Clone)] 61 pub struct ArgMatches<'a> { 62 #[doc(hidden)] 63 pub args: HashMap<&'a str, MatchedArg>, 64 #[doc(hidden)] 65 pub subcommand: Option<Box<SubCommand<'a>>>, 66 #[doc(hidden)] 67 pub usage: Option<String>, 68 } 69 70 impl<'a> Default for ArgMatches<'a> { default() -> Self71 fn default() -> Self { 72 ArgMatches { 73 args: HashMap::new(), 74 subcommand: None, 75 usage: None, 76 } 77 } 78 } 79 80 impl<'a> ArgMatches<'a> { 81 #[doc(hidden)] new() -> Self82 pub fn new() -> Self { 83 ArgMatches { 84 ..Default::default() 85 } 86 } 87 88 /// Gets the value of a specific [option] or [positional] argument (i.e. an argument that takes 89 /// an additional value at runtime). If the option wasn't present at runtime 90 /// it returns `None`. 91 /// 92 /// *NOTE:* If getting a value for an option or positional argument that allows multiples, 93 /// prefer [`ArgMatches::values_of`] as `ArgMatches::value_of` will only return the *first* 94 /// value. 95 /// 96 /// # Panics 97 /// 98 /// This method will [`panic!`] if the value contains invalid UTF-8 code points. 99 /// 100 /// # Examples 101 /// 102 /// ```rust 103 /// # use clap::{App, Arg}; 104 /// let m = App::new("myapp") 105 /// .arg(Arg::with_name("output") 106 /// .takes_value(true)) 107 /// .get_matches_from(vec!["myapp", "something"]); 108 /// 109 /// assert_eq!(m.value_of("output"), Some("something")); 110 /// ``` 111 /// [option]: ./struct.Arg.html#method.takes_value 112 /// [positional]: ./struct.Arg.html#method.index 113 /// [`ArgMatches::values_of`]: ./struct.ArgMatches.html#method.values_of 114 /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html value_of<S: AsRef<str>>(&self, name: S) -> Option<&str>115 pub fn value_of<S: AsRef<str>>(&self, name: S) -> Option<&str> { 116 if let Some(arg) = self.args.get(name.as_ref()) { 117 if let Some(v) = arg.vals.get(0) { 118 return Some(v.to_str().expect(INVALID_UTF8)); 119 } 120 } 121 None 122 } 123 124 /// Gets the lossy value of a specific argument. If the argument wasn't present at runtime 125 /// it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those 126 /// invalid points will be replaced with `\u{FFFD}` 127 /// 128 /// *NOTE:* If getting a value for an option or positional argument that allows multiples, 129 /// prefer [`Arg::values_of_lossy`] as `value_of_lossy()` will only return the *first* value. 130 /// 131 /// # Examples 132 /// 133 #[cfg_attr(not(unix), doc = " ```ignore")] 134 #[cfg_attr(unix, doc = " ```")] 135 /// # use clap::{App, Arg}; 136 /// use std::ffi::OsString; 137 /// use std::os::unix::ffi::{OsStrExt,OsStringExt}; 138 /// 139 /// let m = App::new("utf8") 140 /// .arg(Arg::from_usage("<arg> 'some arg'")) 141 /// .get_matches_from(vec![OsString::from("myprog"), 142 /// // "Hi {0xe9}!" 143 /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); 144 /// assert_eq!(&*m.value_of_lossy("arg").unwrap(), "Hi \u{FFFD}!"); 145 /// ``` 146 /// [`Arg::values_of_lossy`]: ./struct.ArgMatches.html#method.values_of_lossy value_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Cow<'a, str>>147 pub fn value_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Cow<'a, str>> { 148 if let Some(arg) = self.args.get(name.as_ref()) { 149 if let Some(v) = arg.vals.get(0) { 150 return Some(v.to_string_lossy()); 151 } 152 } 153 None 154 } 155 156 /// Gets the OS version of a string value of a specific argument. If the option wasn't present 157 /// at runtime it returns `None`. An OS value on Unix-like systems is any series of bytes, 158 /// regardless of whether or not they contain valid UTF-8 code points. Since [`String`]s in 159 /// Rust are guaranteed to be valid UTF-8, a valid filename on a Unix system as an argument 160 /// value may contain invalid UTF-8 code points. 161 /// 162 /// *NOTE:* If getting a value for an option or positional argument that allows multiples, 163 /// prefer [`ArgMatches::values_of_os`] as `Arg::value_of_os` will only return the *first* 164 /// value. 165 /// 166 /// # Examples 167 /// 168 #[cfg_attr(not(unix), doc = " ```ignore")] 169 #[cfg_attr(unix, doc = " ```")] 170 /// # use clap::{App, Arg}; 171 /// use std::ffi::OsString; 172 /// use std::os::unix::ffi::{OsStrExt,OsStringExt}; 173 /// 174 /// let m = App::new("utf8") 175 /// .arg(Arg::from_usage("<arg> 'some arg'")) 176 /// .get_matches_from(vec![OsString::from("myprog"), 177 /// // "Hi {0xe9}!" 178 /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); 179 /// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']); 180 /// ``` 181 /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html 182 /// [`ArgMatches::values_of_os`]: ./struct.ArgMatches.html#method.values_of_os value_of_os<S: AsRef<str>>(&self, name: S) -> Option<&OsStr>183 pub fn value_of_os<S: AsRef<str>>(&self, name: S) -> Option<&OsStr> { 184 self.args 185 .get(name.as_ref()) 186 .and_then(|arg| arg.vals.get(0).map(|v| v.as_os_str())) 187 } 188 189 /// Gets a [`Values`] struct which implements [`Iterator`] for values of a specific argument 190 /// (i.e. an argument that takes multiple values at runtime). If the option wasn't present at 191 /// runtime it returns `None` 192 /// 193 /// # Panics 194 /// 195 /// This method will panic if any of the values contain invalid UTF-8 code points. 196 /// 197 /// # Examples 198 /// 199 /// ```rust 200 /// # use clap::{App, Arg}; 201 /// let m = App::new("myprog") 202 /// .arg(Arg::with_name("output") 203 /// .multiple(true) 204 /// .short("o") 205 /// .takes_value(true)) 206 /// .get_matches_from(vec![ 207 /// "myprog", "-o", "val1", "val2", "val3" 208 /// ]); 209 /// let vals: Vec<&str> = m.values_of("output").unwrap().collect(); 210 /// assert_eq!(vals, ["val1", "val2", "val3"]); 211 /// ``` 212 /// [`Values`]: ./struct.Values.html 213 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Values<'a>>214 pub fn values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Values<'a>> { 215 if let Some(arg) = self.args.get(name.as_ref()) { 216 fn to_str_slice(o: &OsString) -> &str { 217 o.to_str().expect(INVALID_UTF8) 218 } 219 let to_str_slice: fn(&OsString) -> &str = to_str_slice; // coerce to fn pointer 220 return Some(Values { 221 iter: arg.vals.iter().map(to_str_slice), 222 }); 223 } 224 None 225 } 226 227 /// Gets the lossy values of a specific argument. If the option wasn't present at runtime 228 /// it returns `None`. A lossy value is one where if it contains invalid UTF-8 code points, 229 /// those invalid points will be replaced with `\u{FFFD}` 230 /// 231 /// # Examples 232 /// 233 #[cfg_attr(not(unix), doc = " ```ignore")] 234 #[cfg_attr(unix, doc = " ```")] 235 /// # use clap::{App, Arg}; 236 /// use std::ffi::OsString; 237 /// use std::os::unix::ffi::OsStringExt; 238 /// 239 /// let m = App::new("utf8") 240 /// .arg(Arg::from_usage("<arg>... 'some arg'")) 241 /// .get_matches_from(vec![OsString::from("myprog"), 242 /// // "Hi" 243 /// OsString::from_vec(vec![b'H', b'i']), 244 /// // "{0xe9}!" 245 /// OsString::from_vec(vec![0xe9, b'!'])]); 246 /// let mut itr = m.values_of_lossy("arg").unwrap().into_iter(); 247 /// assert_eq!(&itr.next().unwrap()[..], "Hi"); 248 /// assert_eq!(&itr.next().unwrap()[..], "\u{FFFD}!"); 249 /// assert_eq!(itr.next(), None); 250 /// ``` values_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>>251 pub fn values_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> { 252 if let Some(arg) = self.args.get(name.as_ref()) { 253 return Some( 254 arg.vals 255 .iter() 256 .map(|v| v.to_string_lossy().into_owned()) 257 .collect(), 258 ); 259 } 260 None 261 } 262 263 /// Gets a [`OsValues`] struct which is implements [`Iterator`] for [`OsString`] values of a 264 /// specific argument. If the option wasn't present at runtime it returns `None`. An OS value 265 /// on Unix-like systems is any series of bytes, regardless of whether or not they contain 266 /// valid UTF-8 code points. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid 267 /// filename as an argument value on Linux (for example) may contain invalid UTF-8 code points. 268 /// 269 /// # Examples 270 /// 271 #[cfg_attr(not(unix), doc = " ```ignore")] 272 #[cfg_attr(unix, doc = " ```")] 273 /// # use clap::{App, Arg}; 274 /// use std::ffi::{OsStr,OsString}; 275 /// use std::os::unix::ffi::{OsStrExt,OsStringExt}; 276 /// 277 /// let m = App::new("utf8") 278 /// .arg(Arg::from_usage("<arg>... 'some arg'")) 279 /// .get_matches_from(vec![OsString::from("myprog"), 280 /// // "Hi" 281 /// OsString::from_vec(vec![b'H', b'i']), 282 /// // "{0xe9}!" 283 /// OsString::from_vec(vec![0xe9, b'!'])]); 284 /// 285 /// let mut itr = m.values_of_os("arg").unwrap().into_iter(); 286 /// assert_eq!(itr.next(), Some(OsStr::new("Hi"))); 287 /// assert_eq!(itr.next(), Some(OsStr::from_bytes(&[0xe9, b'!']))); 288 /// assert_eq!(itr.next(), None); 289 /// ``` 290 /// [`OsValues`]: ./struct.OsValues.html 291 /// [`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html 292 /// [`OsString`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html 293 /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html values_of_os<S: AsRef<str>>(&'a self, name: S) -> Option<OsValues<'a>>294 pub fn values_of_os<S: AsRef<str>>(&'a self, name: S) -> Option<OsValues<'a>> { 295 fn to_str_slice(o: &OsString) -> &OsStr { 296 &*o 297 } 298 let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer 299 if let Some(arg) = self.args.get(name.as_ref()) { 300 return Some(OsValues { 301 iter: arg.vals.iter().map(to_str_slice), 302 }); 303 } 304 None 305 } 306 307 /// Returns `true` if an argument was present at runtime, otherwise `false`. 308 /// 309 /// # Examples 310 /// 311 /// ```rust 312 /// # use clap::{App, Arg}; 313 /// let m = App::new("myprog") 314 /// .arg(Arg::with_name("debug") 315 /// .short("d")) 316 /// .get_matches_from(vec![ 317 /// "myprog", "-d" 318 /// ]); 319 /// 320 /// assert!(m.is_present("debug")); 321 /// ``` is_present<S: AsRef<str>>(&self, name: S) -> bool322 pub fn is_present<S: AsRef<str>>(&self, name: S) -> bool { 323 if let Some(ref sc) = self.subcommand { 324 if sc.name == name.as_ref() { 325 return true; 326 } 327 } 328 self.args.contains_key(name.as_ref()) 329 } 330 331 /// Returns the number of times an argument was used at runtime. If an argument isn't present 332 /// it will return `0`. 333 /// 334 /// **NOTE:** This returns the number of times the argument was used, *not* the number of 335 /// values. For example, `-o val1 val2 val3 -o val4` would return `2` (2 occurrences, but 4 336 /// values). 337 /// 338 /// # Examples 339 /// 340 /// ```rust 341 /// # use clap::{App, Arg}; 342 /// let m = App::new("myprog") 343 /// .arg(Arg::with_name("debug") 344 /// .short("d") 345 /// .multiple(true)) 346 /// .get_matches_from(vec![ 347 /// "myprog", "-d", "-d", "-d" 348 /// ]); 349 /// 350 /// assert_eq!(m.occurrences_of("debug"), 3); 351 /// ``` 352 /// 353 /// This next example shows that counts actual uses of the argument, not just `-`'s 354 /// 355 /// ```rust 356 /// # use clap::{App, Arg}; 357 /// let m = App::new("myprog") 358 /// .arg(Arg::with_name("debug") 359 /// .short("d") 360 /// .multiple(true)) 361 /// .arg(Arg::with_name("flag") 362 /// .short("f")) 363 /// .get_matches_from(vec![ 364 /// "myprog", "-ddfd" 365 /// ]); 366 /// 367 /// assert_eq!(m.occurrences_of("debug"), 3); 368 /// assert_eq!(m.occurrences_of("flag"), 1); 369 /// ``` occurrences_of<S: AsRef<str>>(&self, name: S) -> u64370 pub fn occurrences_of<S: AsRef<str>>(&self, name: S) -> u64 { 371 self.args.get(name.as_ref()).map_or(0, |a| a.occurs) 372 } 373 374 /// Gets the starting index of the argument in respect to all other arguments. Indices are 375 /// similar to argv indices, but are not exactly 1:1. 376 /// 377 /// For flags (i.e. those arguments which don't have an associated value), indices refer 378 /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices 379 /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the 380 /// index for `val` would be recorded. This is by design. 381 /// 382 /// Besides the flag/option descrepancy, the primary difference between an argv index and clap 383 /// index, is that clap continues counting once all arguments have properly seperated, whereas 384 /// an argv index does not. 385 /// 386 /// The examples should clear this up. 387 /// 388 /// *NOTE:* If an argument is allowed multiple times, this method will only give the *first* 389 /// index. 390 /// 391 /// # Examples 392 /// 393 /// The argv indices are listed in the comments below. See how they correspond to the clap 394 /// indices. Note that if it's not listed in a clap index, this is becuase it's not saved in 395 /// in an `ArgMatches` struct for querying. 396 /// 397 /// ```rust 398 /// # use clap::{App, Arg}; 399 /// let m = App::new("myapp") 400 /// .arg(Arg::with_name("flag") 401 /// .short("f")) 402 /// .arg(Arg::with_name("option") 403 /// .short("o") 404 /// .takes_value(true)) 405 /// .get_matches_from(vec!["myapp", "-f", "-o", "val"]); 406 /// // ARGV idices: ^0 ^1 ^2 ^3 407 /// // clap idices: ^1 ^3 408 /// 409 /// assert_eq!(m.index_of("flag"), Some(1)); 410 /// assert_eq!(m.index_of("option"), Some(3)); 411 /// ``` 412 /// 413 /// Now notice, if we use one of the other styles of options: 414 /// 415 /// ```rust 416 /// # use clap::{App, Arg}; 417 /// let m = App::new("myapp") 418 /// .arg(Arg::with_name("flag") 419 /// .short("f")) 420 /// .arg(Arg::with_name("option") 421 /// .short("o") 422 /// .takes_value(true)) 423 /// .get_matches_from(vec!["myapp", "-f", "-o=val"]); 424 /// // ARGV idices: ^0 ^1 ^2 425 /// // clap idices: ^1 ^3 426 /// 427 /// assert_eq!(m.index_of("flag"), Some(1)); 428 /// assert_eq!(m.index_of("option"), Some(3)); 429 /// ``` 430 /// 431 /// Things become much more complicated, or clear if we look at a more complex combination of 432 /// flags. Let's also throw in the final option style for good measure. 433 /// 434 /// ```rust 435 /// # use clap::{App, Arg}; 436 /// let m = App::new("myapp") 437 /// .arg(Arg::with_name("flag") 438 /// .short("f")) 439 /// .arg(Arg::with_name("flag2") 440 /// .short("F")) 441 /// .arg(Arg::with_name("flag3") 442 /// .short("z")) 443 /// .arg(Arg::with_name("option") 444 /// .short("o") 445 /// .takes_value(true)) 446 /// .get_matches_from(vec!["myapp", "-fzF", "-oval"]); 447 /// // ARGV idices: ^0 ^1 ^2 448 /// // clap idices: ^1,2,3 ^5 449 /// // 450 /// // clap sees the above as 'myapp -f -z -F -o val' 451 /// // ^0 ^1 ^2 ^3 ^4 ^5 452 /// assert_eq!(m.index_of("flag"), Some(1)); 453 /// assert_eq!(m.index_of("flag2"), Some(3)); 454 /// assert_eq!(m.index_of("flag3"), Some(2)); 455 /// assert_eq!(m.index_of("option"), Some(5)); 456 /// ``` 457 /// 458 /// One final combination of flags/options to see how they combine: 459 /// 460 /// ```rust 461 /// # use clap::{App, Arg}; 462 /// let m = App::new("myapp") 463 /// .arg(Arg::with_name("flag") 464 /// .short("f")) 465 /// .arg(Arg::with_name("flag2") 466 /// .short("F")) 467 /// .arg(Arg::with_name("flag3") 468 /// .short("z")) 469 /// .arg(Arg::with_name("option") 470 /// .short("o") 471 /// .takes_value(true) 472 /// .multiple(true)) 473 /// .get_matches_from(vec!["myapp", "-fzFoval"]); 474 /// // ARGV idices: ^0 ^1 475 /// // clap idices: ^1,2,3^5 476 /// // 477 /// // clap sees the above as 'myapp -f -z -F -o val' 478 /// // ^0 ^1 ^2 ^3 ^4 ^5 479 /// assert_eq!(m.index_of("flag"), Some(1)); 480 /// assert_eq!(m.index_of("flag2"), Some(3)); 481 /// assert_eq!(m.index_of("flag3"), Some(2)); 482 /// assert_eq!(m.index_of("option"), Some(5)); 483 /// ``` 484 /// 485 /// The last part to mention is when values are sent in multiple groups with a [delimiter]. 486 /// 487 /// ```rust 488 /// # use clap::{App, Arg}; 489 /// let m = App::new("myapp") 490 /// .arg(Arg::with_name("option") 491 /// .short("o") 492 /// .takes_value(true) 493 /// .multiple(true)) 494 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); 495 /// // ARGV idices: ^0 ^1 496 /// // clap idices: ^2 ^3 ^4 497 /// // 498 /// // clap sees the above as 'myapp -o val1 val2 val3' 499 /// // ^0 ^1 ^2 ^3 ^4 500 /// assert_eq!(m.index_of("option"), Some(2)); 501 /// ``` 502 /// [`ArgMatches`]: ./struct.ArgMatches.html 503 /// [delimiter]: ./struct.Arg.html#method.value_delimiter index_of<S: AsRef<str>>(&self, name: S) -> Option<usize>504 pub fn index_of<S: AsRef<str>>(&self, name: S) -> Option<usize> { 505 if let Some(arg) = self.args.get(name.as_ref()) { 506 if let Some(i) = arg.indices.get(0) { 507 return Some(*i); 508 } 509 } 510 None 511 } 512 513 /// Gets all indices of the argument in respect to all other arguments. Indices are 514 /// similar to argv indices, but are not exactly 1:1. 515 /// 516 /// For flags (i.e. those arguments which don't have an associated value), indices refer 517 /// to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices 518 /// refer to the *values* `-o val` would therefore not represent two distinct indices, only the 519 /// index for `val` would be recorded. This is by design. 520 /// 521 /// *NOTE:* For more information about how clap indices compare to argv indices, see 522 /// [`ArgMatches::index_of`] 523 /// 524 /// # Examples 525 /// 526 /// ```rust 527 /// # use clap::{App, Arg}; 528 /// let m = App::new("myapp") 529 /// .arg(Arg::with_name("option") 530 /// .short("o") 531 /// .takes_value(true) 532 /// .use_delimiter(true) 533 /// .multiple(true)) 534 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); 535 /// // ARGV idices: ^0 ^1 536 /// // clap idices: ^2 ^3 ^4 537 /// // 538 /// // clap sees the above as 'myapp -o val1 val2 val3' 539 /// // ^0 ^1 ^2 ^3 ^4 540 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 3, 4]); 541 /// ``` 542 /// 543 /// Another quick example is when flags and options are used together 544 /// 545 /// ```rust 546 /// # use clap::{App, Arg}; 547 /// let m = App::new("myapp") 548 /// .arg(Arg::with_name("option") 549 /// .short("o") 550 /// .takes_value(true) 551 /// .multiple(true)) 552 /// .arg(Arg::with_name("flag") 553 /// .short("f") 554 /// .multiple(true)) 555 /// .get_matches_from(vec!["myapp", "-o", "val1", "-f", "-o", "val2", "-f"]); 556 /// // ARGV idices: ^0 ^1 ^2 ^3 ^4 ^5 ^6 557 /// // clap idices: ^2 ^3 ^5 ^6 558 /// 559 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2, 5]); 560 /// assert_eq!(m.indices_of("flag").unwrap().collect::<Vec<_>>(), &[3, 6]); 561 /// ``` 562 /// 563 /// One final example, which is an odd case; if we *don't* use value delimiter as we did with 564 /// the first example above instead of `val1`, `val2` and `val3` all being distinc values, they 565 /// would all be a single value of `val1,val2,val3`, in which case case they'd only receive a 566 /// single index. 567 /// 568 /// ```rust 569 /// # use clap::{App, Arg}; 570 /// let m = App::new("myapp") 571 /// .arg(Arg::with_name("option") 572 /// .short("o") 573 /// .takes_value(true) 574 /// .multiple(true)) 575 /// .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); 576 /// // ARGV idices: ^0 ^1 577 /// // clap idices: ^2 578 /// // 579 /// // clap sees the above as 'myapp -o "val1,val2,val3"' 580 /// // ^0 ^1 ^2 581 /// assert_eq!(m.indices_of("option").unwrap().collect::<Vec<_>>(), &[2]); 582 /// ``` 583 /// [`ArgMatches`]: ./struct.ArgMatches.html 584 /// [`ArgMatches::index_of`]: ./struct.ArgMatches.html#method.index_of 585 /// [delimiter]: ./struct.Arg.html#method.value_delimiter indices_of<S: AsRef<str>>(&'a self, name: S) -> Option<Indices<'a>>586 pub fn indices_of<S: AsRef<str>>(&'a self, name: S) -> Option<Indices<'a>> { 587 if let Some(arg) = self.args.get(name.as_ref()) { 588 fn to_usize(i: &usize) -> usize { 589 *i 590 } 591 let to_usize: fn(&usize) -> usize = to_usize; // coerce to fn pointer 592 return Some(Indices { 593 iter: arg.indices.iter().map(to_usize), 594 }); 595 } 596 None 597 } 598 599 /// Because [`Subcommand`]s are essentially "sub-[`App`]s" they have their own [`ArgMatches`] 600 /// as well. This method returns the [`ArgMatches`] for a particular subcommand or `None` if 601 /// the subcommand wasn't present at runtime. 602 /// 603 /// # Examples 604 /// 605 /// ```rust 606 /// # use clap::{App, Arg, SubCommand}; 607 /// let app_m = App::new("myprog") 608 /// .arg(Arg::with_name("debug") 609 /// .short("d")) 610 /// .subcommand(SubCommand::with_name("test") 611 /// .arg(Arg::with_name("opt") 612 /// .long("option") 613 /// .takes_value(true))) 614 /// .get_matches_from(vec![ 615 /// "myprog", "-d", "test", "--option", "val" 616 /// ]); 617 /// 618 /// // Both parent commands, and child subcommands can have arguments present at the same times 619 /// assert!(app_m.is_present("debug")); 620 /// 621 /// // Get the subcommand's ArgMatches instance 622 /// if let Some(sub_m) = app_m.subcommand_matches("test") { 623 /// // Use the struct like normal 624 /// assert_eq!(sub_m.value_of("opt"), Some("val")); 625 /// } 626 /// ``` 627 /// [`Subcommand`]: ./struct.SubCommand.html 628 /// [`App`]: ./struct.App.html 629 /// [`ArgMatches`]: ./struct.ArgMatches.html subcommand_matches<S: AsRef<str>>(&self, name: S) -> Option<&ArgMatches<'a>>630 pub fn subcommand_matches<S: AsRef<str>>(&self, name: S) -> Option<&ArgMatches<'a>> { 631 if let Some(ref s) = self.subcommand { 632 if s.name == name.as_ref() { 633 return Some(&s.matches); 634 } 635 } 636 None 637 } 638 639 /// Because [`Subcommand`]s are essentially "sub-[`App`]s" they have their own [`ArgMatches`] 640 /// as well.But simply getting the sub-[`ArgMatches`] doesn't help much if we don't also know 641 /// which subcommand was actually used. This method returns the name of the subcommand that was 642 /// used at runtime, or `None` if one wasn't. 643 /// 644 /// *NOTE*: Subcommands form a hierarchy, where multiple subcommands can be used at runtime, 645 /// but only a single subcommand from any group of sibling commands may used at once. 646 /// 647 /// An ASCII art depiction may help explain this better...Using a fictional version of `git` as 648 /// the demo subject. Imagine the following are all subcommands of `git` (note, the author is 649 /// aware these aren't actually all subcommands in the real `git` interface, but it makes 650 /// explanation easier) 651 /// 652 /// ```notrust 653 /// Top Level App (git) TOP 654 /// | 655 /// ----------------------------------------- 656 /// / | \ \ 657 /// clone push add commit LEVEL 1 658 /// | / \ / \ | 659 /// url origin remote ref name message LEVEL 2 660 /// / /\ 661 /// path remote local LEVEL 3 662 /// ``` 663 /// 664 /// Given the above fictional subcommand hierarchy, valid runtime uses would be (not an all 665 /// inclusive list, and not including argument options per command for brevity and clarity): 666 /// 667 /// ```sh 668 /// $ git clone url 669 /// $ git push origin path 670 /// $ git add ref local 671 /// $ git commit message 672 /// ``` 673 /// 674 /// Notice only one command per "level" may be used. You could not, for example, do `$ git 675 /// clone url push origin path` 676 /// 677 /// # Examples 678 /// 679 /// ```no_run 680 /// # use clap::{App, Arg, SubCommand}; 681 /// let app_m = App::new("git") 682 /// .subcommand(SubCommand::with_name("clone")) 683 /// .subcommand(SubCommand::with_name("push")) 684 /// .subcommand(SubCommand::with_name("commit")) 685 /// .get_matches(); 686 /// 687 /// match app_m.subcommand_name() { 688 /// Some("clone") => {}, // clone was used 689 /// Some("push") => {}, // push was used 690 /// Some("commit") => {}, // commit was used 691 /// _ => {}, // Either no subcommand or one not tested for... 692 /// } 693 /// ``` 694 /// [`Subcommand`]: ./struct.SubCommand.html 695 /// [`App`]: ./struct.App.html 696 /// [`ArgMatches`]: ./struct.ArgMatches.html subcommand_name(&self) -> Option<&str>697 pub fn subcommand_name(&self) -> Option<&str> { 698 self.subcommand.as_ref().map(|sc| &sc.name[..]) 699 } 700 701 /// This brings together [`ArgMatches::subcommand_matches`] and [`ArgMatches::subcommand_name`] 702 /// by returning a tuple with both pieces of information. 703 /// 704 /// # Examples 705 /// 706 /// ```no_run 707 /// # use clap::{App, Arg, SubCommand}; 708 /// let app_m = App::new("git") 709 /// .subcommand(SubCommand::with_name("clone")) 710 /// .subcommand(SubCommand::with_name("push")) 711 /// .subcommand(SubCommand::with_name("commit")) 712 /// .get_matches(); 713 /// 714 /// match app_m.subcommand() { 715 /// ("clone", Some(sub_m)) => {}, // clone was used 716 /// ("push", Some(sub_m)) => {}, // push was used 717 /// ("commit", Some(sub_m)) => {}, // commit was used 718 /// _ => {}, // Either no subcommand or one not tested for... 719 /// } 720 /// ``` 721 /// 722 /// Another useful scenario is when you want to support third party, or external, subcommands. 723 /// In these cases you can't know the subcommand name ahead of time, so use a variable instead 724 /// with pattern matching! 725 /// 726 /// ```rust 727 /// # use clap::{App, AppSettings}; 728 /// // Assume there is an external subcommand named "subcmd" 729 /// let app_m = App::new("myprog") 730 /// .setting(AppSettings::AllowExternalSubcommands) 731 /// .get_matches_from(vec![ 732 /// "myprog", "subcmd", "--option", "value", "-fff", "--flag" 733 /// ]); 734 /// 735 /// // All trailing arguments will be stored under the subcommand's sub-matches using an empty 736 /// // string argument name 737 /// match app_m.subcommand() { 738 /// (external, Some(sub_m)) => { 739 /// let ext_args: Vec<&str> = sub_m.values_of("").unwrap().collect(); 740 /// assert_eq!(external, "subcmd"); 741 /// assert_eq!(ext_args, ["--option", "value", "-fff", "--flag"]); 742 /// }, 743 /// _ => {}, 744 /// } 745 /// ``` 746 /// [`ArgMatches::subcommand_matches`]: ./struct.ArgMatches.html#method.subcommand_matches 747 /// [`ArgMatches::subcommand_name`]: ./struct.ArgMatches.html#method.subcommand_name subcommand(&self) -> (&str, Option<&ArgMatches<'a>>)748 pub fn subcommand(&self) -> (&str, Option<&ArgMatches<'a>>) { 749 self.subcommand 750 .as_ref() 751 .map_or(("", None), |sc| (&sc.name[..], Some(&sc.matches))) 752 } 753 754 /// Returns a string slice of the usage statement for the [`App`] or [`SubCommand`] 755 /// 756 /// # Examples 757 /// 758 /// ```no_run 759 /// # use clap::{App, Arg, SubCommand}; 760 /// let app_m = App::new("myprog") 761 /// .subcommand(SubCommand::with_name("test")) 762 /// .get_matches(); 763 /// 764 /// println!("{}", app_m.usage()); 765 /// ``` 766 /// [`Subcommand`]: ./struct.SubCommand.html 767 /// [`App`]: ./struct.App.html usage(&self) -> &str768 pub fn usage(&self) -> &str { 769 self.usage.as_ref().map_or("", |u| &u[..]) 770 } 771 } 772 773 // The following were taken and adapated from vec_map source 774 // repo: https://github.com/contain-rs/vec-map 775 // commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33 776 // license: MIT - Copyright (c) 2015 The Rust Project Developers 777 778 /// An iterator for getting multiple values out of an argument via the [`ArgMatches::values_of`] 779 /// method. 780 /// 781 /// # Examples 782 /// 783 /// ```rust 784 /// # use clap::{App, Arg}; 785 /// let m = App::new("myapp") 786 /// .arg(Arg::with_name("output") 787 /// .short("o") 788 /// .multiple(true) 789 /// .takes_value(true)) 790 /// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]); 791 /// 792 /// let mut values = m.values_of("output").unwrap(); 793 /// 794 /// assert_eq!(values.next(), Some("val1")); 795 /// assert_eq!(values.next(), Some("val2")); 796 /// assert_eq!(values.next(), None); 797 /// ``` 798 /// [`ArgMatches::values_of`]: ./struct.ArgMatches.html#method.values_of 799 #[derive(Debug, Clone)] 800 pub struct Values<'a> { 801 iter: Map<Iter<'a, OsString>, fn(&'a OsString) -> &'a str>, 802 } 803 804 impl<'a> Iterator for Values<'a> { 805 type Item = &'a str; 806 next(&mut self) -> Option<&'a str>807 fn next(&mut self) -> Option<&'a str> { 808 self.iter.next() 809 } size_hint(&self) -> (usize, Option<usize>)810 fn size_hint(&self) -> (usize, Option<usize>) { 811 self.iter.size_hint() 812 } 813 } 814 815 impl<'a> DoubleEndedIterator for Values<'a> { next_back(&mut self) -> Option<&'a str>816 fn next_back(&mut self) -> Option<&'a str> { 817 self.iter.next_back() 818 } 819 } 820 821 impl<'a> ExactSizeIterator for Values<'a> {} 822 823 /// Creates an empty iterator. 824 impl<'a> Default for Values<'a> { default() -> Self825 fn default() -> Self { 826 static EMPTY: [OsString; 0] = []; 827 // This is never called because the iterator is empty: 828 fn to_str_slice(_: &OsString) -> &str { 829 unreachable!() 830 }; 831 Values { 832 iter: EMPTY[..].iter().map(to_str_slice), 833 } 834 } 835 } 836 837 /// An iterator for getting multiple values out of an argument via the [`ArgMatches::values_of_os`] 838 /// method. Usage of this iterator allows values which contain invalid UTF-8 code points unlike 839 /// [`Values`]. 840 /// 841 /// # Examples 842 /// 843 #[cfg_attr(not(unix), doc = " ```ignore")] 844 #[cfg_attr(unix, doc = " ```")] 845 /// # use clap::{App, Arg}; 846 /// use std::ffi::OsString; 847 /// use std::os::unix::ffi::{OsStrExt,OsStringExt}; 848 /// 849 /// let m = App::new("utf8") 850 /// .arg(Arg::from_usage("<arg> 'some arg'")) 851 /// .get_matches_from(vec![OsString::from("myprog"), 852 /// // "Hi {0xe9}!" 853 /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); 854 /// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']); 855 /// ``` 856 /// [`ArgMatches::values_of_os`]: ./struct.ArgMatches.html#method.values_of_os 857 /// [`Values`]: ./struct.Values.html 858 #[derive(Debug, Clone)] 859 pub struct OsValues<'a> { 860 iter: Map<Iter<'a, OsString>, fn(&'a OsString) -> &'a OsStr>, 861 } 862 863 impl<'a> Iterator for OsValues<'a> { 864 type Item = &'a OsStr; 865 next(&mut self) -> Option<&'a OsStr>866 fn next(&mut self) -> Option<&'a OsStr> { 867 self.iter.next() 868 } size_hint(&self) -> (usize, Option<usize>)869 fn size_hint(&self) -> (usize, Option<usize>) { 870 self.iter.size_hint() 871 } 872 } 873 874 impl<'a> DoubleEndedIterator for OsValues<'a> { next_back(&mut self) -> Option<&'a OsStr>875 fn next_back(&mut self) -> Option<&'a OsStr> { 876 self.iter.next_back() 877 } 878 } 879 880 impl<'a> ExactSizeIterator for OsValues<'a> {} 881 882 /// Creates an empty iterator. 883 impl<'a> Default for OsValues<'a> { default() -> Self884 fn default() -> Self { 885 static EMPTY: [OsString; 0] = []; 886 // This is never called because the iterator is empty: 887 fn to_str_slice(_: &OsString) -> &OsStr { 888 unreachable!() 889 }; 890 OsValues { 891 iter: EMPTY[..].iter().map(to_str_slice), 892 } 893 } 894 } 895 896 /// An iterator for getting multiple indices out of an argument via the [`ArgMatches::indices_of`] 897 /// method. 898 /// 899 /// # Examples 900 /// 901 /// ```rust 902 /// # use clap::{App, Arg}; 903 /// let m = App::new("myapp") 904 /// .arg(Arg::with_name("output") 905 /// .short("o") 906 /// .multiple(true) 907 /// .takes_value(true)) 908 /// .get_matches_from(vec!["myapp", "-o", "val1", "val2"]); 909 /// 910 /// let mut indices = m.indices_of("output").unwrap(); 911 /// 912 /// assert_eq!(indices.next(), Some(2)); 913 /// assert_eq!(indices.next(), Some(3)); 914 /// assert_eq!(indices.next(), None); 915 /// ``` 916 /// [`ArgMatches::indices_of`]: ./struct.ArgMatches.html#method.indices_of 917 #[derive(Debug, Clone)] 918 pub struct Indices<'a> { 919 // would rather use '_, but: https://github.com/rust-lang/rust/issues/48469 920 iter: Map<Iter<'a, usize>, fn(&'a usize) -> usize>, 921 } 922 923 impl<'a> Iterator for Indices<'a> { 924 type Item = usize; 925 next(&mut self) -> Option<usize>926 fn next(&mut self) -> Option<usize> { 927 self.iter.next() 928 } size_hint(&self) -> (usize, Option<usize>)929 fn size_hint(&self) -> (usize, Option<usize>) { 930 self.iter.size_hint() 931 } 932 } 933 934 impl<'a> DoubleEndedIterator for Indices<'a> { next_back(&mut self) -> Option<usize>935 fn next_back(&mut self) -> Option<usize> { 936 self.iter.next_back() 937 } 938 } 939 940 impl<'a> ExactSizeIterator for Indices<'a> {} 941 942 /// Creates an empty iterator. 943 impl<'a> Default for Indices<'a> { default() -> Self944 fn default() -> Self { 945 static EMPTY: [usize; 0] = []; 946 // This is never called because the iterator is empty: 947 fn to_usize(_: &usize) -> usize { 948 unreachable!() 949 }; 950 Indices { 951 iter: EMPTY[..].iter().map(to_usize), 952 } 953 } 954 } 955 956 #[cfg(test)] 957 mod tests { 958 use super::*; 959 960 #[test] test_default_values()961 fn test_default_values() { 962 let mut values: Values = Values::default(); 963 assert_eq!(values.next(), None); 964 } 965 966 #[test] test_default_values_with_shorter_lifetime()967 fn test_default_values_with_shorter_lifetime() { 968 let matches = ArgMatches::new(); 969 let mut values = matches.values_of("").unwrap_or_default(); 970 assert_eq!(values.next(), None); 971 } 972 973 #[test] test_default_osvalues()974 fn test_default_osvalues() { 975 let mut values: OsValues = OsValues::default(); 976 assert_eq!(values.next(), None); 977 } 978 979 #[test] test_default_osvalues_with_shorter_lifetime()980 fn test_default_osvalues_with_shorter_lifetime() { 981 let matches = ArgMatches::new(); 982 let mut values = matches.values_of_os("").unwrap_or_default(); 983 assert_eq!(values.next(), None); 984 } 985 986 #[test] test_default_indices()987 fn test_default_indices() { 988 let mut indices: Indices = Indices::default(); 989 assert_eq!(indices.next(), None); 990 } 991 992 #[test] test_default_indices_with_shorter_lifetime()993 fn test_default_indices_with_shorter_lifetime() { 994 let matches = ArgMatches::new(); 995 let mut indices = matches.indices_of("").unwrap_or_default(); 996 assert_eq!(indices.next(), None); 997 } 998 } 999