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