diff --git a/src/app/parser.rs b/src/app/parser.rs index 951a15f085fa..e895eeae4e40 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -1058,7 +1058,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b { where A: AnyArg<'a, 'b> + Display { debugln!("fn=add_val_to_arg;"); let mut ret = None; - for v in val.split(b',') { + for v in val.split(arg.val_delim().unwrap_or(',') as u32 as u8) { debugln!("adding val: {:?}", v); matcher.add_val_to(&*arg.name(), v); diff --git a/src/args/any_arg.rs b/src/args/any_arg.rs index 1ce761cb6e17..6dcfda4baa60 100644 --- a/src/args/any_arg.rs +++ b/src/args/any_arg.rs @@ -19,4 +19,5 @@ pub trait AnyArg<'n, 'e>: Display { fn validator(&self) -> Option<&Rc Result<(), String>>>; fn short(&self) -> Option; fn long(&self) -> Option<&'e str>; + fn val_delim(&self) -> Option; } diff --git a/src/args/arg.rs b/src/args/arg.rs index ef31e4006b8d..e89de2aaa2b1 100644 --- a/src/args/arg.rs +++ b/src/args/arg.rs @@ -90,6 +90,9 @@ pub struct Arg<'a, 'b> where 'a: 'b { pub overrides: Option>, #[doc(hidden)] pub settings: ArgFlags, + // Delimiting character for value separation + #[doc(hidden)] + pub val_delim: Option, } impl<'a, 'b> Default for Arg<'a, 'b> { @@ -111,6 +114,7 @@ impl<'a, 'b> Default for Arg<'a, 'b> { validator: None, overrides: None, settings: ArgFlags::new(), + val_delim: Some(','), } } } @@ -175,6 +179,7 @@ impl<'a, 'b> Arg<'a, 'b> { "max_values" => a.max_values(v.as_i64().unwrap() as u8), "min_values" => a.min_values(v.as_i64().unwrap() as u8), "value_name" => a.value_name(v.as_str().unwrap()), + "value_delimiter" => a.value_delimiter(v.as_str().unwrap()), "value_names" => { for ys in v.as_vec().unwrap() { if let Some(s) = ys.as_str() { @@ -199,10 +204,10 @@ impl<'a, 'b> Arg<'a, 'b> { } a } - "mutually_overrides_with" => { + "overrides_with" => { for ys in v.as_vec().unwrap() { if let Some(s) = ys.as_str() { - a = a.mutually_overrides_with(s); + a = a.overrides_with(s); } } a @@ -430,9 +435,9 @@ impl<'a, 'b> Arg<'a, 'b> { /// ```no_run /// # use clap::{App, Arg}; /// # let myprog = App::new("myprog").arg(Arg::with_name("config") - /// .mutually_overrides_with("debug") + /// .overrides_with("debug") /// # ).get_matches(); - pub fn mutually_overrides_with(mut self, name: &'a str) -> Self { + pub fn overrides_with(mut self, name: &'a str) -> Self { if let Some(ref mut vec) = self.overrides { vec.push(name.as_ref()); } else { @@ -450,9 +455,9 @@ impl<'a, 'b> Arg<'a, 'b> { /// # use clap::{App, Arg}; /// let config_overrides = ["debug", "input"]; /// # let myprog = App::new("myprog").arg(Arg::with_name("config") - /// .mutually_overrides_with_all(&config_overrides) + /// .overrides_with_all(&config_overrides) /// # ).get_matches(); - pub fn mutually_overrides_with_all(mut self, names: &[&'a str]) -> Self { + pub fn overrides_with_all(mut self, names: &[&'a str]) -> Self { if let Some(ref mut vec) = self.overrides { for s in names { vec.push(s); @@ -810,31 +815,57 @@ impl<'a, 'b> Arg<'a, 'b> { self } + /// Specifies the separator to use when values are clumped together, defaults to `,` (comma). + /// + /// **NOTE:** implicitly sets `Arg::takes_value(true)` + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{App, Arg}; + /// let app = App::new("fake") + /// .arg(Arg::with_name("config") + /// .short("c") + /// .long("config") + /// .value_delimiter(";")); + /// + /// let m = app.get_matches_from(vec![ + /// "fake", "--config=val1;val2;val3" + /// ]); + /// + /// assert_eq!(m.values_of("config").unwrap().collect::>(), ["val1", "val2", "val3"]) + /// ``` + pub fn value_delimiter(mut self, d: &str) -> Self { + self = self.set(ArgSettings::TakesValue); + self.val_delim = Some(d.chars() + .nth(0) + .expect("Failed to get value_delimiter from arg")); + self + } + /// Specifies names for values of option arguments. These names are cosmetic only, used for /// help and usage strings only. The names are **not** used to access arguments. The values of /// the arguments are accessed in numeric order (i.e. if you specify two names `one` and `two` /// `one` will be the first matched value, `two` will be the second). /// - /// **NOTE:** This implicitly sets `.number_of_values()` so there is no need to set that, but - /// be aware that the number of "names" you set for the values, will be the *exact* number of - /// values required to satisfy this argument + /// **NOTE:** This implicitly sets `.number_of_values()`, but be aware that the number of + /// "names" you set for the values, will be the *exact* number of values required to satisfy + /// this argument /// - /// **NOTE:** Does *not* require `.multiple(true)` to be set. Setting `.multiple(true)` would - /// allow `-f -f ` where as *not* setting - /// `.multiple(true)` would only allow one occurrence of this argument. + /// **NOTE:** implicitly sets `Arg::takes_value(true)` + /// + /// **NOTE:** Does *not* require or imply `.multiple(true)`. /// /// # Examples /// /// ```no_run /// # use clap::{App, Arg}; - /// let val_names = ["one", "two"]; - /// # let matches = App::new("myprog") - /// # .arg( - /// # Arg::with_name("debug").index(1) - /// // ... - /// .value_names(&val_names) - /// # ).get_matches(); + /// Arg::with_name("speed") + /// .short("s") + /// .value_names(&["fast", "slow"]) + /// # ; pub fn value_names(mut self, names: &[&'b str]) -> Self { + self.setb(ArgSettings::TakesValue); if let Some(ref mut vals) = self.val_names { let mut l = vals.len(); for s in names { @@ -878,20 +909,21 @@ impl<'a, 'b> Arg<'a, 'b> { self } - /// Specifies the name for value of option or positional arguments. This name is cosmetic only, - /// used for help and usage strings. The name is **not** used to access arguments. + /// Specifies the name for value of option or positional arguments inside of help documenation. + /// This name is cosmetic only, the name is **not** used to access arguments. + /// + /// **NOTE:** implicitly sets `Arg::takes_value(true)` /// /// # Examples /// /// ```no_run /// # use clap::{App, Arg}; - /// # let matches = App::new("myprog") - /// # .arg( - /// Arg::with_name("debug") + /// Arg::with_name("input") /// .index(1) - /// .value_name("file") - /// # ).get_matches(); + /// .value_name("FILE") + /// # ; pub fn value_name(mut self, name: &'b str) -> Self { + self.setb(ArgSettings::TakesValue); if let Some(ref mut vals) = self.val_names { let l = vals.len(); vals.insert(l, name); @@ -924,6 +956,7 @@ impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> validator: a.validator.clone(), overrides: a.overrides.clone(), settings: a.settings.clone(), + val_delim: a.val_delim, } } } diff --git a/src/args/arg_builder/flag.rs b/src/args/arg_builder/flag.rs index 18ede14a9d91..6aaedc09f6b7 100644 --- a/src/args/arg_builder/flag.rs +++ b/src/args/arg_builder/flag.rs @@ -10,26 +10,14 @@ use args::AnyArg; use args::settings::{ArgFlags, ArgSettings}; #[derive(Debug)] +#[doc(hidden)] pub struct FlagBuilder<'n, 'e> { pub name: &'n str, - /// The long version of the flag (i.e. word) - /// without the preceding `--` pub long: Option<&'e str>, - /// The string of text that will displayed to - /// the user when the application's `help` - /// text is displayed pub help: Option<&'e str>, - /// A list of names for other arguments that - /// *may not* be used with this flag pub blacklist: Option>, - /// A list of names of other arguments that - /// are *required* to be used when this - /// flag is used pub requires: Option>, - /// The short version (i.e. single character) - /// of the argument, no preceding `-` pub short: Option, - /// A list of names for other arguments that *mutually override* this flag pub overrides: Option>, pub settings: ArgFlags, } @@ -192,6 +180,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> { fn min_vals(&self) -> Option { None } fn short(&self) -> Option { self.short } fn long(&self) -> Option<&'e str> { self.long } + fn val_delim(&self) -> Option { None } } #[cfg(test)] diff --git a/src/args/arg_builder/option.rs b/src/args/arg_builder/option.rs index 963b28036ec5..9b16bec8baca 100644 --- a/src/args/arg_builder/option.rs +++ b/src/args/arg_builder/option.rs @@ -9,30 +9,23 @@ use args::{AnyArg, Arg}; use args::settings::{ArgFlags, ArgSettings}; #[allow(missing_debug_implementations)] +#[doc(hidden)] pub struct OptBuilder<'n, 'e> { pub name: &'n str, - /// The short version (i.e. single character) of the argument, no preceding `-` pub short: Option, - /// The long version of the flag (i.e. word) without the preceding `--` pub long: Option<&'e str>, - /// The string of text that will displayed to the user when the application's - /// `help` text is displayed pub help: Option<&'e str>, - /// A list of names for other arguments that *may not* be used with this flag pub blacklist: Option>, - /// A list of possible values for this argument pub possible_vals: Option>, - /// A list of names of other arguments that are *required* to be used when - /// this flag is used pub requires: Option>, pub num_vals: Option, pub min_vals: Option, pub max_vals: Option, pub val_names: Option>, pub validator: Option StdResult<(), String>>>, - /// A list of names for other arguments that *mutually override* this flag pub overrides: Option>, pub settings: ArgFlags, + pub val_delim: Option, } impl<'n, 'e> Default for OptBuilder<'n, 'e> { @@ -52,6 +45,7 @@ impl<'n, 'e> Default for OptBuilder<'n, 'e> { validator: None, overrides: None, settings: ArgFlags::new(), + val_delim: Some(','), } } } @@ -81,6 +75,7 @@ impl<'n, 'e> OptBuilder<'n, 'e> { min_vals: a.min_vals, max_vals: a.max_vals, val_names: a.val_names.clone(), + val_delim: a.val_delim, ..Default::default() }; if a.is_set(ArgSettings::Multiple) { @@ -253,6 +248,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> { fn min_vals(&self) -> Option { self.min_vals } fn short(&self) -> Option { self.short } fn long(&self) -> Option<&'e str> { self.long } + fn val_delim(&self) -> Option { self.val_delim } } #[cfg(test)] diff --git a/src/args/arg_builder/positional.rs b/src/args/arg_builder/positional.rs index cb684e69a9cd..8c398f046e47 100644 --- a/src/args/arg_builder/positional.rs +++ b/src/args/arg_builder/positional.rs @@ -3,32 +3,29 @@ use std::result::Result as StdResult; use std::rc::Rc; use std::io; +use vec_map::VecMap; + use Arg; use args::AnyArg; use args::settings::{ArgFlags, ArgSettings}; #[allow(missing_debug_implementations)] +#[doc(hidden)] pub struct PosBuilder<'n, 'e> { pub name: &'n str, - /// The string of text that will displayed to the user when the application's - /// `help` text is displayed pub help: Option<&'e str>, - /// A list of names of other arguments that are *required* to be used when - /// this flag is used pub requires: Option>, - /// A list of names for other arguments that *may not* be used with this flag pub blacklist: Option>, - /// A list of possible values for this argument pub possible_vals: Option>, - /// The index of the argument pub index: u8, pub num_vals: Option, pub max_vals: Option, pub min_vals: Option, + pub val_names: Option>, pub validator: Option StdResult<(), String>>>, - /// A list of names for other arguments that *mutually override* this flag pub overrides: Option>, pub settings: ArgFlags, + pub val_delim: Option, } impl<'n, 'e> Default for PosBuilder<'n, 'e> { @@ -41,11 +38,13 @@ impl<'n, 'e> Default for PosBuilder<'n, 'e> { possible_vals: None, index: 0, num_vals: None, - max_vals: None, min_vals: None, + max_vals: None, + val_names: None, validator: None, overrides: None, settings: ArgFlags::new(), + val_delim: Some(','), } } } @@ -66,19 +65,6 @@ impl<'n, 'e> PosBuilder<'n, 'e> { a.name); } - if a.is_set(ArgSettings::TakesValue) { - panic!("Argument \"{}\" has conflicting requirements, both index() and \ - takes_value(true) were supplied\n\n\tArguments with an index automatically \ - take a value, you do not need to specify it manually", - a.name); - } - - if a.val_names.is_some() { - panic!("Positional arguments (\"{}\") do not support named values, instead \ - consider multiple positional arguments", - a.name); - } - // Create the Positional Argument Builder with each HashSet = None to only // allocate // those that require it @@ -88,7 +74,9 @@ impl<'n, 'e> PosBuilder<'n, 'e> { num_vals: a.num_vals, min_vals: a.min_vals, max_vals: a.max_vals, + val_names: a.val_names.clone(), help: a.help, + val_delim: a.val_delim, ..Default::default() }; if a.is_set(ArgSettings::Multiple) || a.num_vals.is_some() || a.max_vals.is_some() || a.min_vals.is_some() { @@ -204,6 +192,7 @@ impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> { fn min_vals(&self) -> Option { self.min_vals } fn short(&self) -> Option { None } fn long(&self) -> Option<&'e str> { None } + fn val_delim(&self) -> Option { self.val_delim } } #[cfg(test)] diff --git a/src/args/arg_matches.rs b/src/args/arg_matches.rs index 43dc922ce285..f8cd15f53f81 100644 --- a/src/args/arg_matches.rs +++ b/src/args/arg_matches.rs @@ -92,27 +92,25 @@ impl<'a> ArgMatches<'a> { #[doc(hidden)] pub fn new() -> Self { ArgMatches { ..Default::default() } } + /// Gets the value of a specific option or positional argument (i.e. an argument that takes + /// an additional value at runtime). If the option wasn't present at runtime + /// it returns `None`. + /// + /// *NOTE:* If getting a value for an option or positional argument that allows multiples, + /// prefer `values_of()` as `value_of()` will only return the _*first*_ value. + /// + /// # Examples + /// + /// ```no_run + /// # use clap::{App, Arg}; + /// let m = App::new("myapp") + /// .arg(Arg::with_name("output") + /// .takes_value(true)) + /// .get_matches_from(vec!["myapp", "something"]); + /// + /// assert_eq!(m.value_of("output"), Some("something")); + /// ``` pub fn value_of>(&self, name: S) -> Option<&str> { - /*! - Gets the value of a specific option or positional argument (i.e. an argument that takes - an additional value at runtime). If the option wasn't present at runtime - it returns `None`. - - *NOTE:* If getting a value for an option or positional argument that allows multiples, - prefer `values_of()` as `value_of()` will only return the _*first*_ value. - - # Examples - - ```no_run - # use clap::{App, Arg}; - let m = App::new("myapp") - .arg(Arg::with_name("output") - .takes_value(true)) - .get_matches_from(vec!["myapp", "something"]); - - assert_eq!(m.value_of("output"), Some("something")); - ``` - */ if let Some(ref arg) = self.args.get(name.as_ref()) { if let Some(v) = arg.vals.values().nth(0) { return Some(v.to_str().expect(INVALID_UTF8)); @@ -121,30 +119,28 @@ impl<'a> ArgMatches<'a> { None } + /// Gets the lossy value of a specific argument If the option wasn't present at runtime + /// it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those + /// invalid points will be replaced with `\u{FFFD}` + /// + /// *NOTE:* If getting a value for an option or positional argument that allows multiples, + /// prefer `lossy_values_of()` as `lossy_value_of()` will only return the _*first*_ value. + /// + /// # Examples + /// + /// ```ignore + /// # use clap::{App, Arg}; + /// use std::ffi::OsString; + /// use std::os::unix::ffi::OsStrExt; + /// + /// let m = App::new("utf8") + /// .arg(Arg::from_usage(" 'some arg'")) + /// .get_matches_from(vec![OsString::from("myprog"), + /// // "Hi {0xe9}!" + /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); + /// assert_eq!(&*m.lossy_value_of("arg").unwrap(), "Hi \u{FFFD}!"); + /// ``` pub fn lossy_value_of>(&'a self, name: S) -> Option> { - /*! - Gets the lossy value of a specific argument If the option wasn't present at runtime - it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those - invalid points will be replaced with `\u{FFFD}` - - *NOTE:* If getting a value for an option or positional argument that allows multiples, - prefer `lossy_values_of()` as `lossy_value_of()` will only return the _*first*_ value. - - # Examples - - ```ignore - # use clap::{App, Arg}; - use std::ffi::OsString; - use std::os::unix::ffi::OsStrExt; - - let m = App::new("utf8") - .arg(Arg::from_usage(" 'some arg'")) - .get_matches_from(vec![OsString::from("myprog"), - // "Hi {0xe9}!" - OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); - assert_eq!(&*m.lossy_value_of("arg").unwrap(), "Hi \u{FFFD}!"); - ``` - */ if let Some(arg) = self.args.get(name.as_ref()) { if let Some(v) = arg.vals.values().nth(0) { return Some(v.to_string_lossy()); @@ -153,35 +149,33 @@ impl<'a> ArgMatches<'a> { None } + /// Gets the OS version of a string value of a specific argument If the option wasn't present at + /// runtime it returns `None`. An OS value on Unix-like systems is any series of bytes, regardless + /// of whether or not they contain valid UTF-8 code points. Since `String`s in Rust are + /// garunteed to be valid UTF-8, a valid filename as an argument value on Linux (for example) may + /// contain invalid UTF-8 code points. This would cause a `panic!` or only the abiltiy to get a + /// lossy version of the file name (i.e. one where the invalid code points were replaced with + /// `\u{FFFD}`). This method returns an `OsString` which allows one to represent those strings + /// which rightfully contain invalid UTF-8. + /// + /// *NOTE:* If getting a value for an option or positional argument that allows multiples, + /// prefer `os_values_of()` as `os_value_of()` will only return the _*first*_ value. + /// + /// # Examples + /// + /// ```ignore + /// # use clap::{App, Arg}; + /// use std::ffi::OsString; + /// use std::os::unix::ffi::OsStrExt; + /// + /// let m = App::new("utf8") + /// .arg(Arg::from_usage(" 'some arg'")) + /// .get_matches_from(vec![OsString::from("myprog"), + /// // "Hi {0xe9}!" + /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); + /// assert_eq!(&*m.os_value_of("arg").unwrap().as_bytes(), &[b'H', b'i', b' ', 0xe9, b'!']); + /// ``` pub fn os_value_of>(&self, name: S) -> Option<&OsStr> { - /*! - Gets the OS version of a string value of a specific argument If the option wasn't present at - runtime it returns `None`. An OS value on Unix-like systems is any series of bytes, regardless - of whether or not they contain valid UTF-8 code points. Since `String`s in Rust are - garunteed to be valid UTF-8, a valid filename as an argument value on Linux (for example) may - contain invalid UTF-8 code points. This would cause a `panic!` or only the abiltiy to get a - lossy version of the file name (i.e. one where the invalid code points were replaced with - `\u{FFFD}`). This method returns an `OsString` which allows one to represent those strings - which rightfully contain invalid UTF-8. - - *NOTE:* If getting a value for an option or positional argument that allows multiples, - prefer `os_values_of()` as `os_value_of()` will only return the _*first*_ value. - - # Examples - - ```ignore - # use clap::{App, Arg}; - use std::ffi::OsString; - use std::os::unix::ffi::OsStrExt; - - let m = App::new("utf8") - .arg(Arg::from_usage(" 'some arg'")) - .get_matches_from(vec![OsString::from("myprog"), - // "Hi {0xe9}!" - OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); - assert_eq!(&*m.os_value_of("arg").unwrap().as_bytes(), &[b'H', b'i', b' ', 0xe9, b'!']); - ``` - */ self.args.get(name.as_ref()).map_or(None, |arg| arg.vals.values().nth(0).map(|v| v.as_os_str())) } @@ -213,30 +207,28 @@ impl<'a> ArgMatches<'a> { None } + /// Gets the lossy values of a specific argument If the option wasn't present at runtime + /// it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those + /// invalid points will be replaced with `\u{FFFD}` + /// + /// # Examples + /// + /// ```ignore + /// # use clap::{App, Arg}; + /// use std::ffi::OsString; + /// use std::os::unix::ffi::OsStrExt; + /// + /// let m = App::new("utf8") + /// .arg(Arg::from_usage(" 'some arg'")) + /// .get_matches_from(vec![OsString::from("myprog"), + /// // "Hi {0xe9}!" + /// OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); + /// let itr = m.lossy_values_of("arg").unwrap(); + /// assert_eq!(&*itr.next().unwrap(), "Hi"); + /// assert_eq!(&*itr.next().unwrap(), "\u{FFFD}!"); + /// assert_eq!(itr.next(), None); + /// ``` pub fn lossy_values_of>(&'a self, name: S) -> Option> { - /*! - Gets the lossy values of a specific argument If the option wasn't present at runtime - it returns `None`. A lossy value is one which contains invalid UTF-8 code points, those - invalid points will be replaced with `\u{FFFD}` - - # Examples - - ```ignore - # use clap::{App, Arg}; - use std::ffi::OsString; - use std::os::unix::ffi::OsStrExt; - - let m = App::new("utf8") - .arg(Arg::from_usage(" 'some arg'")) - .get_matches_from(vec![OsString::from("myprog"), - // "Hi {0xe9}!" - OsString::from_vec(vec![b'H', b'i', b' ', 0xe9, b'!'])]); - let itr = m.lossy_values_of("arg").unwrap(); - assert_eq!(&*itr.next().unwrap(), "Hi"); - assert_eq!(&*itr.next().unwrap(), "\u{FFFD}!"); - assert_eq!(itr.next(), None); - ``` - */ if let Some(ref arg) = self.args.get(name.as_ref()) { return Some(arg.vals.values() .map(|v| v.to_string_lossy().into_owned()) @@ -245,38 +237,36 @@ impl<'a> ArgMatches<'a> { None } + /// Gets the OS version of a string value of a specific argument If the option wasn't present + /// at runtime it returns `None`. An OS value on Unix-like systems is any series of bytes, + /// regardless of whether or not they contain valid UTF-8 code points. Since `String`s in Rust + /// are garunteed to be valid UTF-8, a valid filename as an argument value on Linux (for + /// example) may contain invalid UTF-8 code points. This would cause a `panic!` or only the + /// abiltiy to get a lossy version of the file name (i.e. one where the invalid code points + /// were replaced with `\u{FFFD}`). This method returns an `OsString` which allows one to + /// represent those strings which rightfully contain invalid UTF-8. + /// + /// # Examples + /// + /// ```ignore + /// # use clap::{App, Arg}; + /// use std::ffi::OsString; + /// use std::os::unix::ffi::OsStrExt; + /// + /// let m = App::new("utf8") + /// .arg(Arg::from_usage(" 'some arg'")) + /// .get_matches_from(vec![OsString::from("myprog"), + /// // "Hi" + /// OsString::from_vec(vec![b'H', b'i']), + /// // "{0xe9}!" + /// OsString::from_vec(vec![0xe9, b'!'])]); + /// + /// let itr = m.os_values_of("arg").unwrap(); + /// assert_eq!(itr.next(), Some(&*OsString::from("Hi"))); + /// assert_eq!(itr.next(), Some(&*OsString::from_vec(vec![0xe9, b'!']))); + /// assert_eq!(itr.next(), None); + /// ``` pub fn os_values_of>(&'a self, name: S) -> Option> { - /*! - Gets the OS version of a string value of a specific argument If the option wasn't present at - runtime it returns `None`. An OS value on Unix-like systems is any series of bytes, regardless - of whether or not they contain valid UTF-8 code points. Since `String`s in Rust are - garunteed to be valid UTF-8, a valid filename as an argument value on Linux (for example) may - contain invalid UTF-8 code points. This would cause a `panic!` or only the abiltiy to get a - lossy version of the file name (i.e. one where the invalid code points were replaced with - `\u{FFFD}`). This method returns an `OsString` which allows one to represent those strings - which rightfully contain invalid UTF-8. - - # Examples - - ```ignore - # use clap::{App, Arg}; - use std::ffi::OsString; - use std::os::unix::ffi::OsStrExt; - - let m = App::new("utf8") - .arg(Arg::from_usage(" 'some arg'")) - .get_matches_from(vec![OsString::from("myprog"), - // "Hi" - OsString::from_vec(vec![b'H', b'i']), - // "{0xe9}!" - OsString::from_vec(vec![0xe9, b'!'])]); - - let itr = m.os_values_of("arg").unwrap(); - assert_eq!(itr.next(), Some(&*OsString::from("Hi"))); - assert_eq!(itr.next(), Some(&*OsString::from_vec(vec![0xe9, b'!']))); - assert_eq!(itr.next(), None); - ``` - */ fn to_str_slice(o: &OsString) -> &OsStr { &*o } let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer if let Some(ref arg) = self.args.get(name.as_ref()) {