119625d8cSopenharmony_ciuse std::convert::TryInto; 219625d8cSopenharmony_ciuse std::ops::RangeBounds; 319625d8cSopenharmony_ci 419625d8cSopenharmony_ciuse crate::parser::AnyValue; 519625d8cSopenharmony_ciuse crate::parser::AnyValueId; 619625d8cSopenharmony_ci 719625d8cSopenharmony_ci/// Parse/validate argument values 819625d8cSopenharmony_ci/// 919625d8cSopenharmony_ci/// Specified with [`Arg::value_parser`][crate::Arg::value_parser]. 1019625d8cSopenharmony_ci/// 1119625d8cSopenharmony_ci/// `ValueParser` defines how to convert a raw argument value into a validated and typed value for 1219625d8cSopenharmony_ci/// use within an application. 1319625d8cSopenharmony_ci/// 1419625d8cSopenharmony_ci/// See 1519625d8cSopenharmony_ci/// - [`value_parser!`][crate::value_parser] for automatically selecting an implementation for a given type 1619625d8cSopenharmony_ci/// - [`ValueParser::new`] for additional [`TypedValueParser`] that can be used 1719625d8cSopenharmony_ci/// 1819625d8cSopenharmony_ci/// # Example 1919625d8cSopenharmony_ci/// 2019625d8cSopenharmony_ci/// ```rust 2119625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 2219625d8cSopenharmony_ci/// .arg( 2319625d8cSopenharmony_ci/// clap::Arg::new("color") 2419625d8cSopenharmony_ci/// .long("color") 2519625d8cSopenharmony_ci/// .value_parser(["always", "auto", "never"]) 2619625d8cSopenharmony_ci/// .default_value("auto") 2719625d8cSopenharmony_ci/// ) 2819625d8cSopenharmony_ci/// .arg( 2919625d8cSopenharmony_ci/// clap::Arg::new("hostname") 3019625d8cSopenharmony_ci/// .long("hostname") 3119625d8cSopenharmony_ci/// .value_parser(clap::builder::NonEmptyStringValueParser::new()) 3219625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 3319625d8cSopenharmony_ci/// .required(true) 3419625d8cSopenharmony_ci/// ) 3519625d8cSopenharmony_ci/// .arg( 3619625d8cSopenharmony_ci/// clap::Arg::new("port") 3719625d8cSopenharmony_ci/// .long("port") 3819625d8cSopenharmony_ci/// .value_parser(clap::value_parser!(u16).range(3000..)) 3919625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 4019625d8cSopenharmony_ci/// .required(true) 4119625d8cSopenharmony_ci/// ); 4219625d8cSopenharmony_ci/// 4319625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut( 4419625d8cSopenharmony_ci/// ["cmd", "--hostname", "rust-lang.org", "--port", "3001"] 4519625d8cSopenharmony_ci/// ).unwrap(); 4619625d8cSopenharmony_ci/// 4719625d8cSopenharmony_ci/// let color: &String = m.get_one("color") 4819625d8cSopenharmony_ci/// .expect("default"); 4919625d8cSopenharmony_ci/// assert_eq!(color, "auto"); 5019625d8cSopenharmony_ci/// 5119625d8cSopenharmony_ci/// let hostname: &String = m.get_one("hostname") 5219625d8cSopenharmony_ci/// .expect("required"); 5319625d8cSopenharmony_ci/// assert_eq!(hostname, "rust-lang.org"); 5419625d8cSopenharmony_ci/// 5519625d8cSopenharmony_ci/// let port: u16 = *m.get_one("port") 5619625d8cSopenharmony_ci/// .expect("required"); 5719625d8cSopenharmony_ci/// assert_eq!(port, 3001); 5819625d8cSopenharmony_ci/// ``` 5919625d8cSopenharmony_cipub struct ValueParser(ValueParserInner); 6019625d8cSopenharmony_ci 6119625d8cSopenharmony_cienum ValueParserInner { 6219625d8cSopenharmony_ci // Common enough to optimize and for possible values 6319625d8cSopenharmony_ci Bool, 6419625d8cSopenharmony_ci // Common enough to optimize 6519625d8cSopenharmony_ci String, 6619625d8cSopenharmony_ci // Common enough to optimize 6719625d8cSopenharmony_ci OsString, 6819625d8cSopenharmony_ci // Common enough to optimize 6919625d8cSopenharmony_ci PathBuf, 7019625d8cSopenharmony_ci Other(Box<dyn AnyValueParser>), 7119625d8cSopenharmony_ci} 7219625d8cSopenharmony_ci 7319625d8cSopenharmony_ciimpl ValueParser { 7419625d8cSopenharmony_ci /// Custom parser for argument values 7519625d8cSopenharmony_ci /// 7619625d8cSopenharmony_ci /// Pre-existing [`TypedValueParser`] implementations include: 7719625d8cSopenharmony_ci /// - `Fn(&str) -> Result<T, E>` 7819625d8cSopenharmony_ci /// - [`EnumValueParser`] and [`PossibleValuesParser`] for static enumerated values 7919625d8cSopenharmony_ci /// - [`BoolishValueParser`] and [`FalseyValueParser`] for alternative `bool` implementations 8019625d8cSopenharmony_ci /// - [`RangedI64ValueParser`] and [`RangedU64ValueParser`] 8119625d8cSopenharmony_ci /// - [`NonEmptyStringValueParser`] 8219625d8cSopenharmony_ci /// 8319625d8cSopenharmony_ci /// # Example 8419625d8cSopenharmony_ci /// 8519625d8cSopenharmony_ci /// ```rust 8619625d8cSopenharmony_ci /// type EnvVar = (String, Option<String>); 8719625d8cSopenharmony_ci /// fn parse_env_var(env: &str) -> Result<EnvVar, std::io::Error> { 8819625d8cSopenharmony_ci /// if let Some((var, value)) = env.split_once('=') { 8919625d8cSopenharmony_ci /// Ok((var.to_owned(), Some(value.to_owned()))) 9019625d8cSopenharmony_ci /// } else { 9119625d8cSopenharmony_ci /// Ok((env.to_owned(), None)) 9219625d8cSopenharmony_ci /// } 9319625d8cSopenharmony_ci /// } 9419625d8cSopenharmony_ci /// 9519625d8cSopenharmony_ci /// let mut cmd = clap::Command::new("raw") 9619625d8cSopenharmony_ci /// .arg( 9719625d8cSopenharmony_ci /// clap::Arg::new("env") 9819625d8cSopenharmony_ci /// .value_parser(clap::builder::ValueParser::new(parse_env_var)) 9919625d8cSopenharmony_ci /// .required(true) 10019625d8cSopenharmony_ci /// ); 10119625d8cSopenharmony_ci /// 10219625d8cSopenharmony_ci /// let m = cmd.try_get_matches_from_mut(["cmd", "key=value"]).unwrap(); 10319625d8cSopenharmony_ci /// let port: &EnvVar = m.get_one("env") 10419625d8cSopenharmony_ci /// .expect("required"); 10519625d8cSopenharmony_ci /// assert_eq!(*port, ("key".into(), Some("value".into()))); 10619625d8cSopenharmony_ci /// ``` 10719625d8cSopenharmony_ci pub fn new<P>(other: P) -> Self 10819625d8cSopenharmony_ci where 10919625d8cSopenharmony_ci P: TypedValueParser, 11019625d8cSopenharmony_ci { 11119625d8cSopenharmony_ci Self(ValueParserInner::Other(Box::new(other))) 11219625d8cSopenharmony_ci } 11319625d8cSopenharmony_ci 11419625d8cSopenharmony_ci /// [`bool`] parser for argument values 11519625d8cSopenharmony_ci /// 11619625d8cSopenharmony_ci /// See also: 11719625d8cSopenharmony_ci /// - [`BoolishValueParser`] for different human readable bool representations 11819625d8cSopenharmony_ci /// - [`FalseyValueParser`] for assuming non-false is true 11919625d8cSopenharmony_ci /// 12019625d8cSopenharmony_ci /// # Example 12119625d8cSopenharmony_ci /// 12219625d8cSopenharmony_ci /// ```rust 12319625d8cSopenharmony_ci /// let mut cmd = clap::Command::new("raw") 12419625d8cSopenharmony_ci /// .arg( 12519625d8cSopenharmony_ci /// clap::Arg::new("download") 12619625d8cSopenharmony_ci /// .value_parser(clap::value_parser!(bool)) 12719625d8cSopenharmony_ci /// .required(true) 12819625d8cSopenharmony_ci /// ); 12919625d8cSopenharmony_ci /// 13019625d8cSopenharmony_ci /// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap(); 13119625d8cSopenharmony_ci /// let port: bool = *m.get_one("download") 13219625d8cSopenharmony_ci /// .expect("required"); 13319625d8cSopenharmony_ci /// assert_eq!(port, true); 13419625d8cSopenharmony_ci /// 13519625d8cSopenharmony_ci /// assert!(cmd.try_get_matches_from_mut(["cmd", "forever"]).is_err()); 13619625d8cSopenharmony_ci /// ``` 13719625d8cSopenharmony_ci pub const fn bool() -> Self { 13819625d8cSopenharmony_ci Self(ValueParserInner::Bool) 13919625d8cSopenharmony_ci } 14019625d8cSopenharmony_ci 14119625d8cSopenharmony_ci /// [`String`] parser for argument values 14219625d8cSopenharmony_ci /// 14319625d8cSopenharmony_ci /// See also: 14419625d8cSopenharmony_ci /// - [`NonEmptyStringValueParser`] 14519625d8cSopenharmony_ci /// 14619625d8cSopenharmony_ci /// # Example 14719625d8cSopenharmony_ci /// 14819625d8cSopenharmony_ci /// ```rust 14919625d8cSopenharmony_ci /// let mut cmd = clap::Command::new("raw") 15019625d8cSopenharmony_ci /// .arg( 15119625d8cSopenharmony_ci /// clap::Arg::new("port") 15219625d8cSopenharmony_ci /// .value_parser(clap::value_parser!(String)) 15319625d8cSopenharmony_ci /// .required(true) 15419625d8cSopenharmony_ci /// ); 15519625d8cSopenharmony_ci /// 15619625d8cSopenharmony_ci /// let m = cmd.try_get_matches_from_mut(["cmd", "80"]).unwrap(); 15719625d8cSopenharmony_ci /// let port: &String = m.get_one("port") 15819625d8cSopenharmony_ci /// .expect("required"); 15919625d8cSopenharmony_ci /// assert_eq!(port, "80"); 16019625d8cSopenharmony_ci /// ``` 16119625d8cSopenharmony_ci pub const fn string() -> Self { 16219625d8cSopenharmony_ci Self(ValueParserInner::String) 16319625d8cSopenharmony_ci } 16419625d8cSopenharmony_ci 16519625d8cSopenharmony_ci /// [`OsString`][std::ffi::OsString] parser for argument values 16619625d8cSopenharmony_ci /// 16719625d8cSopenharmony_ci /// # Example 16819625d8cSopenharmony_ci /// 16919625d8cSopenharmony_ci #[cfg_attr(not(unix), doc = " ```ignore")] 17019625d8cSopenharmony_ci #[cfg_attr(unix, doc = " ```rust")] 17119625d8cSopenharmony_ci /// # use clap::{Command, Arg, builder::ValueParser}; 17219625d8cSopenharmony_ci /// use std::ffi::OsString; 17319625d8cSopenharmony_ci /// use std::os::unix::ffi::{OsStrExt,OsStringExt}; 17419625d8cSopenharmony_ci /// let r = Command::new("myprog") 17519625d8cSopenharmony_ci /// .arg( 17619625d8cSopenharmony_ci /// Arg::new("arg") 17719625d8cSopenharmony_ci /// .required(true) 17819625d8cSopenharmony_ci /// .value_parser(ValueParser::os_string()) 17919625d8cSopenharmony_ci /// ) 18019625d8cSopenharmony_ci /// .try_get_matches_from(vec![ 18119625d8cSopenharmony_ci /// OsString::from("myprog"), 18219625d8cSopenharmony_ci /// OsString::from_vec(vec![0xe9]) 18319625d8cSopenharmony_ci /// ]); 18419625d8cSopenharmony_ci /// 18519625d8cSopenharmony_ci /// assert!(r.is_ok()); 18619625d8cSopenharmony_ci /// let m = r.unwrap(); 18719625d8cSopenharmony_ci /// let arg: &OsString = m.get_one("arg") 18819625d8cSopenharmony_ci /// .expect("required"); 18919625d8cSopenharmony_ci /// assert_eq!(arg.as_bytes(), &[0xe9]); 19019625d8cSopenharmony_ci /// ``` 19119625d8cSopenharmony_ci pub const fn os_string() -> Self { 19219625d8cSopenharmony_ci Self(ValueParserInner::OsString) 19319625d8cSopenharmony_ci } 19419625d8cSopenharmony_ci 19519625d8cSopenharmony_ci /// [`PathBuf`][std::path::PathBuf] parser for argument values 19619625d8cSopenharmony_ci /// 19719625d8cSopenharmony_ci /// # Example 19819625d8cSopenharmony_ci /// 19919625d8cSopenharmony_ci /// ```rust 20019625d8cSopenharmony_ci /// # use std::path::PathBuf; 20119625d8cSopenharmony_ci /// # use std::path::Path; 20219625d8cSopenharmony_ci /// let mut cmd = clap::Command::new("raw") 20319625d8cSopenharmony_ci /// .arg( 20419625d8cSopenharmony_ci /// clap::Arg::new("output") 20519625d8cSopenharmony_ci /// .value_parser(clap::value_parser!(PathBuf)) 20619625d8cSopenharmony_ci /// .required(true) 20719625d8cSopenharmony_ci /// ); 20819625d8cSopenharmony_ci /// 20919625d8cSopenharmony_ci /// let m = cmd.try_get_matches_from_mut(["cmd", "hello.txt"]).unwrap(); 21019625d8cSopenharmony_ci /// let port: &PathBuf = m.get_one("output") 21119625d8cSopenharmony_ci /// .expect("required"); 21219625d8cSopenharmony_ci /// assert_eq!(port, Path::new("hello.txt")); 21319625d8cSopenharmony_ci /// 21419625d8cSopenharmony_ci /// assert!(cmd.try_get_matches_from_mut(["cmd", ""]).is_err()); 21519625d8cSopenharmony_ci /// ``` 21619625d8cSopenharmony_ci pub const fn path_buf() -> Self { 21719625d8cSopenharmony_ci Self(ValueParserInner::PathBuf) 21819625d8cSopenharmony_ci } 21919625d8cSopenharmony_ci} 22019625d8cSopenharmony_ci 22119625d8cSopenharmony_ciimpl ValueParser { 22219625d8cSopenharmony_ci /// Parse into a `AnyValue` 22319625d8cSopenharmony_ci /// 22419625d8cSopenharmony_ci /// When `arg` is `None`, an external subcommand value is being parsed. 22519625d8cSopenharmony_ci pub(crate) fn parse_ref( 22619625d8cSopenharmony_ci &self, 22719625d8cSopenharmony_ci cmd: &crate::Command, 22819625d8cSopenharmony_ci arg: Option<&crate::Arg>, 22919625d8cSopenharmony_ci value: &std::ffi::OsStr, 23019625d8cSopenharmony_ci ) -> Result<AnyValue, crate::Error> { 23119625d8cSopenharmony_ci self.any_value_parser().parse_ref(cmd, arg, value) 23219625d8cSopenharmony_ci } 23319625d8cSopenharmony_ci 23419625d8cSopenharmony_ci /// Describes the content of `AnyValue` 23519625d8cSopenharmony_ci pub fn type_id(&self) -> AnyValueId { 23619625d8cSopenharmony_ci self.any_value_parser().type_id() 23719625d8cSopenharmony_ci } 23819625d8cSopenharmony_ci 23919625d8cSopenharmony_ci /// Reflect on enumerated value properties 24019625d8cSopenharmony_ci /// 24119625d8cSopenharmony_ci /// Error checking should not be done with this; it is mostly targeted at user-facing 24219625d8cSopenharmony_ci /// applications like errors and completion. 24319625d8cSopenharmony_ci pub fn possible_values( 24419625d8cSopenharmony_ci &self, 24519625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 24619625d8cSopenharmony_ci self.any_value_parser().possible_values() 24719625d8cSopenharmony_ci } 24819625d8cSopenharmony_ci 24919625d8cSopenharmony_ci fn any_value_parser(&self) -> &dyn AnyValueParser { 25019625d8cSopenharmony_ci match &self.0 { 25119625d8cSopenharmony_ci ValueParserInner::Bool => &BoolValueParser {}, 25219625d8cSopenharmony_ci ValueParserInner::String => &StringValueParser {}, 25319625d8cSopenharmony_ci ValueParserInner::OsString => &OsStringValueParser {}, 25419625d8cSopenharmony_ci ValueParserInner::PathBuf => &PathBufValueParser {}, 25519625d8cSopenharmony_ci ValueParserInner::Other(o) => o.as_ref(), 25619625d8cSopenharmony_ci } 25719625d8cSopenharmony_ci } 25819625d8cSopenharmony_ci} 25919625d8cSopenharmony_ci 26019625d8cSopenharmony_ci/// Convert a [`TypedValueParser`] to [`ValueParser`] 26119625d8cSopenharmony_ci/// 26219625d8cSopenharmony_ci/// # Example 26319625d8cSopenharmony_ci/// 26419625d8cSopenharmony_ci/// ```rust 26519625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 26619625d8cSopenharmony_ci/// .arg( 26719625d8cSopenharmony_ci/// clap::Arg::new("hostname") 26819625d8cSopenharmony_ci/// .long("hostname") 26919625d8cSopenharmony_ci/// .value_parser(clap::builder::NonEmptyStringValueParser::new()) 27019625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 27119625d8cSopenharmony_ci/// .required(true) 27219625d8cSopenharmony_ci/// ); 27319625d8cSopenharmony_ci/// 27419625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut( 27519625d8cSopenharmony_ci/// ["cmd", "--hostname", "rust-lang.org"] 27619625d8cSopenharmony_ci/// ).unwrap(); 27719625d8cSopenharmony_ci/// 27819625d8cSopenharmony_ci/// let hostname: &String = m.get_one("hostname") 27919625d8cSopenharmony_ci/// .expect("required"); 28019625d8cSopenharmony_ci/// assert_eq!(hostname, "rust-lang.org"); 28119625d8cSopenharmony_ci/// ``` 28219625d8cSopenharmony_ciimpl<P> From<P> for ValueParser 28319625d8cSopenharmony_ciwhere 28419625d8cSopenharmony_ci P: TypedValueParser + Send + Sync + 'static, 28519625d8cSopenharmony_ci{ 28619625d8cSopenharmony_ci fn from(p: P) -> Self { 28719625d8cSopenharmony_ci Self::new(p) 28819625d8cSopenharmony_ci } 28919625d8cSopenharmony_ci} 29019625d8cSopenharmony_ci 29119625d8cSopenharmony_ciimpl From<_AnonymousValueParser> for ValueParser { 29219625d8cSopenharmony_ci fn from(p: _AnonymousValueParser) -> Self { 29319625d8cSopenharmony_ci p.0 29419625d8cSopenharmony_ci } 29519625d8cSopenharmony_ci} 29619625d8cSopenharmony_ci 29719625d8cSopenharmony_ci/// Create an `i64` [`ValueParser`] from a `N..M` range 29819625d8cSopenharmony_ci/// 29919625d8cSopenharmony_ci/// See [`RangedI64ValueParser`] for more control over the output type. 30019625d8cSopenharmony_ci/// 30119625d8cSopenharmony_ci/// See also [`RangedU64ValueParser`] 30219625d8cSopenharmony_ci/// 30319625d8cSopenharmony_ci/// # Examples 30419625d8cSopenharmony_ci/// 30519625d8cSopenharmony_ci/// ```rust 30619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 30719625d8cSopenharmony_ci/// .arg( 30819625d8cSopenharmony_ci/// clap::Arg::new("port") 30919625d8cSopenharmony_ci/// .long("port") 31019625d8cSopenharmony_ci/// .value_parser(3000..4000) 31119625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 31219625d8cSopenharmony_ci/// .required(true) 31319625d8cSopenharmony_ci/// ); 31419625d8cSopenharmony_ci/// 31519625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap(); 31619625d8cSopenharmony_ci/// let port: i64 = *m.get_one("port") 31719625d8cSopenharmony_ci/// .expect("required"); 31819625d8cSopenharmony_ci/// assert_eq!(port, 3001); 31919625d8cSopenharmony_ci/// ``` 32019625d8cSopenharmony_ciimpl From<std::ops::Range<i64>> for ValueParser { 32119625d8cSopenharmony_ci fn from(value: std::ops::Range<i64>) -> Self { 32219625d8cSopenharmony_ci let inner = RangedI64ValueParser::<i64>::new().range(value.start..value.end); 32319625d8cSopenharmony_ci Self::from(inner) 32419625d8cSopenharmony_ci } 32519625d8cSopenharmony_ci} 32619625d8cSopenharmony_ci 32719625d8cSopenharmony_ci/// Create an `i64` [`ValueParser`] from a `N..=M` range 32819625d8cSopenharmony_ci/// 32919625d8cSopenharmony_ci/// See [`RangedI64ValueParser`] for more control over the output type. 33019625d8cSopenharmony_ci/// 33119625d8cSopenharmony_ci/// See also [`RangedU64ValueParser`] 33219625d8cSopenharmony_ci/// 33319625d8cSopenharmony_ci/// # Examples 33419625d8cSopenharmony_ci/// 33519625d8cSopenharmony_ci/// ```rust 33619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 33719625d8cSopenharmony_ci/// .arg( 33819625d8cSopenharmony_ci/// clap::Arg::new("port") 33919625d8cSopenharmony_ci/// .long("port") 34019625d8cSopenharmony_ci/// .value_parser(3000..=4000) 34119625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 34219625d8cSopenharmony_ci/// .required(true) 34319625d8cSopenharmony_ci/// ); 34419625d8cSopenharmony_ci/// 34519625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap(); 34619625d8cSopenharmony_ci/// let port: i64 = *m.get_one("port") 34719625d8cSopenharmony_ci/// .expect("required"); 34819625d8cSopenharmony_ci/// assert_eq!(port, 3001); 34919625d8cSopenharmony_ci/// ``` 35019625d8cSopenharmony_ciimpl From<std::ops::RangeInclusive<i64>> for ValueParser { 35119625d8cSopenharmony_ci fn from(value: std::ops::RangeInclusive<i64>) -> Self { 35219625d8cSopenharmony_ci let inner = RangedI64ValueParser::<i64>::new().range(value.start()..=value.end()); 35319625d8cSopenharmony_ci Self::from(inner) 35419625d8cSopenharmony_ci } 35519625d8cSopenharmony_ci} 35619625d8cSopenharmony_ci 35719625d8cSopenharmony_ci/// Create an `i64` [`ValueParser`] from a `N..` range 35819625d8cSopenharmony_ci/// 35919625d8cSopenharmony_ci/// See [`RangedI64ValueParser`] for more control over the output type. 36019625d8cSopenharmony_ci/// 36119625d8cSopenharmony_ci/// See also [`RangedU64ValueParser`] 36219625d8cSopenharmony_ci/// 36319625d8cSopenharmony_ci/// # Examples 36419625d8cSopenharmony_ci/// 36519625d8cSopenharmony_ci/// ```rust 36619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 36719625d8cSopenharmony_ci/// .arg( 36819625d8cSopenharmony_ci/// clap::Arg::new("port") 36919625d8cSopenharmony_ci/// .long("port") 37019625d8cSopenharmony_ci/// .value_parser(3000..) 37119625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 37219625d8cSopenharmony_ci/// .required(true) 37319625d8cSopenharmony_ci/// ); 37419625d8cSopenharmony_ci/// 37519625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap(); 37619625d8cSopenharmony_ci/// let port: i64 = *m.get_one("port") 37719625d8cSopenharmony_ci/// .expect("required"); 37819625d8cSopenharmony_ci/// assert_eq!(port, 3001); 37919625d8cSopenharmony_ci/// ``` 38019625d8cSopenharmony_ciimpl From<std::ops::RangeFrom<i64>> for ValueParser { 38119625d8cSopenharmony_ci fn from(value: std::ops::RangeFrom<i64>) -> Self { 38219625d8cSopenharmony_ci let inner = RangedI64ValueParser::<i64>::new().range(value.start..); 38319625d8cSopenharmony_ci Self::from(inner) 38419625d8cSopenharmony_ci } 38519625d8cSopenharmony_ci} 38619625d8cSopenharmony_ci 38719625d8cSopenharmony_ci/// Create an `i64` [`ValueParser`] from a `..M` range 38819625d8cSopenharmony_ci/// 38919625d8cSopenharmony_ci/// See [`RangedI64ValueParser`] for more control over the output type. 39019625d8cSopenharmony_ci/// 39119625d8cSopenharmony_ci/// See also [`RangedU64ValueParser`] 39219625d8cSopenharmony_ci/// 39319625d8cSopenharmony_ci/// # Examples 39419625d8cSopenharmony_ci/// 39519625d8cSopenharmony_ci/// ```rust 39619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 39719625d8cSopenharmony_ci/// .arg( 39819625d8cSopenharmony_ci/// clap::Arg::new("port") 39919625d8cSopenharmony_ci/// .long("port") 40019625d8cSopenharmony_ci/// .value_parser(..3000) 40119625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 40219625d8cSopenharmony_ci/// .required(true) 40319625d8cSopenharmony_ci/// ); 40419625d8cSopenharmony_ci/// 40519625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "80"]).unwrap(); 40619625d8cSopenharmony_ci/// let port: i64 = *m.get_one("port") 40719625d8cSopenharmony_ci/// .expect("required"); 40819625d8cSopenharmony_ci/// assert_eq!(port, 80); 40919625d8cSopenharmony_ci/// ``` 41019625d8cSopenharmony_ciimpl From<std::ops::RangeTo<i64>> for ValueParser { 41119625d8cSopenharmony_ci fn from(value: std::ops::RangeTo<i64>) -> Self { 41219625d8cSopenharmony_ci let inner = RangedI64ValueParser::<i64>::new().range(..value.end); 41319625d8cSopenharmony_ci Self::from(inner) 41419625d8cSopenharmony_ci } 41519625d8cSopenharmony_ci} 41619625d8cSopenharmony_ci 41719625d8cSopenharmony_ci/// Create an `i64` [`ValueParser`] from a `..=M` range 41819625d8cSopenharmony_ci/// 41919625d8cSopenharmony_ci/// See [`RangedI64ValueParser`] for more control over the output type. 42019625d8cSopenharmony_ci/// 42119625d8cSopenharmony_ci/// See also [`RangedU64ValueParser`] 42219625d8cSopenharmony_ci/// 42319625d8cSopenharmony_ci/// # Examples 42419625d8cSopenharmony_ci/// 42519625d8cSopenharmony_ci/// ```rust 42619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 42719625d8cSopenharmony_ci/// .arg( 42819625d8cSopenharmony_ci/// clap::Arg::new("port") 42919625d8cSopenharmony_ci/// .long("port") 43019625d8cSopenharmony_ci/// .value_parser(..=3000) 43119625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 43219625d8cSopenharmony_ci/// .required(true) 43319625d8cSopenharmony_ci/// ); 43419625d8cSopenharmony_ci/// 43519625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "80"]).unwrap(); 43619625d8cSopenharmony_ci/// let port: i64 = *m.get_one("port") 43719625d8cSopenharmony_ci/// .expect("required"); 43819625d8cSopenharmony_ci/// assert_eq!(port, 80); 43919625d8cSopenharmony_ci/// ``` 44019625d8cSopenharmony_ciimpl From<std::ops::RangeToInclusive<i64>> for ValueParser { 44119625d8cSopenharmony_ci fn from(value: std::ops::RangeToInclusive<i64>) -> Self { 44219625d8cSopenharmony_ci let inner = RangedI64ValueParser::<i64>::new().range(..=value.end); 44319625d8cSopenharmony_ci Self::from(inner) 44419625d8cSopenharmony_ci } 44519625d8cSopenharmony_ci} 44619625d8cSopenharmony_ci 44719625d8cSopenharmony_ci/// Create an `i64` [`ValueParser`] from a `..` range 44819625d8cSopenharmony_ci/// 44919625d8cSopenharmony_ci/// See [`RangedI64ValueParser`] for more control over the output type. 45019625d8cSopenharmony_ci/// 45119625d8cSopenharmony_ci/// See also [`RangedU64ValueParser`] 45219625d8cSopenharmony_ci/// 45319625d8cSopenharmony_ci/// # Examples 45419625d8cSopenharmony_ci/// 45519625d8cSopenharmony_ci/// ```rust 45619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 45719625d8cSopenharmony_ci/// .arg( 45819625d8cSopenharmony_ci/// clap::Arg::new("port") 45919625d8cSopenharmony_ci/// .long("port") 46019625d8cSopenharmony_ci/// .value_parser(..) 46119625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 46219625d8cSopenharmony_ci/// .required(true) 46319625d8cSopenharmony_ci/// ); 46419625d8cSopenharmony_ci/// 46519625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap(); 46619625d8cSopenharmony_ci/// let port: i64 = *m.get_one("port") 46719625d8cSopenharmony_ci/// .expect("required"); 46819625d8cSopenharmony_ci/// assert_eq!(port, 3001); 46919625d8cSopenharmony_ci/// ``` 47019625d8cSopenharmony_ciimpl From<std::ops::RangeFull> for ValueParser { 47119625d8cSopenharmony_ci fn from(value: std::ops::RangeFull) -> Self { 47219625d8cSopenharmony_ci let inner = RangedI64ValueParser::<i64>::new().range(value); 47319625d8cSopenharmony_ci Self::from(inner) 47419625d8cSopenharmony_ci } 47519625d8cSopenharmony_ci} 47619625d8cSopenharmony_ci 47719625d8cSopenharmony_ci/// Create a [`ValueParser`] with [`PossibleValuesParser`] 47819625d8cSopenharmony_ci/// 47919625d8cSopenharmony_ci/// See [`PossibleValuesParser`] for more flexibility in creating the 48019625d8cSopenharmony_ci/// [`PossibleValue`][crate::builder::PossibleValue]s. 48119625d8cSopenharmony_ci/// 48219625d8cSopenharmony_ci/// # Examples 48319625d8cSopenharmony_ci/// 48419625d8cSopenharmony_ci/// ```rust 48519625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 48619625d8cSopenharmony_ci/// .arg( 48719625d8cSopenharmony_ci/// clap::Arg::new("color") 48819625d8cSopenharmony_ci/// .long("color") 48919625d8cSopenharmony_ci/// .value_parser(["always", "auto", "never"]) 49019625d8cSopenharmony_ci/// .default_value("auto") 49119625d8cSopenharmony_ci/// ); 49219625d8cSopenharmony_ci/// 49319625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut( 49419625d8cSopenharmony_ci/// ["cmd", "--color", "never"] 49519625d8cSopenharmony_ci/// ).unwrap(); 49619625d8cSopenharmony_ci/// 49719625d8cSopenharmony_ci/// let color: &String = m.get_one("color") 49819625d8cSopenharmony_ci/// .expect("default"); 49919625d8cSopenharmony_ci/// assert_eq!(color, "never"); 50019625d8cSopenharmony_ci/// ``` 50119625d8cSopenharmony_ciimpl<P, const C: usize> From<[P; C]> for ValueParser 50219625d8cSopenharmony_ciwhere 50319625d8cSopenharmony_ci P: Into<super::PossibleValue>, 50419625d8cSopenharmony_ci{ 50519625d8cSopenharmony_ci fn from(values: [P; C]) -> Self { 50619625d8cSopenharmony_ci let inner = PossibleValuesParser::from(values); 50719625d8cSopenharmony_ci Self::from(inner) 50819625d8cSopenharmony_ci } 50919625d8cSopenharmony_ci} 51019625d8cSopenharmony_ci 51119625d8cSopenharmony_ci/// Create a [`ValueParser`] with [`PossibleValuesParser`] 51219625d8cSopenharmony_ci/// 51319625d8cSopenharmony_ci/// See [`PossibleValuesParser`] for more flexibility in creating the 51419625d8cSopenharmony_ci/// [`PossibleValue`][crate::builder::PossibleValue]s. 51519625d8cSopenharmony_ci/// 51619625d8cSopenharmony_ci/// # Examples 51719625d8cSopenharmony_ci/// 51819625d8cSopenharmony_ci/// ```rust 51919625d8cSopenharmony_ci/// let possible = vec!["always", "auto", "never"]; 52019625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 52119625d8cSopenharmony_ci/// .arg( 52219625d8cSopenharmony_ci/// clap::Arg::new("color") 52319625d8cSopenharmony_ci/// .long("color") 52419625d8cSopenharmony_ci/// .value_parser(possible) 52519625d8cSopenharmony_ci/// .default_value("auto") 52619625d8cSopenharmony_ci/// ); 52719625d8cSopenharmony_ci/// 52819625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut( 52919625d8cSopenharmony_ci/// ["cmd", "--color", "never"] 53019625d8cSopenharmony_ci/// ).unwrap(); 53119625d8cSopenharmony_ci/// 53219625d8cSopenharmony_ci/// let color: &String = m.get_one("color") 53319625d8cSopenharmony_ci/// .expect("default"); 53419625d8cSopenharmony_ci/// assert_eq!(color, "never"); 53519625d8cSopenharmony_ci/// ``` 53619625d8cSopenharmony_ciimpl<P> From<Vec<P>> for ValueParser 53719625d8cSopenharmony_ciwhere 53819625d8cSopenharmony_ci P: Into<super::PossibleValue>, 53919625d8cSopenharmony_ci{ 54019625d8cSopenharmony_ci fn from(values: Vec<P>) -> Self { 54119625d8cSopenharmony_ci let inner = PossibleValuesParser::from(values); 54219625d8cSopenharmony_ci Self::from(inner) 54319625d8cSopenharmony_ci } 54419625d8cSopenharmony_ci} 54519625d8cSopenharmony_ci 54619625d8cSopenharmony_ciimpl std::fmt::Debug for ValueParser { 54719625d8cSopenharmony_ci fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { 54819625d8cSopenharmony_ci match &self.0 { 54919625d8cSopenharmony_ci ValueParserInner::Bool => f.debug_struct("ValueParser::bool").finish(), 55019625d8cSopenharmony_ci ValueParserInner::String => f.debug_struct("ValueParser::string").finish(), 55119625d8cSopenharmony_ci ValueParserInner::OsString => f.debug_struct("ValueParser::os_string").finish(), 55219625d8cSopenharmony_ci ValueParserInner::PathBuf => f.debug_struct("ValueParser::path_buf").finish(), 55319625d8cSopenharmony_ci ValueParserInner::Other(o) => write!(f, "ValueParser::other({:?})", o.type_id()), 55419625d8cSopenharmony_ci } 55519625d8cSopenharmony_ci } 55619625d8cSopenharmony_ci} 55719625d8cSopenharmony_ci 55819625d8cSopenharmony_ciimpl Clone for ValueParser { 55919625d8cSopenharmony_ci fn clone(&self) -> Self { 56019625d8cSopenharmony_ci Self(match &self.0 { 56119625d8cSopenharmony_ci ValueParserInner::Bool => ValueParserInner::Bool, 56219625d8cSopenharmony_ci ValueParserInner::String => ValueParserInner::String, 56319625d8cSopenharmony_ci ValueParserInner::OsString => ValueParserInner::OsString, 56419625d8cSopenharmony_ci ValueParserInner::PathBuf => ValueParserInner::PathBuf, 56519625d8cSopenharmony_ci ValueParserInner::Other(o) => ValueParserInner::Other(o.clone_any()), 56619625d8cSopenharmony_ci }) 56719625d8cSopenharmony_ci } 56819625d8cSopenharmony_ci} 56919625d8cSopenharmony_ci 57019625d8cSopenharmony_ci/// A type-erased wrapper for [`TypedValueParser`]. 57119625d8cSopenharmony_citrait AnyValueParser: Send + Sync + 'static { 57219625d8cSopenharmony_ci fn parse_ref( 57319625d8cSopenharmony_ci &self, 57419625d8cSopenharmony_ci cmd: &crate::Command, 57519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 57619625d8cSopenharmony_ci value: &std::ffi::OsStr, 57719625d8cSopenharmony_ci ) -> Result<AnyValue, crate::Error>; 57819625d8cSopenharmony_ci 57919625d8cSopenharmony_ci fn parse( 58019625d8cSopenharmony_ci &self, 58119625d8cSopenharmony_ci cmd: &crate::Command, 58219625d8cSopenharmony_ci arg: Option<&crate::Arg>, 58319625d8cSopenharmony_ci value: std::ffi::OsString, 58419625d8cSopenharmony_ci ) -> Result<AnyValue, crate::Error>; 58519625d8cSopenharmony_ci 58619625d8cSopenharmony_ci /// Describes the content of `AnyValue` 58719625d8cSopenharmony_ci fn type_id(&self) -> AnyValueId; 58819625d8cSopenharmony_ci 58919625d8cSopenharmony_ci fn possible_values( 59019625d8cSopenharmony_ci &self, 59119625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>>; 59219625d8cSopenharmony_ci 59319625d8cSopenharmony_ci fn clone_any(&self) -> Box<dyn AnyValueParser>; 59419625d8cSopenharmony_ci} 59519625d8cSopenharmony_ci 59619625d8cSopenharmony_ciimpl<T, P> AnyValueParser for P 59719625d8cSopenharmony_ciwhere 59819625d8cSopenharmony_ci T: std::any::Any + Clone + Send + Sync + 'static, 59919625d8cSopenharmony_ci P: TypedValueParser<Value = T>, 60019625d8cSopenharmony_ci{ 60119625d8cSopenharmony_ci fn parse_ref( 60219625d8cSopenharmony_ci &self, 60319625d8cSopenharmony_ci cmd: &crate::Command, 60419625d8cSopenharmony_ci arg: Option<&crate::Arg>, 60519625d8cSopenharmony_ci value: &std::ffi::OsStr, 60619625d8cSopenharmony_ci ) -> Result<AnyValue, crate::Error> { 60719625d8cSopenharmony_ci let value = ok!(TypedValueParser::parse_ref(self, cmd, arg, value)); 60819625d8cSopenharmony_ci Ok(AnyValue::new(value)) 60919625d8cSopenharmony_ci } 61019625d8cSopenharmony_ci 61119625d8cSopenharmony_ci fn parse( 61219625d8cSopenharmony_ci &self, 61319625d8cSopenharmony_ci cmd: &crate::Command, 61419625d8cSopenharmony_ci arg: Option<&crate::Arg>, 61519625d8cSopenharmony_ci value: std::ffi::OsString, 61619625d8cSopenharmony_ci ) -> Result<AnyValue, crate::Error> { 61719625d8cSopenharmony_ci let value = ok!(TypedValueParser::parse(self, cmd, arg, value)); 61819625d8cSopenharmony_ci Ok(AnyValue::new(value)) 61919625d8cSopenharmony_ci } 62019625d8cSopenharmony_ci 62119625d8cSopenharmony_ci fn type_id(&self) -> AnyValueId { 62219625d8cSopenharmony_ci AnyValueId::of::<T>() 62319625d8cSopenharmony_ci } 62419625d8cSopenharmony_ci 62519625d8cSopenharmony_ci fn possible_values( 62619625d8cSopenharmony_ci &self, 62719625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 62819625d8cSopenharmony_ci P::possible_values(self) 62919625d8cSopenharmony_ci } 63019625d8cSopenharmony_ci 63119625d8cSopenharmony_ci fn clone_any(&self) -> Box<dyn AnyValueParser> { 63219625d8cSopenharmony_ci Box::new(self.clone()) 63319625d8cSopenharmony_ci } 63419625d8cSopenharmony_ci} 63519625d8cSopenharmony_ci 63619625d8cSopenharmony_ci/// Parse/validate argument values 63719625d8cSopenharmony_ci/// 63819625d8cSopenharmony_ci/// As alternatives to implementing `TypedValueParser`, 63919625d8cSopenharmony_ci/// - Use `Fn(&str) -> Result<T, E>` which implements `TypedValueParser` 64019625d8cSopenharmony_ci/// - [`TypedValueParser::map`] or [`TypedValueParser::try_map`] to adapt an existing `TypedValueParser` 64119625d8cSopenharmony_ci/// 64219625d8cSopenharmony_ci/// See `ValueParserFactory` to register `TypedValueParser::Value` with 64319625d8cSopenharmony_ci/// [`value_parser!`][crate::value_parser]. 64419625d8cSopenharmony_ci/// 64519625d8cSopenharmony_ci/// # Example 64619625d8cSopenharmony_ci/// 64719625d8cSopenharmony_ci#[cfg_attr(not(feature = "error-context"), doc = " ```ignore")] 64819625d8cSopenharmony_ci#[cfg_attr(feature = "error-context", doc = " ```")] 64919625d8cSopenharmony_ci/// # use clap::error::ErrorKind; 65019625d8cSopenharmony_ci/// # use clap::error::ContextKind; 65119625d8cSopenharmony_ci/// # use clap::error::ContextValue; 65219625d8cSopenharmony_ci/// #[derive(Clone)] 65319625d8cSopenharmony_ci/// struct Custom(u32); 65419625d8cSopenharmony_ci/// 65519625d8cSopenharmony_ci/// #[derive(Clone)] 65619625d8cSopenharmony_ci/// struct CustomValueParser; 65719625d8cSopenharmony_ci/// 65819625d8cSopenharmony_ci/// impl clap::builder::TypedValueParser for CustomValueParser { 65919625d8cSopenharmony_ci/// type Value = Custom; 66019625d8cSopenharmony_ci/// 66119625d8cSopenharmony_ci/// fn parse_ref( 66219625d8cSopenharmony_ci/// &self, 66319625d8cSopenharmony_ci/// cmd: &clap::Command, 66419625d8cSopenharmony_ci/// arg: Option<&clap::Arg>, 66519625d8cSopenharmony_ci/// value: &std::ffi::OsStr, 66619625d8cSopenharmony_ci/// ) -> Result<Self::Value, clap::Error> { 66719625d8cSopenharmony_ci/// let inner = clap::value_parser!(u32); 66819625d8cSopenharmony_ci/// let val = inner.parse_ref(cmd, arg, value)?; 66919625d8cSopenharmony_ci/// 67019625d8cSopenharmony_ci/// const INVALID_VALUE: u32 = 10; 67119625d8cSopenharmony_ci/// if val == INVALID_VALUE { 67219625d8cSopenharmony_ci/// let mut err = clap::Error::new(ErrorKind::ValueValidation) 67319625d8cSopenharmony_ci/// .with_cmd(cmd); 67419625d8cSopenharmony_ci/// if let Some(arg) = arg { 67519625d8cSopenharmony_ci/// err.insert(ContextKind::InvalidArg, ContextValue::String(arg.to_string())); 67619625d8cSopenharmony_ci/// } 67719625d8cSopenharmony_ci/// err.insert(ContextKind::InvalidValue, ContextValue::String(INVALID_VALUE.to_string())); 67819625d8cSopenharmony_ci/// return Err(err); 67919625d8cSopenharmony_ci/// } 68019625d8cSopenharmony_ci/// 68119625d8cSopenharmony_ci/// Ok(Custom(val)) 68219625d8cSopenharmony_ci/// } 68319625d8cSopenharmony_ci/// } 68419625d8cSopenharmony_ci/// ``` 68519625d8cSopenharmony_cipub trait TypedValueParser: Clone + Send + Sync + 'static { 68619625d8cSopenharmony_ci /// Argument's value type 68719625d8cSopenharmony_ci type Value: Send + Sync + Clone; 68819625d8cSopenharmony_ci 68919625d8cSopenharmony_ci /// Parse the argument value 69019625d8cSopenharmony_ci /// 69119625d8cSopenharmony_ci /// When `arg` is `None`, an external subcommand value is being parsed. 69219625d8cSopenharmony_ci fn parse_ref( 69319625d8cSopenharmony_ci &self, 69419625d8cSopenharmony_ci cmd: &crate::Command, 69519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 69619625d8cSopenharmony_ci value: &std::ffi::OsStr, 69719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error>; 69819625d8cSopenharmony_ci 69919625d8cSopenharmony_ci /// Parse the argument value 70019625d8cSopenharmony_ci /// 70119625d8cSopenharmony_ci /// When `arg` is `None`, an external subcommand value is being parsed. 70219625d8cSopenharmony_ci fn parse( 70319625d8cSopenharmony_ci &self, 70419625d8cSopenharmony_ci cmd: &crate::Command, 70519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 70619625d8cSopenharmony_ci value: std::ffi::OsString, 70719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 70819625d8cSopenharmony_ci self.parse_ref(cmd, arg, &value) 70919625d8cSopenharmony_ci } 71019625d8cSopenharmony_ci 71119625d8cSopenharmony_ci /// Reflect on enumerated value properties 71219625d8cSopenharmony_ci /// 71319625d8cSopenharmony_ci /// Error checking should not be done with this; it is mostly targeted at user-facing 71419625d8cSopenharmony_ci /// applications like errors and completion. 71519625d8cSopenharmony_ci fn possible_values( 71619625d8cSopenharmony_ci &self, 71719625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 71819625d8cSopenharmony_ci None 71919625d8cSopenharmony_ci } 72019625d8cSopenharmony_ci 72119625d8cSopenharmony_ci /// Adapt a `TypedValueParser` from one value to another 72219625d8cSopenharmony_ci /// 72319625d8cSopenharmony_ci /// # Example 72419625d8cSopenharmony_ci /// 72519625d8cSopenharmony_ci /// ```rust 72619625d8cSopenharmony_ci /// # use clap::Command; 72719625d8cSopenharmony_ci /// # use clap::Arg; 72819625d8cSopenharmony_ci /// # use clap::builder::TypedValueParser as _; 72919625d8cSopenharmony_ci /// # use clap::builder::BoolishValueParser; 73019625d8cSopenharmony_ci /// let cmd = Command::new("mycmd") 73119625d8cSopenharmony_ci /// .arg( 73219625d8cSopenharmony_ci /// Arg::new("flag") 73319625d8cSopenharmony_ci /// .long("flag") 73419625d8cSopenharmony_ci /// .action(clap::ArgAction::SetTrue) 73519625d8cSopenharmony_ci /// .value_parser( 73619625d8cSopenharmony_ci /// BoolishValueParser::new() 73719625d8cSopenharmony_ci /// .map(|b| -> usize { 73819625d8cSopenharmony_ci /// if b { 10 } else { 5 } 73919625d8cSopenharmony_ci /// }) 74019625d8cSopenharmony_ci /// ) 74119625d8cSopenharmony_ci /// ); 74219625d8cSopenharmony_ci /// 74319625d8cSopenharmony_ci /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap(); 74419625d8cSopenharmony_ci /// assert!(matches.contains_id("flag")); 74519625d8cSopenharmony_ci /// assert_eq!( 74619625d8cSopenharmony_ci /// matches.get_one::<usize>("flag").copied(), 74719625d8cSopenharmony_ci /// Some(10) 74819625d8cSopenharmony_ci /// ); 74919625d8cSopenharmony_ci /// 75019625d8cSopenharmony_ci /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap(); 75119625d8cSopenharmony_ci /// assert!(matches.contains_id("flag")); 75219625d8cSopenharmony_ci /// assert_eq!( 75319625d8cSopenharmony_ci /// matches.get_one::<usize>("flag").copied(), 75419625d8cSopenharmony_ci /// Some(5) 75519625d8cSopenharmony_ci /// ); 75619625d8cSopenharmony_ci /// ``` 75719625d8cSopenharmony_ci fn map<T, F>(self, func: F) -> MapValueParser<Self, F> 75819625d8cSopenharmony_ci where 75919625d8cSopenharmony_ci T: Send + Sync + Clone, 76019625d8cSopenharmony_ci F: Fn(Self::Value) -> T + Clone, 76119625d8cSopenharmony_ci { 76219625d8cSopenharmony_ci MapValueParser::new(self, func) 76319625d8cSopenharmony_ci } 76419625d8cSopenharmony_ci 76519625d8cSopenharmony_ci /// Adapt a `TypedValueParser` from one value to another 76619625d8cSopenharmony_ci /// 76719625d8cSopenharmony_ci /// # Example 76819625d8cSopenharmony_ci /// 76919625d8cSopenharmony_ci /// ```rust 77019625d8cSopenharmony_ci /// # use std::ffi::OsString; 77119625d8cSopenharmony_ci /// # use std::ffi::OsStr; 77219625d8cSopenharmony_ci /// # use std::path::PathBuf; 77319625d8cSopenharmony_ci /// # use std::path::Path; 77419625d8cSopenharmony_ci /// # use clap::Command; 77519625d8cSopenharmony_ci /// # use clap::Arg; 77619625d8cSopenharmony_ci /// # use clap::builder::TypedValueParser as _; 77719625d8cSopenharmony_ci /// # use clap::builder::OsStringValueParser; 77819625d8cSopenharmony_ci /// let cmd = Command::new("mycmd") 77919625d8cSopenharmony_ci /// .arg( 78019625d8cSopenharmony_ci /// Arg::new("flag") 78119625d8cSopenharmony_ci /// .long("flag") 78219625d8cSopenharmony_ci /// .value_parser( 78319625d8cSopenharmony_ci /// OsStringValueParser::new() 78419625d8cSopenharmony_ci /// .try_map(verify_ext) 78519625d8cSopenharmony_ci /// ) 78619625d8cSopenharmony_ci /// ); 78719625d8cSopenharmony_ci /// 78819625d8cSopenharmony_ci /// fn verify_ext(os: OsString) -> Result<PathBuf, &'static str> { 78919625d8cSopenharmony_ci /// let path = PathBuf::from(os); 79019625d8cSopenharmony_ci /// if path.extension() != Some(OsStr::new("rs")) { 79119625d8cSopenharmony_ci /// return Err("only Rust files are supported"); 79219625d8cSopenharmony_ci /// } 79319625d8cSopenharmony_ci /// Ok(path) 79419625d8cSopenharmony_ci /// } 79519625d8cSopenharmony_ci /// 79619625d8cSopenharmony_ci /// let error = cmd.clone().try_get_matches_from(["mycmd", "--flag", "foo.txt"]).unwrap_err(); 79719625d8cSopenharmony_ci /// error.print(); 79819625d8cSopenharmony_ci /// 79919625d8cSopenharmony_ci /// let matches = cmd.try_get_matches_from(["mycmd", "--flag", "foo.rs"]).unwrap(); 80019625d8cSopenharmony_ci /// assert!(matches.contains_id("flag")); 80119625d8cSopenharmony_ci /// assert_eq!( 80219625d8cSopenharmony_ci /// matches.get_one::<PathBuf>("flag").map(|s| s.as_path()), 80319625d8cSopenharmony_ci /// Some(Path::new("foo.rs")) 80419625d8cSopenharmony_ci /// ); 80519625d8cSopenharmony_ci /// ``` 80619625d8cSopenharmony_ci fn try_map<T, E, F>(self, func: F) -> TryMapValueParser<Self, F> 80719625d8cSopenharmony_ci where 80819625d8cSopenharmony_ci F: Fn(Self::Value) -> Result<T, E> + Clone + Send + Sync + 'static, 80919625d8cSopenharmony_ci T: Send + Sync + Clone, 81019625d8cSopenharmony_ci E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, 81119625d8cSopenharmony_ci { 81219625d8cSopenharmony_ci TryMapValueParser::new(self, func) 81319625d8cSopenharmony_ci } 81419625d8cSopenharmony_ci} 81519625d8cSopenharmony_ci 81619625d8cSopenharmony_ciimpl<F, T, E> TypedValueParser for F 81719625d8cSopenharmony_ciwhere 81819625d8cSopenharmony_ci F: Fn(&str) -> Result<T, E> + Clone + Send + Sync + 'static, 81919625d8cSopenharmony_ci E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, 82019625d8cSopenharmony_ci T: Send + Sync + Clone, 82119625d8cSopenharmony_ci{ 82219625d8cSopenharmony_ci type Value = T; 82319625d8cSopenharmony_ci 82419625d8cSopenharmony_ci fn parse_ref( 82519625d8cSopenharmony_ci &self, 82619625d8cSopenharmony_ci cmd: &crate::Command, 82719625d8cSopenharmony_ci arg: Option<&crate::Arg>, 82819625d8cSopenharmony_ci value: &std::ffi::OsStr, 82919625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 83019625d8cSopenharmony_ci let value = ok!(value.to_str().ok_or_else(|| { 83119625d8cSopenharmony_ci crate::Error::invalid_utf8( 83219625d8cSopenharmony_ci cmd, 83319625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 83419625d8cSopenharmony_ci ) 83519625d8cSopenharmony_ci })); 83619625d8cSopenharmony_ci let value = ok!((self)(value).map_err(|e| { 83719625d8cSopenharmony_ci let arg = arg 83819625d8cSopenharmony_ci .map(|a| a.to_string()) 83919625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 84019625d8cSopenharmony_ci crate::Error::value_validation(arg, value.to_owned(), e.into()).with_cmd(cmd) 84119625d8cSopenharmony_ci })); 84219625d8cSopenharmony_ci Ok(value) 84319625d8cSopenharmony_ci } 84419625d8cSopenharmony_ci} 84519625d8cSopenharmony_ci 84619625d8cSopenharmony_ci/// Implementation for [`ValueParser::string`] 84719625d8cSopenharmony_ci/// 84819625d8cSopenharmony_ci/// Useful for composing new [`TypedValueParser`]s 84919625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 85019625d8cSopenharmony_ci#[non_exhaustive] 85119625d8cSopenharmony_cipub struct StringValueParser {} 85219625d8cSopenharmony_ci 85319625d8cSopenharmony_ciimpl StringValueParser { 85419625d8cSopenharmony_ci /// Implementation for [`ValueParser::string`] 85519625d8cSopenharmony_ci pub fn new() -> Self { 85619625d8cSopenharmony_ci Self {} 85719625d8cSopenharmony_ci } 85819625d8cSopenharmony_ci} 85919625d8cSopenharmony_ci 86019625d8cSopenharmony_ciimpl TypedValueParser for StringValueParser { 86119625d8cSopenharmony_ci type Value = String; 86219625d8cSopenharmony_ci 86319625d8cSopenharmony_ci fn parse_ref( 86419625d8cSopenharmony_ci &self, 86519625d8cSopenharmony_ci cmd: &crate::Command, 86619625d8cSopenharmony_ci arg: Option<&crate::Arg>, 86719625d8cSopenharmony_ci value: &std::ffi::OsStr, 86819625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 86919625d8cSopenharmony_ci TypedValueParser::parse(self, cmd, arg, value.to_owned()) 87019625d8cSopenharmony_ci } 87119625d8cSopenharmony_ci 87219625d8cSopenharmony_ci fn parse( 87319625d8cSopenharmony_ci &self, 87419625d8cSopenharmony_ci cmd: &crate::Command, 87519625d8cSopenharmony_ci _arg: Option<&crate::Arg>, 87619625d8cSopenharmony_ci value: std::ffi::OsString, 87719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 87819625d8cSopenharmony_ci let value = ok!(value.into_string().map_err(|_| { 87919625d8cSopenharmony_ci crate::Error::invalid_utf8( 88019625d8cSopenharmony_ci cmd, 88119625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 88219625d8cSopenharmony_ci ) 88319625d8cSopenharmony_ci })); 88419625d8cSopenharmony_ci Ok(value) 88519625d8cSopenharmony_ci } 88619625d8cSopenharmony_ci} 88719625d8cSopenharmony_ci 88819625d8cSopenharmony_ciimpl Default for StringValueParser { 88919625d8cSopenharmony_ci fn default() -> Self { 89019625d8cSopenharmony_ci Self::new() 89119625d8cSopenharmony_ci } 89219625d8cSopenharmony_ci} 89319625d8cSopenharmony_ci 89419625d8cSopenharmony_ci/// Implementation for [`ValueParser::os_string`] 89519625d8cSopenharmony_ci/// 89619625d8cSopenharmony_ci/// Useful for composing new [`TypedValueParser`]s 89719625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 89819625d8cSopenharmony_ci#[non_exhaustive] 89919625d8cSopenharmony_cipub struct OsStringValueParser {} 90019625d8cSopenharmony_ci 90119625d8cSopenharmony_ciimpl OsStringValueParser { 90219625d8cSopenharmony_ci /// Implementation for [`ValueParser::os_string`] 90319625d8cSopenharmony_ci pub fn new() -> Self { 90419625d8cSopenharmony_ci Self {} 90519625d8cSopenharmony_ci } 90619625d8cSopenharmony_ci} 90719625d8cSopenharmony_ci 90819625d8cSopenharmony_ciimpl TypedValueParser for OsStringValueParser { 90919625d8cSopenharmony_ci type Value = std::ffi::OsString; 91019625d8cSopenharmony_ci 91119625d8cSopenharmony_ci fn parse_ref( 91219625d8cSopenharmony_ci &self, 91319625d8cSopenharmony_ci cmd: &crate::Command, 91419625d8cSopenharmony_ci arg: Option<&crate::Arg>, 91519625d8cSopenharmony_ci value: &std::ffi::OsStr, 91619625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 91719625d8cSopenharmony_ci TypedValueParser::parse(self, cmd, arg, value.to_owned()) 91819625d8cSopenharmony_ci } 91919625d8cSopenharmony_ci 92019625d8cSopenharmony_ci fn parse( 92119625d8cSopenharmony_ci &self, 92219625d8cSopenharmony_ci _cmd: &crate::Command, 92319625d8cSopenharmony_ci _arg: Option<&crate::Arg>, 92419625d8cSopenharmony_ci value: std::ffi::OsString, 92519625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 92619625d8cSopenharmony_ci Ok(value) 92719625d8cSopenharmony_ci } 92819625d8cSopenharmony_ci} 92919625d8cSopenharmony_ci 93019625d8cSopenharmony_ciimpl Default for OsStringValueParser { 93119625d8cSopenharmony_ci fn default() -> Self { 93219625d8cSopenharmony_ci Self::new() 93319625d8cSopenharmony_ci } 93419625d8cSopenharmony_ci} 93519625d8cSopenharmony_ci 93619625d8cSopenharmony_ci/// Implementation for [`ValueParser::path_buf`] 93719625d8cSopenharmony_ci/// 93819625d8cSopenharmony_ci/// Useful for composing new [`TypedValueParser`]s 93919625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 94019625d8cSopenharmony_ci#[non_exhaustive] 94119625d8cSopenharmony_cipub struct PathBufValueParser {} 94219625d8cSopenharmony_ci 94319625d8cSopenharmony_ciimpl PathBufValueParser { 94419625d8cSopenharmony_ci /// Implementation for [`ValueParser::path_buf`] 94519625d8cSopenharmony_ci pub fn new() -> Self { 94619625d8cSopenharmony_ci Self {} 94719625d8cSopenharmony_ci } 94819625d8cSopenharmony_ci} 94919625d8cSopenharmony_ci 95019625d8cSopenharmony_ciimpl TypedValueParser for PathBufValueParser { 95119625d8cSopenharmony_ci type Value = std::path::PathBuf; 95219625d8cSopenharmony_ci 95319625d8cSopenharmony_ci fn parse_ref( 95419625d8cSopenharmony_ci &self, 95519625d8cSopenharmony_ci cmd: &crate::Command, 95619625d8cSopenharmony_ci arg: Option<&crate::Arg>, 95719625d8cSopenharmony_ci value: &std::ffi::OsStr, 95819625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 95919625d8cSopenharmony_ci TypedValueParser::parse(self, cmd, arg, value.to_owned()) 96019625d8cSopenharmony_ci } 96119625d8cSopenharmony_ci 96219625d8cSopenharmony_ci fn parse( 96319625d8cSopenharmony_ci &self, 96419625d8cSopenharmony_ci cmd: &crate::Command, 96519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 96619625d8cSopenharmony_ci value: std::ffi::OsString, 96719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 96819625d8cSopenharmony_ci if value.is_empty() { 96919625d8cSopenharmony_ci return Err(crate::Error::empty_value( 97019625d8cSopenharmony_ci cmd, 97119625d8cSopenharmony_ci &[], 97219625d8cSopenharmony_ci arg.map(ToString::to_string) 97319625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()), 97419625d8cSopenharmony_ci )); 97519625d8cSopenharmony_ci } 97619625d8cSopenharmony_ci Ok(Self::Value::from(value)) 97719625d8cSopenharmony_ci } 97819625d8cSopenharmony_ci} 97919625d8cSopenharmony_ci 98019625d8cSopenharmony_ciimpl Default for PathBufValueParser { 98119625d8cSopenharmony_ci fn default() -> Self { 98219625d8cSopenharmony_ci Self::new() 98319625d8cSopenharmony_ci } 98419625d8cSopenharmony_ci} 98519625d8cSopenharmony_ci 98619625d8cSopenharmony_ci/// Parse an [`ValueEnum`][crate::ValueEnum] value. 98719625d8cSopenharmony_ci/// 98819625d8cSopenharmony_ci/// See also: 98919625d8cSopenharmony_ci/// - [`PossibleValuesParser`] 99019625d8cSopenharmony_ci/// 99119625d8cSopenharmony_ci/// # Example 99219625d8cSopenharmony_ci/// 99319625d8cSopenharmony_ci/// ```rust 99419625d8cSopenharmony_ci/// # use std::ffi::OsStr; 99519625d8cSopenharmony_ci/// # use clap::ColorChoice; 99619625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 99719625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 99819625d8cSopenharmony_ci/// # let arg = None; 99919625d8cSopenharmony_ci/// 100019625d8cSopenharmony_ci/// // Usage 100119625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 100219625d8cSopenharmony_ci/// .arg( 100319625d8cSopenharmony_ci/// clap::Arg::new("color") 100419625d8cSopenharmony_ci/// .value_parser(clap::builder::EnumValueParser::<ColorChoice>::new()) 100519625d8cSopenharmony_ci/// .required(true) 100619625d8cSopenharmony_ci/// ); 100719625d8cSopenharmony_ci/// 100819625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "always"]).unwrap(); 100919625d8cSopenharmony_ci/// let port: ColorChoice = *m.get_one("color") 101019625d8cSopenharmony_ci/// .expect("required"); 101119625d8cSopenharmony_ci/// assert_eq!(port, ColorChoice::Always); 101219625d8cSopenharmony_ci/// 101319625d8cSopenharmony_ci/// // Semantics 101419625d8cSopenharmony_ci/// let value_parser = clap::builder::EnumValueParser::<ColorChoice>::new(); 101519625d8cSopenharmony_ci/// // or 101619625d8cSopenharmony_ci/// let value_parser = clap::value_parser!(ColorChoice); 101719625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err()); 101819625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err()); 101919625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("always")).unwrap(), ColorChoice::Always); 102019625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("auto")).unwrap(), ColorChoice::Auto); 102119625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), ColorChoice::Never); 102219625d8cSopenharmony_ci/// ``` 102319625d8cSopenharmony_ci#[derive(Clone, Debug)] 102419625d8cSopenharmony_cipub struct EnumValueParser<E: crate::ValueEnum + Clone + Send + Sync + 'static>( 102519625d8cSopenharmony_ci std::marker::PhantomData<E>, 102619625d8cSopenharmony_ci); 102719625d8cSopenharmony_ci 102819625d8cSopenharmony_ciimpl<E: crate::ValueEnum + Clone + Send + Sync + 'static> EnumValueParser<E> { 102919625d8cSopenharmony_ci /// Parse an [`ValueEnum`][crate::ValueEnum] 103019625d8cSopenharmony_ci pub fn new() -> Self { 103119625d8cSopenharmony_ci let phantom: std::marker::PhantomData<E> = Default::default(); 103219625d8cSopenharmony_ci Self(phantom) 103319625d8cSopenharmony_ci } 103419625d8cSopenharmony_ci} 103519625d8cSopenharmony_ci 103619625d8cSopenharmony_ciimpl<E: crate::ValueEnum + Clone + Send + Sync + 'static> TypedValueParser for EnumValueParser<E> { 103719625d8cSopenharmony_ci type Value = E; 103819625d8cSopenharmony_ci 103919625d8cSopenharmony_ci fn parse_ref( 104019625d8cSopenharmony_ci &self, 104119625d8cSopenharmony_ci cmd: &crate::Command, 104219625d8cSopenharmony_ci arg: Option<&crate::Arg>, 104319625d8cSopenharmony_ci value: &std::ffi::OsStr, 104419625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 104519625d8cSopenharmony_ci let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false); 104619625d8cSopenharmony_ci let possible_vals = || { 104719625d8cSopenharmony_ci E::value_variants() 104819625d8cSopenharmony_ci .iter() 104919625d8cSopenharmony_ci .filter_map(|v| v.to_possible_value()) 105019625d8cSopenharmony_ci .filter(|v| !v.is_hide_set()) 105119625d8cSopenharmony_ci .map(|v| v.get_name().to_owned()) 105219625d8cSopenharmony_ci .collect::<Vec<_>>() 105319625d8cSopenharmony_ci }; 105419625d8cSopenharmony_ci 105519625d8cSopenharmony_ci let value = ok!(value.to_str().ok_or_else(|| { 105619625d8cSopenharmony_ci crate::Error::invalid_value( 105719625d8cSopenharmony_ci cmd, 105819625d8cSopenharmony_ci value.to_string_lossy().into_owned(), 105919625d8cSopenharmony_ci &possible_vals(), 106019625d8cSopenharmony_ci arg.map(ToString::to_string) 106119625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()), 106219625d8cSopenharmony_ci ) 106319625d8cSopenharmony_ci })); 106419625d8cSopenharmony_ci let value = ok!(E::value_variants() 106519625d8cSopenharmony_ci .iter() 106619625d8cSopenharmony_ci .find(|v| { 106719625d8cSopenharmony_ci v.to_possible_value() 106819625d8cSopenharmony_ci .expect("ValueEnum::value_variants contains only values with a corresponding ValueEnum::to_possible_value") 106919625d8cSopenharmony_ci .matches(value, ignore_case) 107019625d8cSopenharmony_ci }) 107119625d8cSopenharmony_ci .ok_or_else(|| { 107219625d8cSopenharmony_ci crate::Error::invalid_value( 107319625d8cSopenharmony_ci cmd, 107419625d8cSopenharmony_ci value.to_owned(), 107519625d8cSopenharmony_ci &possible_vals(), 107619625d8cSopenharmony_ci arg.map(ToString::to_string) 107719625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()), 107819625d8cSopenharmony_ci ) 107919625d8cSopenharmony_ci })) 108019625d8cSopenharmony_ci .clone(); 108119625d8cSopenharmony_ci Ok(value) 108219625d8cSopenharmony_ci } 108319625d8cSopenharmony_ci 108419625d8cSopenharmony_ci fn possible_values( 108519625d8cSopenharmony_ci &self, 108619625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 108719625d8cSopenharmony_ci Some(Box::new( 108819625d8cSopenharmony_ci E::value_variants() 108919625d8cSopenharmony_ci .iter() 109019625d8cSopenharmony_ci .filter_map(|v| v.to_possible_value()), 109119625d8cSopenharmony_ci )) 109219625d8cSopenharmony_ci } 109319625d8cSopenharmony_ci} 109419625d8cSopenharmony_ci 109519625d8cSopenharmony_ciimpl<E: crate::ValueEnum + Clone + Send + Sync + 'static> Default for EnumValueParser<E> { 109619625d8cSopenharmony_ci fn default() -> Self { 109719625d8cSopenharmony_ci Self::new() 109819625d8cSopenharmony_ci } 109919625d8cSopenharmony_ci} 110019625d8cSopenharmony_ci 110119625d8cSopenharmony_ci/// Verify the value is from an enumerated set of [`PossibleValue`][crate::builder::PossibleValue]. 110219625d8cSopenharmony_ci/// 110319625d8cSopenharmony_ci/// See also: 110419625d8cSopenharmony_ci/// - [`EnumValueParser`] for directly supporting [`ValueEnum`][crate::ValueEnum] types 110519625d8cSopenharmony_ci/// - [`TypedValueParser::map`] for adapting values to a more specialized type, like an external 110619625d8cSopenharmony_ci/// enums that can't implement [`ValueEnum`][crate::ValueEnum] 110719625d8cSopenharmony_ci/// 110819625d8cSopenharmony_ci/// # Example 110919625d8cSopenharmony_ci/// 111019625d8cSopenharmony_ci/// Usage: 111119625d8cSopenharmony_ci/// ```rust 111219625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 111319625d8cSopenharmony_ci/// .arg( 111419625d8cSopenharmony_ci/// clap::Arg::new("color") 111519625d8cSopenharmony_ci/// .value_parser(clap::builder::PossibleValuesParser::new(["always", "auto", "never"])) 111619625d8cSopenharmony_ci/// .required(true) 111719625d8cSopenharmony_ci/// ); 111819625d8cSopenharmony_ci/// 111919625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "always"]).unwrap(); 112019625d8cSopenharmony_ci/// let port: &String = m.get_one("color") 112119625d8cSopenharmony_ci/// .expect("required"); 112219625d8cSopenharmony_ci/// assert_eq!(port, "always"); 112319625d8cSopenharmony_ci/// ``` 112419625d8cSopenharmony_ci/// 112519625d8cSopenharmony_ci/// Semantics: 112619625d8cSopenharmony_ci/// ```rust 112719625d8cSopenharmony_ci/// # use std::ffi::OsStr; 112819625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 112919625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 113019625d8cSopenharmony_ci/// # let arg = None; 113119625d8cSopenharmony_ci/// let value_parser = clap::builder::PossibleValuesParser::new(["always", "auto", "never"]); 113219625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err()); 113319625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err()); 113419625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("always")).unwrap(), "always"); 113519625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("auto")).unwrap(), "auto"); 113619625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("never")).unwrap(), "never"); 113719625d8cSopenharmony_ci/// ``` 113819625d8cSopenharmony_ci#[derive(Clone, Debug)] 113919625d8cSopenharmony_cipub struct PossibleValuesParser(Vec<super::PossibleValue>); 114019625d8cSopenharmony_ci 114119625d8cSopenharmony_ciimpl PossibleValuesParser { 114219625d8cSopenharmony_ci /// Verify the value is from an enumerated set pf [`PossibleValue`][crate::builder::PossibleValue]. 114319625d8cSopenharmony_ci pub fn new(values: impl Into<PossibleValuesParser>) -> Self { 114419625d8cSopenharmony_ci values.into() 114519625d8cSopenharmony_ci } 114619625d8cSopenharmony_ci} 114719625d8cSopenharmony_ci 114819625d8cSopenharmony_ciimpl TypedValueParser for PossibleValuesParser { 114919625d8cSopenharmony_ci type Value = String; 115019625d8cSopenharmony_ci 115119625d8cSopenharmony_ci fn parse_ref( 115219625d8cSopenharmony_ci &self, 115319625d8cSopenharmony_ci cmd: &crate::Command, 115419625d8cSopenharmony_ci arg: Option<&crate::Arg>, 115519625d8cSopenharmony_ci value: &std::ffi::OsStr, 115619625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 115719625d8cSopenharmony_ci TypedValueParser::parse(self, cmd, arg, value.to_owned()) 115819625d8cSopenharmony_ci } 115919625d8cSopenharmony_ci 116019625d8cSopenharmony_ci fn parse( 116119625d8cSopenharmony_ci &self, 116219625d8cSopenharmony_ci cmd: &crate::Command, 116319625d8cSopenharmony_ci arg: Option<&crate::Arg>, 116419625d8cSopenharmony_ci value: std::ffi::OsString, 116519625d8cSopenharmony_ci ) -> Result<String, crate::Error> { 116619625d8cSopenharmony_ci let value = ok!(value.into_string().map_err(|_| { 116719625d8cSopenharmony_ci crate::Error::invalid_utf8( 116819625d8cSopenharmony_ci cmd, 116919625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 117019625d8cSopenharmony_ci ) 117119625d8cSopenharmony_ci })); 117219625d8cSopenharmony_ci 117319625d8cSopenharmony_ci let ignore_case = arg.map(|a| a.is_ignore_case_set()).unwrap_or(false); 117419625d8cSopenharmony_ci if self.0.iter().any(|v| v.matches(&value, ignore_case)) { 117519625d8cSopenharmony_ci Ok(value) 117619625d8cSopenharmony_ci } else { 117719625d8cSopenharmony_ci let possible_vals = self 117819625d8cSopenharmony_ci .0 117919625d8cSopenharmony_ci .iter() 118019625d8cSopenharmony_ci .filter(|v| !v.is_hide_set()) 118119625d8cSopenharmony_ci .map(|v| v.get_name().to_owned()) 118219625d8cSopenharmony_ci .collect::<Vec<_>>(); 118319625d8cSopenharmony_ci 118419625d8cSopenharmony_ci Err(crate::Error::invalid_value( 118519625d8cSopenharmony_ci cmd, 118619625d8cSopenharmony_ci value, 118719625d8cSopenharmony_ci &possible_vals, 118819625d8cSopenharmony_ci arg.map(ToString::to_string) 118919625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()), 119019625d8cSopenharmony_ci )) 119119625d8cSopenharmony_ci } 119219625d8cSopenharmony_ci } 119319625d8cSopenharmony_ci 119419625d8cSopenharmony_ci fn possible_values( 119519625d8cSopenharmony_ci &self, 119619625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 119719625d8cSopenharmony_ci Some(Box::new(self.0.iter().cloned())) 119819625d8cSopenharmony_ci } 119919625d8cSopenharmony_ci} 120019625d8cSopenharmony_ci 120119625d8cSopenharmony_ciimpl<I, T> From<I> for PossibleValuesParser 120219625d8cSopenharmony_ciwhere 120319625d8cSopenharmony_ci I: IntoIterator<Item = T>, 120419625d8cSopenharmony_ci T: Into<super::PossibleValue>, 120519625d8cSopenharmony_ci{ 120619625d8cSopenharmony_ci fn from(values: I) -> Self { 120719625d8cSopenharmony_ci Self(values.into_iter().map(|t| t.into()).collect()) 120819625d8cSopenharmony_ci } 120919625d8cSopenharmony_ci} 121019625d8cSopenharmony_ci 121119625d8cSopenharmony_ci/// Parse number that fall within a range of values 121219625d8cSopenharmony_ci/// 121319625d8cSopenharmony_ci/// **NOTE:** To capture negative values, you will also need to set 121419625d8cSopenharmony_ci/// [`Arg::allow_negative_numbers`][crate::Arg::allow_negative_numbers] or 121519625d8cSopenharmony_ci/// [`Arg::allow_hyphen_values`][crate::Arg::allow_hyphen_values]. 121619625d8cSopenharmony_ci/// 121719625d8cSopenharmony_ci/// # Example 121819625d8cSopenharmony_ci/// 121919625d8cSopenharmony_ci/// Usage: 122019625d8cSopenharmony_ci/// ```rust 122119625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 122219625d8cSopenharmony_ci/// .arg( 122319625d8cSopenharmony_ci/// clap::Arg::new("port") 122419625d8cSopenharmony_ci/// .long("port") 122519625d8cSopenharmony_ci/// .value_parser(clap::value_parser!(u16).range(3000..)) 122619625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 122719625d8cSopenharmony_ci/// .required(true) 122819625d8cSopenharmony_ci/// ); 122919625d8cSopenharmony_ci/// 123019625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap(); 123119625d8cSopenharmony_ci/// let port: u16 = *m.get_one("port") 123219625d8cSopenharmony_ci/// .expect("required"); 123319625d8cSopenharmony_ci/// assert_eq!(port, 3001); 123419625d8cSopenharmony_ci/// ``` 123519625d8cSopenharmony_ci/// 123619625d8cSopenharmony_ci/// Semantics: 123719625d8cSopenharmony_ci/// ```rust 123819625d8cSopenharmony_ci/// # use std::ffi::OsStr; 123919625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 124019625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 124119625d8cSopenharmony_ci/// # let arg = None; 124219625d8cSopenharmony_ci/// let value_parser = clap::builder::RangedI64ValueParser::<i32>::new().range(-1..200); 124319625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err()); 124419625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err()); 124519625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-200")).is_err()); 124619625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("300")).is_err()); 124719625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("-1")).unwrap(), -1); 124819625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), 0); 124919625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50); 125019625d8cSopenharmony_ci/// ``` 125119625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 125219625d8cSopenharmony_cipub struct RangedI64ValueParser<T: std::convert::TryFrom<i64> + Clone + Send + Sync = i64> { 125319625d8cSopenharmony_ci bounds: (std::ops::Bound<i64>, std::ops::Bound<i64>), 125419625d8cSopenharmony_ci target: std::marker::PhantomData<T>, 125519625d8cSopenharmony_ci} 125619625d8cSopenharmony_ci 125719625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> RangedI64ValueParser<T> { 125819625d8cSopenharmony_ci /// Select full range of `i64` 125919625d8cSopenharmony_ci pub fn new() -> Self { 126019625d8cSopenharmony_ci Self::from(..) 126119625d8cSopenharmony_ci } 126219625d8cSopenharmony_ci 126319625d8cSopenharmony_ci /// Narrow the supported range 126419625d8cSopenharmony_ci pub fn range<B: RangeBounds<i64>>(mut self, range: B) -> Self { 126519625d8cSopenharmony_ci // Consideration: when the user does `value_parser!(u8).range()` 126619625d8cSopenharmony_ci // - Avoid programming mistakes by accidentally expanding the range 126719625d8cSopenharmony_ci // - Make it convenient to limit the range like with `..10` 126819625d8cSopenharmony_ci let start = match range.start_bound() { 126919625d8cSopenharmony_ci l @ std::ops::Bound::Included(i) => { 127019625d8cSopenharmony_ci debug_assert!( 127119625d8cSopenharmony_ci self.bounds.contains(i), 127219625d8cSopenharmony_ci "{} must be in {:?}", 127319625d8cSopenharmony_ci i, 127419625d8cSopenharmony_ci self.bounds 127519625d8cSopenharmony_ci ); 127619625d8cSopenharmony_ci l.cloned() 127719625d8cSopenharmony_ci } 127819625d8cSopenharmony_ci l @ std::ops::Bound::Excluded(i) => { 127919625d8cSopenharmony_ci debug_assert!( 128019625d8cSopenharmony_ci self.bounds.contains(&i.saturating_add(1)), 128119625d8cSopenharmony_ci "{} must be in {:?}", 128219625d8cSopenharmony_ci i, 128319625d8cSopenharmony_ci self.bounds 128419625d8cSopenharmony_ci ); 128519625d8cSopenharmony_ci l.cloned() 128619625d8cSopenharmony_ci } 128719625d8cSopenharmony_ci std::ops::Bound::Unbounded => self.bounds.start_bound().cloned(), 128819625d8cSopenharmony_ci }; 128919625d8cSopenharmony_ci let end = match range.end_bound() { 129019625d8cSopenharmony_ci l @ std::ops::Bound::Included(i) => { 129119625d8cSopenharmony_ci debug_assert!( 129219625d8cSopenharmony_ci self.bounds.contains(i), 129319625d8cSopenharmony_ci "{} must be in {:?}", 129419625d8cSopenharmony_ci i, 129519625d8cSopenharmony_ci self.bounds 129619625d8cSopenharmony_ci ); 129719625d8cSopenharmony_ci l.cloned() 129819625d8cSopenharmony_ci } 129919625d8cSopenharmony_ci l @ std::ops::Bound::Excluded(i) => { 130019625d8cSopenharmony_ci debug_assert!( 130119625d8cSopenharmony_ci self.bounds.contains(&i.saturating_sub(1)), 130219625d8cSopenharmony_ci "{} must be in {:?}", 130319625d8cSopenharmony_ci i, 130419625d8cSopenharmony_ci self.bounds 130519625d8cSopenharmony_ci ); 130619625d8cSopenharmony_ci l.cloned() 130719625d8cSopenharmony_ci } 130819625d8cSopenharmony_ci std::ops::Bound::Unbounded => self.bounds.end_bound().cloned(), 130919625d8cSopenharmony_ci }; 131019625d8cSopenharmony_ci self.bounds = (start, end); 131119625d8cSopenharmony_ci self 131219625d8cSopenharmony_ci } 131319625d8cSopenharmony_ci 131419625d8cSopenharmony_ci fn format_bounds(&self) -> String { 131519625d8cSopenharmony_ci let mut result = match self.bounds.0 { 131619625d8cSopenharmony_ci std::ops::Bound::Included(i) => i.to_string(), 131719625d8cSopenharmony_ci std::ops::Bound::Excluded(i) => i.saturating_add(1).to_string(), 131819625d8cSopenharmony_ci std::ops::Bound::Unbounded => i64::MIN.to_string(), 131919625d8cSopenharmony_ci }; 132019625d8cSopenharmony_ci result.push_str(".."); 132119625d8cSopenharmony_ci match self.bounds.1 { 132219625d8cSopenharmony_ci std::ops::Bound::Included(i) => { 132319625d8cSopenharmony_ci result.push('='); 132419625d8cSopenharmony_ci result.push_str(&i.to_string()); 132519625d8cSopenharmony_ci } 132619625d8cSopenharmony_ci std::ops::Bound::Excluded(i) => { 132719625d8cSopenharmony_ci result.push_str(&i.to_string()); 132819625d8cSopenharmony_ci } 132919625d8cSopenharmony_ci std::ops::Bound::Unbounded => { 133019625d8cSopenharmony_ci result.push_str(&i64::MAX.to_string()); 133119625d8cSopenharmony_ci } 133219625d8cSopenharmony_ci } 133319625d8cSopenharmony_ci result 133419625d8cSopenharmony_ci } 133519625d8cSopenharmony_ci} 133619625d8cSopenharmony_ci 133719625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<i64> + Clone + Send + Sync + 'static> TypedValueParser 133819625d8cSopenharmony_ci for RangedI64ValueParser<T> 133919625d8cSopenharmony_ciwhere 134019625d8cSopenharmony_ci <T as std::convert::TryFrom<i64>>::Error: Send + Sync + 'static + std::error::Error + ToString, 134119625d8cSopenharmony_ci{ 134219625d8cSopenharmony_ci type Value = T; 134319625d8cSopenharmony_ci 134419625d8cSopenharmony_ci fn parse_ref( 134519625d8cSopenharmony_ci &self, 134619625d8cSopenharmony_ci cmd: &crate::Command, 134719625d8cSopenharmony_ci arg: Option<&crate::Arg>, 134819625d8cSopenharmony_ci raw_value: &std::ffi::OsStr, 134919625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 135019625d8cSopenharmony_ci let value = ok!(raw_value.to_str().ok_or_else(|| { 135119625d8cSopenharmony_ci crate::Error::invalid_utf8( 135219625d8cSopenharmony_ci cmd, 135319625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 135419625d8cSopenharmony_ci ) 135519625d8cSopenharmony_ci })); 135619625d8cSopenharmony_ci let value = ok!(value.parse::<i64>().map_err(|err| { 135719625d8cSopenharmony_ci let arg = arg 135819625d8cSopenharmony_ci .map(|a| a.to_string()) 135919625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 136019625d8cSopenharmony_ci crate::Error::value_validation( 136119625d8cSopenharmony_ci arg, 136219625d8cSopenharmony_ci raw_value.to_string_lossy().into_owned(), 136319625d8cSopenharmony_ci err.into(), 136419625d8cSopenharmony_ci ) 136519625d8cSopenharmony_ci .with_cmd(cmd) 136619625d8cSopenharmony_ci })); 136719625d8cSopenharmony_ci if !self.bounds.contains(&value) { 136819625d8cSopenharmony_ci let arg = arg 136919625d8cSopenharmony_ci .map(|a| a.to_string()) 137019625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 137119625d8cSopenharmony_ci return Err(crate::Error::value_validation( 137219625d8cSopenharmony_ci arg, 137319625d8cSopenharmony_ci raw_value.to_string_lossy().into_owned(), 137419625d8cSopenharmony_ci format!("{} is not in {}", value, self.format_bounds()).into(), 137519625d8cSopenharmony_ci ) 137619625d8cSopenharmony_ci .with_cmd(cmd)); 137719625d8cSopenharmony_ci } 137819625d8cSopenharmony_ci 137919625d8cSopenharmony_ci let value: Result<Self::Value, _> = value.try_into(); 138019625d8cSopenharmony_ci let value = ok!(value.map_err(|err| { 138119625d8cSopenharmony_ci let arg = arg 138219625d8cSopenharmony_ci .map(|a| a.to_string()) 138319625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 138419625d8cSopenharmony_ci crate::Error::value_validation( 138519625d8cSopenharmony_ci arg, 138619625d8cSopenharmony_ci raw_value.to_string_lossy().into_owned(), 138719625d8cSopenharmony_ci err.into(), 138819625d8cSopenharmony_ci ) 138919625d8cSopenharmony_ci .with_cmd(cmd) 139019625d8cSopenharmony_ci })); 139119625d8cSopenharmony_ci 139219625d8cSopenharmony_ci Ok(value) 139319625d8cSopenharmony_ci } 139419625d8cSopenharmony_ci} 139519625d8cSopenharmony_ci 139619625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<i64> + Clone + Send + Sync, B: RangeBounds<i64>> From<B> 139719625d8cSopenharmony_ci for RangedI64ValueParser<T> 139819625d8cSopenharmony_ci{ 139919625d8cSopenharmony_ci fn from(range: B) -> Self { 140019625d8cSopenharmony_ci Self { 140119625d8cSopenharmony_ci bounds: (range.start_bound().cloned(), range.end_bound().cloned()), 140219625d8cSopenharmony_ci target: Default::default(), 140319625d8cSopenharmony_ci } 140419625d8cSopenharmony_ci } 140519625d8cSopenharmony_ci} 140619625d8cSopenharmony_ci 140719625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<i64> + Clone + Send + Sync> Default for RangedI64ValueParser<T> { 140819625d8cSopenharmony_ci fn default() -> Self { 140919625d8cSopenharmony_ci Self::new() 141019625d8cSopenharmony_ci } 141119625d8cSopenharmony_ci} 141219625d8cSopenharmony_ci 141319625d8cSopenharmony_ci/// Parse number that fall within a range of values 141419625d8cSopenharmony_ci/// 141519625d8cSopenharmony_ci/// # Example 141619625d8cSopenharmony_ci/// 141719625d8cSopenharmony_ci/// Usage: 141819625d8cSopenharmony_ci/// ```rust 141919625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 142019625d8cSopenharmony_ci/// .arg( 142119625d8cSopenharmony_ci/// clap::Arg::new("port") 142219625d8cSopenharmony_ci/// .long("port") 142319625d8cSopenharmony_ci/// .value_parser(clap::value_parser!(u64).range(3000..)) 142419625d8cSopenharmony_ci/// .action(clap::ArgAction::Set) 142519625d8cSopenharmony_ci/// .required(true) 142619625d8cSopenharmony_ci/// ); 142719625d8cSopenharmony_ci/// 142819625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "--port", "3001"]).unwrap(); 142919625d8cSopenharmony_ci/// let port: u64 = *m.get_one("port") 143019625d8cSopenharmony_ci/// .expect("required"); 143119625d8cSopenharmony_ci/// assert_eq!(port, 3001); 143219625d8cSopenharmony_ci/// ``` 143319625d8cSopenharmony_ci/// 143419625d8cSopenharmony_ci/// Semantics: 143519625d8cSopenharmony_ci/// ```rust 143619625d8cSopenharmony_ci/// # use std::ffi::OsStr; 143719625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 143819625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 143919625d8cSopenharmony_ci/// # let arg = None; 144019625d8cSopenharmony_ci/// let value_parser = clap::builder::RangedU64ValueParser::<u32>::new().range(0..200); 144119625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err()); 144219625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err()); 144319625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-200")).is_err()); 144419625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("300")).is_err()); 144519625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("-1")).is_err()); 144619625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), 0); 144719625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("50")).unwrap(), 50); 144819625d8cSopenharmony_ci/// ``` 144919625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 145019625d8cSopenharmony_cipub struct RangedU64ValueParser<T: std::convert::TryFrom<u64> = u64> { 145119625d8cSopenharmony_ci bounds: (std::ops::Bound<u64>, std::ops::Bound<u64>), 145219625d8cSopenharmony_ci target: std::marker::PhantomData<T>, 145319625d8cSopenharmony_ci} 145419625d8cSopenharmony_ci 145519625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<u64>> RangedU64ValueParser<T> { 145619625d8cSopenharmony_ci /// Select full range of `u64` 145719625d8cSopenharmony_ci pub fn new() -> Self { 145819625d8cSopenharmony_ci Self::from(..) 145919625d8cSopenharmony_ci } 146019625d8cSopenharmony_ci 146119625d8cSopenharmony_ci /// Narrow the supported range 146219625d8cSopenharmony_ci pub fn range<B: RangeBounds<u64>>(mut self, range: B) -> Self { 146319625d8cSopenharmony_ci // Consideration: when the user does `value_parser!(u8).range()` 146419625d8cSopenharmony_ci // - Avoid programming mistakes by accidentally expanding the range 146519625d8cSopenharmony_ci // - Make it convenient to limit the range like with `..10` 146619625d8cSopenharmony_ci let start = match range.start_bound() { 146719625d8cSopenharmony_ci l @ std::ops::Bound::Included(i) => { 146819625d8cSopenharmony_ci debug_assert!( 146919625d8cSopenharmony_ci self.bounds.contains(i), 147019625d8cSopenharmony_ci "{} must be in {:?}", 147119625d8cSopenharmony_ci i, 147219625d8cSopenharmony_ci self.bounds 147319625d8cSopenharmony_ci ); 147419625d8cSopenharmony_ci l.cloned() 147519625d8cSopenharmony_ci } 147619625d8cSopenharmony_ci l @ std::ops::Bound::Excluded(i) => { 147719625d8cSopenharmony_ci debug_assert!( 147819625d8cSopenharmony_ci self.bounds.contains(&i.saturating_add(1)), 147919625d8cSopenharmony_ci "{} must be in {:?}", 148019625d8cSopenharmony_ci i, 148119625d8cSopenharmony_ci self.bounds 148219625d8cSopenharmony_ci ); 148319625d8cSopenharmony_ci l.cloned() 148419625d8cSopenharmony_ci } 148519625d8cSopenharmony_ci std::ops::Bound::Unbounded => self.bounds.start_bound().cloned(), 148619625d8cSopenharmony_ci }; 148719625d8cSopenharmony_ci let end = match range.end_bound() { 148819625d8cSopenharmony_ci l @ std::ops::Bound::Included(i) => { 148919625d8cSopenharmony_ci debug_assert!( 149019625d8cSopenharmony_ci self.bounds.contains(i), 149119625d8cSopenharmony_ci "{} must be in {:?}", 149219625d8cSopenharmony_ci i, 149319625d8cSopenharmony_ci self.bounds 149419625d8cSopenharmony_ci ); 149519625d8cSopenharmony_ci l.cloned() 149619625d8cSopenharmony_ci } 149719625d8cSopenharmony_ci l @ std::ops::Bound::Excluded(i) => { 149819625d8cSopenharmony_ci debug_assert!( 149919625d8cSopenharmony_ci self.bounds.contains(&i.saturating_sub(1)), 150019625d8cSopenharmony_ci "{} must be in {:?}", 150119625d8cSopenharmony_ci i, 150219625d8cSopenharmony_ci self.bounds 150319625d8cSopenharmony_ci ); 150419625d8cSopenharmony_ci l.cloned() 150519625d8cSopenharmony_ci } 150619625d8cSopenharmony_ci std::ops::Bound::Unbounded => self.bounds.end_bound().cloned(), 150719625d8cSopenharmony_ci }; 150819625d8cSopenharmony_ci self.bounds = (start, end); 150919625d8cSopenharmony_ci self 151019625d8cSopenharmony_ci } 151119625d8cSopenharmony_ci 151219625d8cSopenharmony_ci fn format_bounds(&self) -> String { 151319625d8cSopenharmony_ci let mut result = match self.bounds.0 { 151419625d8cSopenharmony_ci std::ops::Bound::Included(i) => i.to_string(), 151519625d8cSopenharmony_ci std::ops::Bound::Excluded(i) => i.saturating_add(1).to_string(), 151619625d8cSopenharmony_ci std::ops::Bound::Unbounded => u64::MIN.to_string(), 151719625d8cSopenharmony_ci }; 151819625d8cSopenharmony_ci result.push_str(".."); 151919625d8cSopenharmony_ci match self.bounds.1 { 152019625d8cSopenharmony_ci std::ops::Bound::Included(i) => { 152119625d8cSopenharmony_ci result.push('='); 152219625d8cSopenharmony_ci result.push_str(&i.to_string()); 152319625d8cSopenharmony_ci } 152419625d8cSopenharmony_ci std::ops::Bound::Excluded(i) => { 152519625d8cSopenharmony_ci result.push_str(&i.to_string()); 152619625d8cSopenharmony_ci } 152719625d8cSopenharmony_ci std::ops::Bound::Unbounded => { 152819625d8cSopenharmony_ci result.push_str(&u64::MAX.to_string()); 152919625d8cSopenharmony_ci } 153019625d8cSopenharmony_ci } 153119625d8cSopenharmony_ci result 153219625d8cSopenharmony_ci } 153319625d8cSopenharmony_ci} 153419625d8cSopenharmony_ci 153519625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<u64> + Clone + Send + Sync + 'static> TypedValueParser 153619625d8cSopenharmony_ci for RangedU64ValueParser<T> 153719625d8cSopenharmony_ciwhere 153819625d8cSopenharmony_ci <T as std::convert::TryFrom<u64>>::Error: Send + Sync + 'static + std::error::Error + ToString, 153919625d8cSopenharmony_ci{ 154019625d8cSopenharmony_ci type Value = T; 154119625d8cSopenharmony_ci 154219625d8cSopenharmony_ci fn parse_ref( 154319625d8cSopenharmony_ci &self, 154419625d8cSopenharmony_ci cmd: &crate::Command, 154519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 154619625d8cSopenharmony_ci raw_value: &std::ffi::OsStr, 154719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 154819625d8cSopenharmony_ci let value = ok!(raw_value.to_str().ok_or_else(|| { 154919625d8cSopenharmony_ci crate::Error::invalid_utf8( 155019625d8cSopenharmony_ci cmd, 155119625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 155219625d8cSopenharmony_ci ) 155319625d8cSopenharmony_ci })); 155419625d8cSopenharmony_ci let value = ok!(value.parse::<u64>().map_err(|err| { 155519625d8cSopenharmony_ci let arg = arg 155619625d8cSopenharmony_ci .map(|a| a.to_string()) 155719625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 155819625d8cSopenharmony_ci crate::Error::value_validation( 155919625d8cSopenharmony_ci arg, 156019625d8cSopenharmony_ci raw_value.to_string_lossy().into_owned(), 156119625d8cSopenharmony_ci err.into(), 156219625d8cSopenharmony_ci ) 156319625d8cSopenharmony_ci .with_cmd(cmd) 156419625d8cSopenharmony_ci })); 156519625d8cSopenharmony_ci if !self.bounds.contains(&value) { 156619625d8cSopenharmony_ci let arg = arg 156719625d8cSopenharmony_ci .map(|a| a.to_string()) 156819625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 156919625d8cSopenharmony_ci return Err(crate::Error::value_validation( 157019625d8cSopenharmony_ci arg, 157119625d8cSopenharmony_ci raw_value.to_string_lossy().into_owned(), 157219625d8cSopenharmony_ci format!("{} is not in {}", value, self.format_bounds()).into(), 157319625d8cSopenharmony_ci ) 157419625d8cSopenharmony_ci .with_cmd(cmd)); 157519625d8cSopenharmony_ci } 157619625d8cSopenharmony_ci 157719625d8cSopenharmony_ci let value: Result<Self::Value, _> = value.try_into(); 157819625d8cSopenharmony_ci let value = ok!(value.map_err(|err| { 157919625d8cSopenharmony_ci let arg = arg 158019625d8cSopenharmony_ci .map(|a| a.to_string()) 158119625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 158219625d8cSopenharmony_ci crate::Error::value_validation( 158319625d8cSopenharmony_ci arg, 158419625d8cSopenharmony_ci raw_value.to_string_lossy().into_owned(), 158519625d8cSopenharmony_ci err.into(), 158619625d8cSopenharmony_ci ) 158719625d8cSopenharmony_ci .with_cmd(cmd) 158819625d8cSopenharmony_ci })); 158919625d8cSopenharmony_ci 159019625d8cSopenharmony_ci Ok(value) 159119625d8cSopenharmony_ci } 159219625d8cSopenharmony_ci} 159319625d8cSopenharmony_ci 159419625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<u64>, B: RangeBounds<u64>> From<B> for RangedU64ValueParser<T> { 159519625d8cSopenharmony_ci fn from(range: B) -> Self { 159619625d8cSopenharmony_ci Self { 159719625d8cSopenharmony_ci bounds: (range.start_bound().cloned(), range.end_bound().cloned()), 159819625d8cSopenharmony_ci target: Default::default(), 159919625d8cSopenharmony_ci } 160019625d8cSopenharmony_ci } 160119625d8cSopenharmony_ci} 160219625d8cSopenharmony_ci 160319625d8cSopenharmony_ciimpl<T: std::convert::TryFrom<u64>> Default for RangedU64ValueParser<T> { 160419625d8cSopenharmony_ci fn default() -> Self { 160519625d8cSopenharmony_ci Self::new() 160619625d8cSopenharmony_ci } 160719625d8cSopenharmony_ci} 160819625d8cSopenharmony_ci 160919625d8cSopenharmony_ci/// Implementation for [`ValueParser::bool`] 161019625d8cSopenharmony_ci/// 161119625d8cSopenharmony_ci/// Useful for composing new [`TypedValueParser`]s 161219625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 161319625d8cSopenharmony_ci#[non_exhaustive] 161419625d8cSopenharmony_cipub struct BoolValueParser {} 161519625d8cSopenharmony_ci 161619625d8cSopenharmony_ciimpl BoolValueParser { 161719625d8cSopenharmony_ci /// Implementation for [`ValueParser::bool`] 161819625d8cSopenharmony_ci pub fn new() -> Self { 161919625d8cSopenharmony_ci Self {} 162019625d8cSopenharmony_ci } 162119625d8cSopenharmony_ci 162219625d8cSopenharmony_ci fn possible_values() -> impl Iterator<Item = crate::builder::PossibleValue> { 162319625d8cSopenharmony_ci ["true", "false"] 162419625d8cSopenharmony_ci .iter() 162519625d8cSopenharmony_ci .copied() 162619625d8cSopenharmony_ci .map(crate::builder::PossibleValue::new) 162719625d8cSopenharmony_ci } 162819625d8cSopenharmony_ci} 162919625d8cSopenharmony_ci 163019625d8cSopenharmony_ciimpl TypedValueParser for BoolValueParser { 163119625d8cSopenharmony_ci type Value = bool; 163219625d8cSopenharmony_ci 163319625d8cSopenharmony_ci fn parse_ref( 163419625d8cSopenharmony_ci &self, 163519625d8cSopenharmony_ci cmd: &crate::Command, 163619625d8cSopenharmony_ci arg: Option<&crate::Arg>, 163719625d8cSopenharmony_ci value: &std::ffi::OsStr, 163819625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 163919625d8cSopenharmony_ci let value = if value == std::ffi::OsStr::new("true") { 164019625d8cSopenharmony_ci true 164119625d8cSopenharmony_ci } else if value == std::ffi::OsStr::new("false") { 164219625d8cSopenharmony_ci false 164319625d8cSopenharmony_ci } else { 164419625d8cSopenharmony_ci // Intentionally showing hidden as we hide all of them 164519625d8cSopenharmony_ci let possible_vals = Self::possible_values() 164619625d8cSopenharmony_ci .map(|v| v.get_name().to_owned()) 164719625d8cSopenharmony_ci .collect::<Vec<_>>(); 164819625d8cSopenharmony_ci 164919625d8cSopenharmony_ci return Err(crate::Error::invalid_value( 165019625d8cSopenharmony_ci cmd, 165119625d8cSopenharmony_ci value.to_string_lossy().into_owned(), 165219625d8cSopenharmony_ci &possible_vals, 165319625d8cSopenharmony_ci arg.map(ToString::to_string) 165419625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()), 165519625d8cSopenharmony_ci )); 165619625d8cSopenharmony_ci }; 165719625d8cSopenharmony_ci Ok(value) 165819625d8cSopenharmony_ci } 165919625d8cSopenharmony_ci 166019625d8cSopenharmony_ci fn possible_values( 166119625d8cSopenharmony_ci &self, 166219625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 166319625d8cSopenharmony_ci Some(Box::new(Self::possible_values())) 166419625d8cSopenharmony_ci } 166519625d8cSopenharmony_ci} 166619625d8cSopenharmony_ci 166719625d8cSopenharmony_ciimpl Default for BoolValueParser { 166819625d8cSopenharmony_ci fn default() -> Self { 166919625d8cSopenharmony_ci Self::new() 167019625d8cSopenharmony_ci } 167119625d8cSopenharmony_ci} 167219625d8cSopenharmony_ci 167319625d8cSopenharmony_ci/// Parse false-like string values, everything else is `true` 167419625d8cSopenharmony_ci/// 167519625d8cSopenharmony_ci/// See also: 167619625d8cSopenharmony_ci/// - [`ValueParser::bool`] for assuming non-false is true 167719625d8cSopenharmony_ci/// - [`BoolishValueParser`] for different human readable bool representations 167819625d8cSopenharmony_ci/// 167919625d8cSopenharmony_ci/// # Example 168019625d8cSopenharmony_ci/// 168119625d8cSopenharmony_ci/// Usage: 168219625d8cSopenharmony_ci/// ```rust 168319625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 168419625d8cSopenharmony_ci/// .arg( 168519625d8cSopenharmony_ci/// clap::Arg::new("append") 168619625d8cSopenharmony_ci/// .value_parser(clap::builder::FalseyValueParser::new()) 168719625d8cSopenharmony_ci/// .required(true) 168819625d8cSopenharmony_ci/// ); 168919625d8cSopenharmony_ci/// 169019625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap(); 169119625d8cSopenharmony_ci/// let port: bool = *m.get_one("append") 169219625d8cSopenharmony_ci/// .expect("required"); 169319625d8cSopenharmony_ci/// assert_eq!(port, true); 169419625d8cSopenharmony_ci/// ``` 169519625d8cSopenharmony_ci/// 169619625d8cSopenharmony_ci/// Semantics: 169719625d8cSopenharmony_ci/// ```rust 169819625d8cSopenharmony_ci/// # use std::ffi::OsStr; 169919625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 170019625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 170119625d8cSopenharmony_ci/// # let arg = None; 170219625d8cSopenharmony_ci/// let value_parser = clap::builder::FalseyValueParser::new(); 170319625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).unwrap(), true); 170419625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("100")).unwrap(), true); 170519625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).unwrap(), false); 170619625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("false")).unwrap(), false); 170719625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("No")).unwrap(), false); 170819625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oFF")).unwrap(), false); 170919625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), false); 171019625d8cSopenharmony_ci/// ``` 171119625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 171219625d8cSopenharmony_ci#[non_exhaustive] 171319625d8cSopenharmony_cipub struct FalseyValueParser {} 171419625d8cSopenharmony_ci 171519625d8cSopenharmony_ciimpl FalseyValueParser { 171619625d8cSopenharmony_ci /// Parse false-like string values, everything else is `true` 171719625d8cSopenharmony_ci pub fn new() -> Self { 171819625d8cSopenharmony_ci Self {} 171919625d8cSopenharmony_ci } 172019625d8cSopenharmony_ci 172119625d8cSopenharmony_ci fn possible_values() -> impl Iterator<Item = crate::builder::PossibleValue> { 172219625d8cSopenharmony_ci crate::util::TRUE_LITERALS 172319625d8cSopenharmony_ci .iter() 172419625d8cSopenharmony_ci .chain(crate::util::FALSE_LITERALS.iter()) 172519625d8cSopenharmony_ci .copied() 172619625d8cSopenharmony_ci .map(|l| crate::builder::PossibleValue::new(l).hide(l != "true" && l != "false")) 172719625d8cSopenharmony_ci } 172819625d8cSopenharmony_ci} 172919625d8cSopenharmony_ci 173019625d8cSopenharmony_ciimpl TypedValueParser for FalseyValueParser { 173119625d8cSopenharmony_ci type Value = bool; 173219625d8cSopenharmony_ci 173319625d8cSopenharmony_ci fn parse_ref( 173419625d8cSopenharmony_ci &self, 173519625d8cSopenharmony_ci cmd: &crate::Command, 173619625d8cSopenharmony_ci _arg: Option<&crate::Arg>, 173719625d8cSopenharmony_ci value: &std::ffi::OsStr, 173819625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 173919625d8cSopenharmony_ci let value = ok!(value.to_str().ok_or_else(|| { 174019625d8cSopenharmony_ci crate::Error::invalid_utf8( 174119625d8cSopenharmony_ci cmd, 174219625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 174319625d8cSopenharmony_ci ) 174419625d8cSopenharmony_ci })); 174519625d8cSopenharmony_ci let value = if value.is_empty() { 174619625d8cSopenharmony_ci false 174719625d8cSopenharmony_ci } else { 174819625d8cSopenharmony_ci crate::util::str_to_bool(value).unwrap_or(true) 174919625d8cSopenharmony_ci }; 175019625d8cSopenharmony_ci Ok(value) 175119625d8cSopenharmony_ci } 175219625d8cSopenharmony_ci 175319625d8cSopenharmony_ci fn possible_values( 175419625d8cSopenharmony_ci &self, 175519625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 175619625d8cSopenharmony_ci Some(Box::new(Self::possible_values())) 175719625d8cSopenharmony_ci } 175819625d8cSopenharmony_ci} 175919625d8cSopenharmony_ci 176019625d8cSopenharmony_ciimpl Default for FalseyValueParser { 176119625d8cSopenharmony_ci fn default() -> Self { 176219625d8cSopenharmony_ci Self::new() 176319625d8cSopenharmony_ci } 176419625d8cSopenharmony_ci} 176519625d8cSopenharmony_ci 176619625d8cSopenharmony_ci/// Parse bool-like string values, everything else is `true` 176719625d8cSopenharmony_ci/// 176819625d8cSopenharmony_ci/// See also: 176919625d8cSopenharmony_ci/// - [`ValueParser::bool`] for different human readable bool representations 177019625d8cSopenharmony_ci/// - [`FalseyValueParser`] for assuming non-false is true 177119625d8cSopenharmony_ci/// 177219625d8cSopenharmony_ci/// # Example 177319625d8cSopenharmony_ci/// 177419625d8cSopenharmony_ci/// Usage: 177519625d8cSopenharmony_ci/// ```rust 177619625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 177719625d8cSopenharmony_ci/// .arg( 177819625d8cSopenharmony_ci/// clap::Arg::new("append") 177919625d8cSopenharmony_ci/// .value_parser(clap::builder::BoolishValueParser::new()) 178019625d8cSopenharmony_ci/// .required(true) 178119625d8cSopenharmony_ci/// ); 178219625d8cSopenharmony_ci/// 178319625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap(); 178419625d8cSopenharmony_ci/// let port: bool = *m.get_one("append") 178519625d8cSopenharmony_ci/// .expect("required"); 178619625d8cSopenharmony_ci/// assert_eq!(port, true); 178719625d8cSopenharmony_ci/// ``` 178819625d8cSopenharmony_ci/// 178919625d8cSopenharmony_ci/// Semantics: 179019625d8cSopenharmony_ci/// ```rust 179119625d8cSopenharmony_ci/// # use std::ffi::OsStr; 179219625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 179319625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 179419625d8cSopenharmony_ci/// # let arg = None; 179519625d8cSopenharmony_ci/// let value_parser = clap::builder::BoolishValueParser::new(); 179619625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).is_err()); 179719625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err()); 179819625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("100")).is_err()); 179919625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("true")).unwrap(), true); 180019625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("Yes")).unwrap(), true); 180119625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oN")).unwrap(), true); 180219625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("1")).unwrap(), true); 180319625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("false")).unwrap(), false); 180419625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("No")).unwrap(), false); 180519625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("oFF")).unwrap(), false); 180619625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("0")).unwrap(), false); 180719625d8cSopenharmony_ci/// ``` 180819625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 180919625d8cSopenharmony_ci#[non_exhaustive] 181019625d8cSopenharmony_cipub struct BoolishValueParser {} 181119625d8cSopenharmony_ci 181219625d8cSopenharmony_ciimpl BoolishValueParser { 181319625d8cSopenharmony_ci /// Parse bool-like string values, everything else is `true` 181419625d8cSopenharmony_ci pub fn new() -> Self { 181519625d8cSopenharmony_ci Self {} 181619625d8cSopenharmony_ci } 181719625d8cSopenharmony_ci 181819625d8cSopenharmony_ci fn possible_values() -> impl Iterator<Item = crate::builder::PossibleValue> { 181919625d8cSopenharmony_ci crate::util::TRUE_LITERALS 182019625d8cSopenharmony_ci .iter() 182119625d8cSopenharmony_ci .chain(crate::util::FALSE_LITERALS.iter()) 182219625d8cSopenharmony_ci .copied() 182319625d8cSopenharmony_ci .map(|l| crate::builder::PossibleValue::new(l).hide(l != "true" && l != "false")) 182419625d8cSopenharmony_ci } 182519625d8cSopenharmony_ci} 182619625d8cSopenharmony_ci 182719625d8cSopenharmony_ciimpl TypedValueParser for BoolishValueParser { 182819625d8cSopenharmony_ci type Value = bool; 182919625d8cSopenharmony_ci 183019625d8cSopenharmony_ci fn parse_ref( 183119625d8cSopenharmony_ci &self, 183219625d8cSopenharmony_ci cmd: &crate::Command, 183319625d8cSopenharmony_ci arg: Option<&crate::Arg>, 183419625d8cSopenharmony_ci value: &std::ffi::OsStr, 183519625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 183619625d8cSopenharmony_ci let value = ok!(value.to_str().ok_or_else(|| { 183719625d8cSopenharmony_ci crate::Error::invalid_utf8( 183819625d8cSopenharmony_ci cmd, 183919625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 184019625d8cSopenharmony_ci ) 184119625d8cSopenharmony_ci })); 184219625d8cSopenharmony_ci let value = ok!(crate::util::str_to_bool(value).ok_or_else(|| { 184319625d8cSopenharmony_ci let arg = arg 184419625d8cSopenharmony_ci .map(|a| a.to_string()) 184519625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 184619625d8cSopenharmony_ci crate::Error::value_validation(arg, value.to_owned(), "value was not a boolean".into()) 184719625d8cSopenharmony_ci .with_cmd(cmd) 184819625d8cSopenharmony_ci })); 184919625d8cSopenharmony_ci Ok(value) 185019625d8cSopenharmony_ci } 185119625d8cSopenharmony_ci 185219625d8cSopenharmony_ci fn possible_values( 185319625d8cSopenharmony_ci &self, 185419625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 185519625d8cSopenharmony_ci Some(Box::new(Self::possible_values())) 185619625d8cSopenharmony_ci } 185719625d8cSopenharmony_ci} 185819625d8cSopenharmony_ci 185919625d8cSopenharmony_ciimpl Default for BoolishValueParser { 186019625d8cSopenharmony_ci fn default() -> Self { 186119625d8cSopenharmony_ci Self::new() 186219625d8cSopenharmony_ci } 186319625d8cSopenharmony_ci} 186419625d8cSopenharmony_ci 186519625d8cSopenharmony_ci/// Parse non-empty string values 186619625d8cSopenharmony_ci/// 186719625d8cSopenharmony_ci/// See also: 186819625d8cSopenharmony_ci/// - [`ValueParser::string`] 186919625d8cSopenharmony_ci/// 187019625d8cSopenharmony_ci/// # Example 187119625d8cSopenharmony_ci/// 187219625d8cSopenharmony_ci/// Usage: 187319625d8cSopenharmony_ci/// ```rust 187419625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 187519625d8cSopenharmony_ci/// .arg( 187619625d8cSopenharmony_ci/// clap::Arg::new("append") 187719625d8cSopenharmony_ci/// .value_parser(clap::builder::NonEmptyStringValueParser::new()) 187819625d8cSopenharmony_ci/// .required(true) 187919625d8cSopenharmony_ci/// ); 188019625d8cSopenharmony_ci/// 188119625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "true"]).unwrap(); 188219625d8cSopenharmony_ci/// let port: &String = m.get_one("append") 188319625d8cSopenharmony_ci/// .expect("required"); 188419625d8cSopenharmony_ci/// assert_eq!(port, "true"); 188519625d8cSopenharmony_ci/// ``` 188619625d8cSopenharmony_ci/// 188719625d8cSopenharmony_ci/// Semantics: 188819625d8cSopenharmony_ci/// ```rust 188919625d8cSopenharmony_ci/// # use std::ffi::OsStr; 189019625d8cSopenharmony_ci/// # use clap::builder::TypedValueParser; 189119625d8cSopenharmony_ci/// # let cmd = clap::Command::new("test"); 189219625d8cSopenharmony_ci/// # let arg = None; 189319625d8cSopenharmony_ci/// let value_parser = clap::builder::NonEmptyStringValueParser::new(); 189419625d8cSopenharmony_ci/// assert_eq!(value_parser.parse_ref(&cmd, arg, OsStr::new("random")).unwrap(), "random"); 189519625d8cSopenharmony_ci/// assert!(value_parser.parse_ref(&cmd, arg, OsStr::new("")).is_err()); 189619625d8cSopenharmony_ci/// ``` 189719625d8cSopenharmony_ci#[derive(Copy, Clone, Debug)] 189819625d8cSopenharmony_ci#[non_exhaustive] 189919625d8cSopenharmony_cipub struct NonEmptyStringValueParser {} 190019625d8cSopenharmony_ci 190119625d8cSopenharmony_ciimpl NonEmptyStringValueParser { 190219625d8cSopenharmony_ci /// Parse non-empty string values 190319625d8cSopenharmony_ci pub fn new() -> Self { 190419625d8cSopenharmony_ci Self {} 190519625d8cSopenharmony_ci } 190619625d8cSopenharmony_ci} 190719625d8cSopenharmony_ci 190819625d8cSopenharmony_ciimpl TypedValueParser for NonEmptyStringValueParser { 190919625d8cSopenharmony_ci type Value = String; 191019625d8cSopenharmony_ci 191119625d8cSopenharmony_ci fn parse_ref( 191219625d8cSopenharmony_ci &self, 191319625d8cSopenharmony_ci cmd: &crate::Command, 191419625d8cSopenharmony_ci arg: Option<&crate::Arg>, 191519625d8cSopenharmony_ci value: &std::ffi::OsStr, 191619625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 191719625d8cSopenharmony_ci if value.is_empty() { 191819625d8cSopenharmony_ci return Err(crate::Error::empty_value( 191919625d8cSopenharmony_ci cmd, 192019625d8cSopenharmony_ci &[], 192119625d8cSopenharmony_ci arg.map(ToString::to_string) 192219625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()), 192319625d8cSopenharmony_ci )); 192419625d8cSopenharmony_ci } 192519625d8cSopenharmony_ci let value = ok!(value.to_str().ok_or_else(|| { 192619625d8cSopenharmony_ci crate::Error::invalid_utf8( 192719625d8cSopenharmony_ci cmd, 192819625d8cSopenharmony_ci crate::output::Usage::new(cmd).create_usage_with_title(&[]), 192919625d8cSopenharmony_ci ) 193019625d8cSopenharmony_ci })); 193119625d8cSopenharmony_ci Ok(value.to_owned()) 193219625d8cSopenharmony_ci } 193319625d8cSopenharmony_ci} 193419625d8cSopenharmony_ci 193519625d8cSopenharmony_ciimpl Default for NonEmptyStringValueParser { 193619625d8cSopenharmony_ci fn default() -> Self { 193719625d8cSopenharmony_ci Self::new() 193819625d8cSopenharmony_ci } 193919625d8cSopenharmony_ci} 194019625d8cSopenharmony_ci 194119625d8cSopenharmony_ci/// Adapt a `TypedValueParser` from one value to another 194219625d8cSopenharmony_ci/// 194319625d8cSopenharmony_ci/// See [`TypedValueParser::map`] 194419625d8cSopenharmony_ci#[derive(Clone, Debug)] 194519625d8cSopenharmony_cipub struct MapValueParser<P, F> { 194619625d8cSopenharmony_ci parser: P, 194719625d8cSopenharmony_ci func: F, 194819625d8cSopenharmony_ci} 194919625d8cSopenharmony_ci 195019625d8cSopenharmony_ciimpl<P, F, T> MapValueParser<P, F> 195119625d8cSopenharmony_ciwhere 195219625d8cSopenharmony_ci P: TypedValueParser, 195319625d8cSopenharmony_ci P::Value: Send + Sync + Clone, 195419625d8cSopenharmony_ci F: Fn(P::Value) -> T + Clone, 195519625d8cSopenharmony_ci T: Send + Sync + Clone, 195619625d8cSopenharmony_ci{ 195719625d8cSopenharmony_ci fn new(parser: P, func: F) -> Self { 195819625d8cSopenharmony_ci Self { parser, func } 195919625d8cSopenharmony_ci } 196019625d8cSopenharmony_ci} 196119625d8cSopenharmony_ci 196219625d8cSopenharmony_ciimpl<P, F, T> TypedValueParser for MapValueParser<P, F> 196319625d8cSopenharmony_ciwhere 196419625d8cSopenharmony_ci P: TypedValueParser, 196519625d8cSopenharmony_ci P::Value: Send + Sync + Clone, 196619625d8cSopenharmony_ci F: Fn(P::Value) -> T + Clone + Send + Sync + 'static, 196719625d8cSopenharmony_ci T: Send + Sync + Clone, 196819625d8cSopenharmony_ci{ 196919625d8cSopenharmony_ci type Value = T; 197019625d8cSopenharmony_ci 197119625d8cSopenharmony_ci fn parse_ref( 197219625d8cSopenharmony_ci &self, 197319625d8cSopenharmony_ci cmd: &crate::Command, 197419625d8cSopenharmony_ci arg: Option<&crate::Arg>, 197519625d8cSopenharmony_ci value: &std::ffi::OsStr, 197619625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 197719625d8cSopenharmony_ci let value = ok!(self.parser.parse_ref(cmd, arg, value)); 197819625d8cSopenharmony_ci let value = (self.func)(value); 197919625d8cSopenharmony_ci Ok(value) 198019625d8cSopenharmony_ci } 198119625d8cSopenharmony_ci 198219625d8cSopenharmony_ci fn parse( 198319625d8cSopenharmony_ci &self, 198419625d8cSopenharmony_ci cmd: &crate::Command, 198519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 198619625d8cSopenharmony_ci value: std::ffi::OsString, 198719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 198819625d8cSopenharmony_ci let value = ok!(self.parser.parse(cmd, arg, value)); 198919625d8cSopenharmony_ci let value = (self.func)(value); 199019625d8cSopenharmony_ci Ok(value) 199119625d8cSopenharmony_ci } 199219625d8cSopenharmony_ci 199319625d8cSopenharmony_ci fn possible_values( 199419625d8cSopenharmony_ci &self, 199519625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 199619625d8cSopenharmony_ci self.parser.possible_values() 199719625d8cSopenharmony_ci } 199819625d8cSopenharmony_ci} 199919625d8cSopenharmony_ci 200019625d8cSopenharmony_ci/// Adapt a `TypedValueParser` from one value to another 200119625d8cSopenharmony_ci/// 200219625d8cSopenharmony_ci/// See [`TypedValueParser::try_map`] 200319625d8cSopenharmony_ci#[derive(Clone, Debug)] 200419625d8cSopenharmony_cipub struct TryMapValueParser<P, F> { 200519625d8cSopenharmony_ci parser: P, 200619625d8cSopenharmony_ci func: F, 200719625d8cSopenharmony_ci} 200819625d8cSopenharmony_ci 200919625d8cSopenharmony_ciimpl<P, F, T, E> TryMapValueParser<P, F> 201019625d8cSopenharmony_ciwhere 201119625d8cSopenharmony_ci P: TypedValueParser, 201219625d8cSopenharmony_ci P::Value: Send + Sync + Clone, 201319625d8cSopenharmony_ci F: Fn(P::Value) -> Result<T, E> + Clone + Send + Sync + 'static, 201419625d8cSopenharmony_ci T: Send + Sync + Clone, 201519625d8cSopenharmony_ci E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, 201619625d8cSopenharmony_ci{ 201719625d8cSopenharmony_ci fn new(parser: P, func: F) -> Self { 201819625d8cSopenharmony_ci Self { parser, func } 201919625d8cSopenharmony_ci } 202019625d8cSopenharmony_ci} 202119625d8cSopenharmony_ci 202219625d8cSopenharmony_ciimpl<P, F, T, E> TypedValueParser for TryMapValueParser<P, F> 202319625d8cSopenharmony_ciwhere 202419625d8cSopenharmony_ci P: TypedValueParser, 202519625d8cSopenharmony_ci P::Value: Send + Sync + Clone, 202619625d8cSopenharmony_ci F: Fn(P::Value) -> Result<T, E> + Clone + Send + Sync + 'static, 202719625d8cSopenharmony_ci T: Send + Sync + Clone, 202819625d8cSopenharmony_ci E: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, 202919625d8cSopenharmony_ci{ 203019625d8cSopenharmony_ci type Value = T; 203119625d8cSopenharmony_ci 203219625d8cSopenharmony_ci fn parse_ref( 203319625d8cSopenharmony_ci &self, 203419625d8cSopenharmony_ci cmd: &crate::Command, 203519625d8cSopenharmony_ci arg: Option<&crate::Arg>, 203619625d8cSopenharmony_ci value: &std::ffi::OsStr, 203719625d8cSopenharmony_ci ) -> Result<Self::Value, crate::Error> { 203819625d8cSopenharmony_ci let mid_value = ok!(self.parser.parse_ref(cmd, arg, value)); 203919625d8cSopenharmony_ci let value = ok!((self.func)(mid_value).map_err(|e| { 204019625d8cSopenharmony_ci let arg = arg 204119625d8cSopenharmony_ci .map(|a| a.to_string()) 204219625d8cSopenharmony_ci .unwrap_or_else(|| "...".to_owned()); 204319625d8cSopenharmony_ci crate::Error::value_validation(arg, value.to_string_lossy().into_owned(), e.into()) 204419625d8cSopenharmony_ci .with_cmd(cmd) 204519625d8cSopenharmony_ci })); 204619625d8cSopenharmony_ci Ok(value) 204719625d8cSopenharmony_ci } 204819625d8cSopenharmony_ci 204919625d8cSopenharmony_ci fn possible_values( 205019625d8cSopenharmony_ci &self, 205119625d8cSopenharmony_ci ) -> Option<Box<dyn Iterator<Item = crate::builder::PossibleValue> + '_>> { 205219625d8cSopenharmony_ci self.parser.possible_values() 205319625d8cSopenharmony_ci } 205419625d8cSopenharmony_ci} 205519625d8cSopenharmony_ci 205619625d8cSopenharmony_ci/// Register a type with [value_parser!][crate::value_parser!] 205719625d8cSopenharmony_ci/// 205819625d8cSopenharmony_ci/// # Example 205919625d8cSopenharmony_ci/// 206019625d8cSopenharmony_ci/// ```rust 206119625d8cSopenharmony_ci/// #[derive(Copy, Clone, Debug)] 206219625d8cSopenharmony_ci/// pub struct Custom(u32); 206319625d8cSopenharmony_ci/// 206419625d8cSopenharmony_ci/// impl clap::builder::ValueParserFactory for Custom { 206519625d8cSopenharmony_ci/// type Parser = CustomValueParser; 206619625d8cSopenharmony_ci/// fn value_parser() -> Self::Parser { 206719625d8cSopenharmony_ci/// CustomValueParser 206819625d8cSopenharmony_ci/// } 206919625d8cSopenharmony_ci/// } 207019625d8cSopenharmony_ci/// 207119625d8cSopenharmony_ci/// #[derive(Clone, Debug)] 207219625d8cSopenharmony_ci/// pub struct CustomValueParser; 207319625d8cSopenharmony_ci/// impl clap::builder::TypedValueParser for CustomValueParser { 207419625d8cSopenharmony_ci/// type Value = Custom; 207519625d8cSopenharmony_ci/// 207619625d8cSopenharmony_ci/// fn parse_ref( 207719625d8cSopenharmony_ci/// &self, 207819625d8cSopenharmony_ci/// cmd: &clap::Command, 207919625d8cSopenharmony_ci/// arg: Option<&clap::Arg>, 208019625d8cSopenharmony_ci/// value: &std::ffi::OsStr, 208119625d8cSopenharmony_ci/// ) -> Result<Self::Value, clap::Error> { 208219625d8cSopenharmony_ci/// let inner = clap::value_parser!(u32); 208319625d8cSopenharmony_ci/// let val = inner.parse_ref(cmd, arg, value)?; 208419625d8cSopenharmony_ci/// Ok(Custom(val)) 208519625d8cSopenharmony_ci/// } 208619625d8cSopenharmony_ci/// } 208719625d8cSopenharmony_ci/// 208819625d8cSopenharmony_ci/// let parser: CustomValueParser = clap::value_parser!(Custom); 208919625d8cSopenharmony_ci/// ``` 209019625d8cSopenharmony_cipub trait ValueParserFactory { 209119625d8cSopenharmony_ci /// Generated parser, usually [`ValueParser`]. 209219625d8cSopenharmony_ci /// 209319625d8cSopenharmony_ci /// It should at least be a type that supports `Into<ValueParser>`. A non-`ValueParser` type 209419625d8cSopenharmony_ci /// allows the caller to do further initialization on the parser. 209519625d8cSopenharmony_ci type Parser; 209619625d8cSopenharmony_ci 209719625d8cSopenharmony_ci /// Create the specified [`Self::Parser`] 209819625d8cSopenharmony_ci fn value_parser() -> Self::Parser; 209919625d8cSopenharmony_ci} 210019625d8cSopenharmony_ciimpl ValueParserFactory for String { 210119625d8cSopenharmony_ci type Parser = ValueParser; 210219625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 210319625d8cSopenharmony_ci ValueParser::string() // Default `clap_derive` to optimized implementation 210419625d8cSopenharmony_ci } 210519625d8cSopenharmony_ci} 210619625d8cSopenharmony_ciimpl ValueParserFactory for std::ffi::OsString { 210719625d8cSopenharmony_ci type Parser = ValueParser; 210819625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 210919625d8cSopenharmony_ci ValueParser::os_string() // Default `clap_derive` to optimized implementation 211019625d8cSopenharmony_ci } 211119625d8cSopenharmony_ci} 211219625d8cSopenharmony_ciimpl ValueParserFactory for std::path::PathBuf { 211319625d8cSopenharmony_ci type Parser = ValueParser; 211419625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 211519625d8cSopenharmony_ci ValueParser::path_buf() // Default `clap_derive` to optimized implementation 211619625d8cSopenharmony_ci } 211719625d8cSopenharmony_ci} 211819625d8cSopenharmony_ciimpl ValueParserFactory for bool { 211919625d8cSopenharmony_ci type Parser = ValueParser; 212019625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 212119625d8cSopenharmony_ci ValueParser::bool() // Default `clap_derive` to optimized implementation 212219625d8cSopenharmony_ci } 212319625d8cSopenharmony_ci} 212419625d8cSopenharmony_ciimpl ValueParserFactory for u8 { 212519625d8cSopenharmony_ci type Parser = RangedI64ValueParser<u8>; 212619625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 212719625d8cSopenharmony_ci let start: i64 = u8::MIN.into(); 212819625d8cSopenharmony_ci let end: i64 = u8::MAX.into(); 212919625d8cSopenharmony_ci RangedI64ValueParser::new().range(start..=end) 213019625d8cSopenharmony_ci } 213119625d8cSopenharmony_ci} 213219625d8cSopenharmony_ciimpl ValueParserFactory for i8 { 213319625d8cSopenharmony_ci type Parser = RangedI64ValueParser<i8>; 213419625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 213519625d8cSopenharmony_ci let start: i64 = i8::MIN.into(); 213619625d8cSopenharmony_ci let end: i64 = i8::MAX.into(); 213719625d8cSopenharmony_ci RangedI64ValueParser::new().range(start..=end) 213819625d8cSopenharmony_ci } 213919625d8cSopenharmony_ci} 214019625d8cSopenharmony_ciimpl ValueParserFactory for u16 { 214119625d8cSopenharmony_ci type Parser = RangedI64ValueParser<u16>; 214219625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 214319625d8cSopenharmony_ci let start: i64 = u16::MIN.into(); 214419625d8cSopenharmony_ci let end: i64 = u16::MAX.into(); 214519625d8cSopenharmony_ci RangedI64ValueParser::new().range(start..=end) 214619625d8cSopenharmony_ci } 214719625d8cSopenharmony_ci} 214819625d8cSopenharmony_ciimpl ValueParserFactory for i16 { 214919625d8cSopenharmony_ci type Parser = RangedI64ValueParser<i16>; 215019625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 215119625d8cSopenharmony_ci let start: i64 = i16::MIN.into(); 215219625d8cSopenharmony_ci let end: i64 = i16::MAX.into(); 215319625d8cSopenharmony_ci RangedI64ValueParser::new().range(start..=end) 215419625d8cSopenharmony_ci } 215519625d8cSopenharmony_ci} 215619625d8cSopenharmony_ciimpl ValueParserFactory for u32 { 215719625d8cSopenharmony_ci type Parser = RangedI64ValueParser<u32>; 215819625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 215919625d8cSopenharmony_ci let start: i64 = u32::MIN.into(); 216019625d8cSopenharmony_ci let end: i64 = u32::MAX.into(); 216119625d8cSopenharmony_ci RangedI64ValueParser::new().range(start..=end) 216219625d8cSopenharmony_ci } 216319625d8cSopenharmony_ci} 216419625d8cSopenharmony_ciimpl ValueParserFactory for i32 { 216519625d8cSopenharmony_ci type Parser = RangedI64ValueParser<i32>; 216619625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 216719625d8cSopenharmony_ci let start: i64 = i32::MIN.into(); 216819625d8cSopenharmony_ci let end: i64 = i32::MAX.into(); 216919625d8cSopenharmony_ci RangedI64ValueParser::new().range(start..=end) 217019625d8cSopenharmony_ci } 217119625d8cSopenharmony_ci} 217219625d8cSopenharmony_ciimpl ValueParserFactory for i64 { 217319625d8cSopenharmony_ci type Parser = RangedI64ValueParser<i64>; 217419625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 217519625d8cSopenharmony_ci RangedI64ValueParser::new() 217619625d8cSopenharmony_ci } 217719625d8cSopenharmony_ci} 217819625d8cSopenharmony_ciimpl ValueParserFactory for u64 { 217919625d8cSopenharmony_ci type Parser = RangedU64ValueParser<u64>; 218019625d8cSopenharmony_ci fn value_parser() -> Self::Parser { 218119625d8cSopenharmony_ci RangedU64ValueParser::new() 218219625d8cSopenharmony_ci } 218319625d8cSopenharmony_ci} 218419625d8cSopenharmony_ci 218519625d8cSopenharmony_ci#[doc(hidden)] 218619625d8cSopenharmony_ci#[derive(Debug)] 218719625d8cSopenharmony_cipub struct _AutoValueParser<T>(std::marker::PhantomData<T>); 218819625d8cSopenharmony_ci 218919625d8cSopenharmony_ciimpl<T> _AutoValueParser<T> { 219019625d8cSopenharmony_ci #[doc(hidden)] 219119625d8cSopenharmony_ci #[allow(clippy::new_without_default)] 219219625d8cSopenharmony_ci pub fn new() -> Self { 219319625d8cSopenharmony_ci Self(Default::default()) 219419625d8cSopenharmony_ci } 219519625d8cSopenharmony_ci} 219619625d8cSopenharmony_ci 219719625d8cSopenharmony_ci/// Unstable [`ValueParser`] 219819625d8cSopenharmony_ci/// 219919625d8cSopenharmony_ci/// Implementation may change to more specific instance in the future 220019625d8cSopenharmony_ci#[doc(hidden)] 220119625d8cSopenharmony_ci#[derive(Debug)] 220219625d8cSopenharmony_cipub struct _AnonymousValueParser(ValueParser); 220319625d8cSopenharmony_ci 220419625d8cSopenharmony_ci#[doc(hidden)] 220519625d8cSopenharmony_cipub mod via_prelude { 220619625d8cSopenharmony_ci use super::*; 220719625d8cSopenharmony_ci 220819625d8cSopenharmony_ci #[doc(hidden)] 220919625d8cSopenharmony_ci pub trait _ValueParserViaFactory: private::_ValueParserViaFactorySealed { 221019625d8cSopenharmony_ci type Parser; 221119625d8cSopenharmony_ci fn value_parser(&self) -> Self::Parser; 221219625d8cSopenharmony_ci } 221319625d8cSopenharmony_ci impl<P: ValueParserFactory> _ValueParserViaFactory for &&&&&&_AutoValueParser<P> { 221419625d8cSopenharmony_ci type Parser = P::Parser; 221519625d8cSopenharmony_ci fn value_parser(&self) -> Self::Parser { 221619625d8cSopenharmony_ci P::value_parser() 221719625d8cSopenharmony_ci } 221819625d8cSopenharmony_ci } 221919625d8cSopenharmony_ci 222019625d8cSopenharmony_ci #[doc(hidden)] 222119625d8cSopenharmony_ci pub trait _ValueParserViaValueEnum: private::_ValueParserViaValueEnumSealed { 222219625d8cSopenharmony_ci type Output; 222319625d8cSopenharmony_ci 222419625d8cSopenharmony_ci fn value_parser(&self) -> Self::Output; 222519625d8cSopenharmony_ci } 222619625d8cSopenharmony_ci impl<E: crate::ValueEnum + Clone + Send + Sync + 'static> _ValueParserViaValueEnum 222719625d8cSopenharmony_ci for &&&&&_AutoValueParser<E> 222819625d8cSopenharmony_ci { 222919625d8cSopenharmony_ci type Output = EnumValueParser<E>; 223019625d8cSopenharmony_ci 223119625d8cSopenharmony_ci fn value_parser(&self) -> Self::Output { 223219625d8cSopenharmony_ci EnumValueParser::<E>::new() 223319625d8cSopenharmony_ci } 223419625d8cSopenharmony_ci } 223519625d8cSopenharmony_ci 223619625d8cSopenharmony_ci #[doc(hidden)] 223719625d8cSopenharmony_ci pub trait _ValueParserViaFromOsString: private::_ValueParserViaFromOsStringSealed { 223819625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser; 223919625d8cSopenharmony_ci } 224019625d8cSopenharmony_ci impl<FromOsString> _ValueParserViaFromOsString for &&&&_AutoValueParser<FromOsString> 224119625d8cSopenharmony_ci where 224219625d8cSopenharmony_ci FromOsString: From<std::ffi::OsString> + std::any::Any + Clone + Send + Sync + 'static, 224319625d8cSopenharmony_ci { 224419625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser { 224519625d8cSopenharmony_ci _AnonymousValueParser( 224619625d8cSopenharmony_ci OsStringValueParser::new() 224719625d8cSopenharmony_ci .map(|s| FromOsString::from(s)) 224819625d8cSopenharmony_ci .into(), 224919625d8cSopenharmony_ci ) 225019625d8cSopenharmony_ci } 225119625d8cSopenharmony_ci } 225219625d8cSopenharmony_ci 225319625d8cSopenharmony_ci #[doc(hidden)] 225419625d8cSopenharmony_ci pub trait _ValueParserViaFromOsStr: private::_ValueParserViaFromOsStrSealed { 225519625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser; 225619625d8cSopenharmony_ci } 225719625d8cSopenharmony_ci impl<FromOsStr> _ValueParserViaFromOsStr for &&&_AutoValueParser<FromOsStr> 225819625d8cSopenharmony_ci where 225919625d8cSopenharmony_ci FromOsStr: 226019625d8cSopenharmony_ci for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Clone + Send + Sync + 'static, 226119625d8cSopenharmony_ci { 226219625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser { 226319625d8cSopenharmony_ci _AnonymousValueParser( 226419625d8cSopenharmony_ci OsStringValueParser::new() 226519625d8cSopenharmony_ci .map(|s| FromOsStr::from(&s)) 226619625d8cSopenharmony_ci .into(), 226719625d8cSopenharmony_ci ) 226819625d8cSopenharmony_ci } 226919625d8cSopenharmony_ci } 227019625d8cSopenharmony_ci 227119625d8cSopenharmony_ci #[doc(hidden)] 227219625d8cSopenharmony_ci pub trait _ValueParserViaFromString: private::_ValueParserViaFromStringSealed { 227319625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser; 227419625d8cSopenharmony_ci } 227519625d8cSopenharmony_ci impl<FromString> _ValueParserViaFromString for &&_AutoValueParser<FromString> 227619625d8cSopenharmony_ci where 227719625d8cSopenharmony_ci FromString: From<String> + std::any::Any + Clone + Send + Sync + 'static, 227819625d8cSopenharmony_ci { 227919625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser { 228019625d8cSopenharmony_ci _AnonymousValueParser(StringValueParser::new().map(|s| FromString::from(s)).into()) 228119625d8cSopenharmony_ci } 228219625d8cSopenharmony_ci } 228319625d8cSopenharmony_ci 228419625d8cSopenharmony_ci #[doc(hidden)] 228519625d8cSopenharmony_ci pub trait _ValueParserViaFromStr: private::_ValueParserViaFromStrSealed { 228619625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser; 228719625d8cSopenharmony_ci } 228819625d8cSopenharmony_ci impl<FromStr> _ValueParserViaFromStr for &_AutoValueParser<FromStr> 228919625d8cSopenharmony_ci where 229019625d8cSopenharmony_ci FromStr: for<'s> From<&'s str> + std::any::Any + Clone + Send + Sync + 'static, 229119625d8cSopenharmony_ci { 229219625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser { 229319625d8cSopenharmony_ci _AnonymousValueParser(StringValueParser::new().map(|s| FromStr::from(&s)).into()) 229419625d8cSopenharmony_ci } 229519625d8cSopenharmony_ci } 229619625d8cSopenharmony_ci 229719625d8cSopenharmony_ci #[doc(hidden)] 229819625d8cSopenharmony_ci pub trait _ValueParserViaParse: private::_ValueParserViaParseSealed { 229919625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser; 230019625d8cSopenharmony_ci } 230119625d8cSopenharmony_ci impl<Parse> _ValueParserViaParse for _AutoValueParser<Parse> 230219625d8cSopenharmony_ci where 230319625d8cSopenharmony_ci Parse: std::str::FromStr + std::any::Any + Clone + Send + Sync + 'static, 230419625d8cSopenharmony_ci <Parse as std::str::FromStr>::Err: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, 230519625d8cSopenharmony_ci { 230619625d8cSopenharmony_ci fn value_parser(&self) -> _AnonymousValueParser { 230719625d8cSopenharmony_ci let func: fn(&str) -> Result<Parse, <Parse as std::str::FromStr>::Err> = 230819625d8cSopenharmony_ci Parse::from_str; 230919625d8cSopenharmony_ci _AnonymousValueParser(ValueParser::new(func)) 231019625d8cSopenharmony_ci } 231119625d8cSopenharmony_ci } 231219625d8cSopenharmony_ci} 231319625d8cSopenharmony_ci 231419625d8cSopenharmony_ci/// Select a [`ValueParser`] implementation from the intended type 231519625d8cSopenharmony_ci/// 231619625d8cSopenharmony_ci/// Supported types 231719625d8cSopenharmony_ci/// - [`ValueParserFactory` types][ValueParserFactory], including 231819625d8cSopenharmony_ci/// - [Native types][ValueParser]: `bool`, `String`, `OsString`, `PathBuf` 231919625d8cSopenharmony_ci/// - [Ranged numeric types][RangedI64ValueParser]: `u8`, `i8`, `u16`, `i16`, `u32`, `i32`, `u64`, `i64` 232019625d8cSopenharmony_ci/// - [`ValueEnum` types][crate::ValueEnum] 232119625d8cSopenharmony_ci/// - [`From<OsString>` types][std::convert::From] and [`From<&OsStr>` types][std::convert::From] 232219625d8cSopenharmony_ci/// - [`From<String>` types][std::convert::From] and [`From<&str>` types][std::convert::From] 232319625d8cSopenharmony_ci/// - [`FromStr` types][std::str::FromStr], including usize, isize 232419625d8cSopenharmony_ci/// 232519625d8cSopenharmony_ci/// # Example 232619625d8cSopenharmony_ci/// 232719625d8cSopenharmony_ci/// Usage: 232819625d8cSopenharmony_ci/// ```rust 232919625d8cSopenharmony_ci/// # use std::path::PathBuf; 233019625d8cSopenharmony_ci/// # use std::path::Path; 233119625d8cSopenharmony_ci/// let mut cmd = clap::Command::new("raw") 233219625d8cSopenharmony_ci/// .arg( 233319625d8cSopenharmony_ci/// clap::Arg::new("output") 233419625d8cSopenharmony_ci/// .value_parser(clap::value_parser!(PathBuf)) 233519625d8cSopenharmony_ci/// .required(true) 233619625d8cSopenharmony_ci/// ); 233719625d8cSopenharmony_ci/// 233819625d8cSopenharmony_ci/// let m = cmd.try_get_matches_from_mut(["cmd", "file.txt"]).unwrap(); 233919625d8cSopenharmony_ci/// let port: &PathBuf = m.get_one("output") 234019625d8cSopenharmony_ci/// .expect("required"); 234119625d8cSopenharmony_ci/// assert_eq!(port, Path::new("file.txt")); 234219625d8cSopenharmony_ci/// ``` 234319625d8cSopenharmony_ci/// 234419625d8cSopenharmony_ci/// Example mappings: 234519625d8cSopenharmony_ci/// ```rust 234619625d8cSopenharmony_ci/// # use clap::ColorChoice; 234719625d8cSopenharmony_ci/// // Built-in types 234819625d8cSopenharmony_ci/// let parser = clap::value_parser!(String); 234919625d8cSopenharmony_ci/// assert_eq!(format!("{:?}", parser), "ValueParser::string"); 235019625d8cSopenharmony_ci/// let parser = clap::value_parser!(std::ffi::OsString); 235119625d8cSopenharmony_ci/// assert_eq!(format!("{:?}", parser), "ValueParser::os_string"); 235219625d8cSopenharmony_ci/// let parser = clap::value_parser!(std::path::PathBuf); 235319625d8cSopenharmony_ci/// assert_eq!(format!("{:?}", parser), "ValueParser::path_buf"); 235419625d8cSopenharmony_ci/// clap::value_parser!(u16).range(3000..); 235519625d8cSopenharmony_ci/// clap::value_parser!(u64).range(3000..); 235619625d8cSopenharmony_ci/// 235719625d8cSopenharmony_ci/// // FromStr types 235819625d8cSopenharmony_ci/// let parser = clap::value_parser!(usize); 235919625d8cSopenharmony_ci/// assert_eq!(format!("{:?}", parser), "_AnonymousValueParser(ValueParser::other(usize))"); 236019625d8cSopenharmony_ci/// 236119625d8cSopenharmony_ci/// // ValueEnum types 236219625d8cSopenharmony_ci/// clap::value_parser!(ColorChoice); 236319625d8cSopenharmony_ci/// ``` 236419625d8cSopenharmony_ci#[macro_export] 236519625d8cSopenharmony_cimacro_rules! value_parser { 236619625d8cSopenharmony_ci ($name:ty) => {{ 236719625d8cSopenharmony_ci use $crate::builder::via_prelude::*; 236819625d8cSopenharmony_ci let auto = $crate::builder::_AutoValueParser::<$name>::new(); 236919625d8cSopenharmony_ci (&&&&&&auto).value_parser() 237019625d8cSopenharmony_ci }}; 237119625d8cSopenharmony_ci} 237219625d8cSopenharmony_ci 237319625d8cSopenharmony_cimod private { 237419625d8cSopenharmony_ci use super::*; 237519625d8cSopenharmony_ci 237619625d8cSopenharmony_ci // Prefer these so `clap_derive` defaults to optimized implementations 237719625d8cSopenharmony_ci pub trait _ValueParserViaSelfSealed {} 237819625d8cSopenharmony_ci impl<P: Into<ValueParser>> _ValueParserViaSelfSealed for &&&&&&&_AutoValueParser<P> {} 237919625d8cSopenharmony_ci 238019625d8cSopenharmony_ci pub trait _ValueParserViaFactorySealed {} 238119625d8cSopenharmony_ci impl<P: ValueParserFactory> _ValueParserViaFactorySealed for &&&&&&_AutoValueParser<P> {} 238219625d8cSopenharmony_ci 238319625d8cSopenharmony_ci pub trait _ValueParserViaValueEnumSealed {} 238419625d8cSopenharmony_ci impl<E: crate::ValueEnum> _ValueParserViaValueEnumSealed for &&&&&_AutoValueParser<E> {} 238519625d8cSopenharmony_ci 238619625d8cSopenharmony_ci pub trait _ValueParserViaFromOsStringSealed {} 238719625d8cSopenharmony_ci impl<FromOsString> _ValueParserViaFromOsStringSealed for &&&&_AutoValueParser<FromOsString> where 238819625d8cSopenharmony_ci FromOsString: From<std::ffi::OsString> + std::any::Any + Send + Sync + 'static 238919625d8cSopenharmony_ci { 239019625d8cSopenharmony_ci } 239119625d8cSopenharmony_ci 239219625d8cSopenharmony_ci pub trait _ValueParserViaFromOsStrSealed {} 239319625d8cSopenharmony_ci impl<FromOsStr> _ValueParserViaFromOsStrSealed for &&&_AutoValueParser<FromOsStr> where 239419625d8cSopenharmony_ci FromOsStr: for<'s> From<&'s std::ffi::OsStr> + std::any::Any + Send + Sync + 'static 239519625d8cSopenharmony_ci { 239619625d8cSopenharmony_ci } 239719625d8cSopenharmony_ci 239819625d8cSopenharmony_ci pub trait _ValueParserViaFromStringSealed {} 239919625d8cSopenharmony_ci impl<FromString> _ValueParserViaFromStringSealed for &&_AutoValueParser<FromString> where 240019625d8cSopenharmony_ci FromString: From<String> + std::any::Any + Send + Sync + 'static 240119625d8cSopenharmony_ci { 240219625d8cSopenharmony_ci } 240319625d8cSopenharmony_ci 240419625d8cSopenharmony_ci pub trait _ValueParserViaFromStrSealed {} 240519625d8cSopenharmony_ci impl<FromStr> _ValueParserViaFromStrSealed for &_AutoValueParser<FromStr> where 240619625d8cSopenharmony_ci FromStr: for<'s> From<&'s str> + std::any::Any + Send + Sync + 'static 240719625d8cSopenharmony_ci { 240819625d8cSopenharmony_ci } 240919625d8cSopenharmony_ci 241019625d8cSopenharmony_ci pub trait _ValueParserViaParseSealed {} 241119625d8cSopenharmony_ci impl<Parse> _ValueParserViaParseSealed for _AutoValueParser<Parse> 241219625d8cSopenharmony_ci where 241319625d8cSopenharmony_ci Parse: std::str::FromStr + std::any::Any + Send + Sync + 'static, 241419625d8cSopenharmony_ci <Parse as std::str::FromStr>::Err: Into<Box<dyn std::error::Error + Send + Sync + 'static>>, 241519625d8cSopenharmony_ci { 241619625d8cSopenharmony_ci } 241719625d8cSopenharmony_ci} 241819625d8cSopenharmony_ci 241919625d8cSopenharmony_ci#[cfg(test)] 242019625d8cSopenharmony_cimod test { 242119625d8cSopenharmony_ci use super::*; 242219625d8cSopenharmony_ci 242319625d8cSopenharmony_ci #[test] 242419625d8cSopenharmony_ci fn ensure_typed_applies_to_parse() { 242519625d8cSopenharmony_ci fn parse(_: &str) -> Result<usize, std::io::Error> { 242619625d8cSopenharmony_ci Ok(10) 242719625d8cSopenharmony_ci } 242819625d8cSopenharmony_ci let cmd = crate::Command::new("cmd"); 242919625d8cSopenharmony_ci let arg = None; 243019625d8cSopenharmony_ci assert_eq!( 243119625d8cSopenharmony_ci TypedValueParser::parse_ref(&parse, &cmd, arg, std::ffi::OsStr::new("foo")).unwrap(), 243219625d8cSopenharmony_ci 10 243319625d8cSopenharmony_ci ); 243419625d8cSopenharmony_ci } 243519625d8cSopenharmony_ci} 2436