diff --git a/src/builder/possible_value.rs b/src/builder/possible_value.rs index 03964fe118b..7a313ad2585 100644 --- a/src/builder/possible_value.rs +++ b/src/builder/possible_value.rs @@ -7,8 +7,11 @@ use crate::util::eq_ignore_case; /// /// This is used for specifying [possible values] of [Args]. /// -/// **NOTE:** This struct is likely not needed for most usecases as it is only required to -/// [hide] single values from help messages and shell completions or to attach [help] to possible values. +/// See also [`PossibleValuesParser`][crate::builder::PossibleValuesParser] +/// +/// **NOTE:** Most likely you can use strings, rather than `PossibleValue` as it is only required +/// to [hide] single values from help messages and shell completions or to attach [help] to +/// possible values. /// /// # Examples /// @@ -23,6 +26,7 @@ use crate::util::eq_ignore_case; /// PossibleValue::new("secret speed").hide(true) /// ]); /// ``` +/// /// [Args]: crate::Arg /// [possible values]: crate::builder::ValueParser::possible_values /// [hide]: PossibleValue::hide() diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs index 1b2b51dba13..4681857acc1 100644 --- a/src/builder/value_parser.rs +++ b/src/builder/value_parser.rs @@ -508,6 +508,41 @@ where } } +/// Create a [`ValueParser`] with [`PossibleValuesParser`] +/// +/// See [`PossibleValuesParser`] for more flexibility in creating the +/// [`PossibleValue`][crate::builder::PossibleValue]s. +/// +/// # Examples +/// +/// ```rust +/// let possible = vec!["always", "auto", "never"]; +/// let mut cmd = clap::Command::new("raw") +/// .arg( +/// clap::Arg::new("color") +/// .long("color") +/// .value_parser(possible) +/// .default_value("auto") +/// ); +/// +/// let m = cmd.try_get_matches_from_mut( +/// ["cmd", "--color", "never"] +/// ).unwrap(); +/// +/// let color: &String = m.get_one("color") +/// .expect("default"); +/// assert_eq!(color, "never"); +/// ``` +impl

From> for ValueParser +where + P: Into, +{ + fn from(values: Vec

) -> Self { + let inner = PossibleValuesParser::from(values); + Self::from(inner) + } +} + impl std::fmt::Debug for ValueParser { fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { match &self.0 { @@ -957,31 +992,11 @@ impl Default for PathBufValueParser { /// /// ```rust /// # use std::ffi::OsStr; +/// # use clap::ColorChoice; /// # use clap::builder::TypedValueParser; /// # let cmd = clap::Command::new("test"); /// # let arg = None; /// -/// #[derive(Copy, Clone, Debug, PartialEq, Eq)] -/// enum ColorChoice { -/// Always, -/// Auto, -/// Never, -/// } -/// -/// impl clap::ValueEnum for ColorChoice { -/// fn value_variants<'a>() -> &'a [Self] { -/// &[Self::Always, Self::Auto, Self::Never] -/// } -/// -/// fn to_possible_value<'a>(&self) -> Option { -/// match self { -/// Self::Always => Some(clap::builder::PossibleValue::new("always")), -/// Self::Auto => Some(clap::builder::PossibleValue::new("auto")), -/// Self::Never => Some(clap::builder::PossibleValue::new("never")), -/// } -/// } -/// } -/// /// // Usage /// let mut cmd = clap::Command::new("raw") /// .arg( @@ -1086,8 +1101,9 @@ impl Default for EnumValueP /// Verify the value is from an enumerated set of [`PossibleValue`][crate::builder::PossibleValue]. /// /// See also: -/// - [`EnumValueParser`] for directly supporting `enum`s -/// - [`TypedValueParser::map`] for adapting values to a more specialized type +/// - [`EnumValueParser`] for directly supporting [`ValueEnum`][crate::ValueEnum] types +/// - [`TypedValueParser::map`] for adapting values to a more specialized type, like an external +/// enums that can't implement [`ValueEnum`][crate::ValueEnum] /// /// # Example /// @@ -2327,6 +2343,7 @@ pub mod via_prelude { /// /// Example mappings: /// ```rust +/// # use clap::ColorChoice; /// // Built-in types /// let parser = clap::value_parser!(String); /// assert_eq!(format!("{:?}", parser), "ValueParser::string"); @@ -2344,25 +2361,6 @@ pub mod via_prelude { /// assert_eq!(format!("{:?}", parser), "_AnonymousValueParser(ValueParser::other(usize))"); /// /// // ValueEnum types -/// #[derive(Copy, Clone, Debug, PartialEq, Eq)] -/// enum ColorChoice { -/// Always, -/// Auto, -/// Never, -/// } -/// impl clap::ValueEnum for ColorChoice { -/// // ... -/// # fn value_variants<'a>() -> &'a [Self] { -/// # &[Self::Always, Self::Auto, Self::Never] -/// # } -/// # fn to_possible_value<'a>(&self) -> Option { -/// # match self { -/// # Self::Always => Some(clap::builder::PossibleValue::new("always")), -/// # Self::Auto => Some(clap::builder::PossibleValue::new("auto")), -/// # Self::Never => Some(clap::builder::PossibleValue::new("never")), -/// # } -/// # } -/// } /// let parser = clap::value_parser!(ColorChoice); /// assert_eq!(format!("{:?}", parser), "EnumValueParser(PhantomData)"); /// ``` diff --git a/src/lib.rs b/src/lib.rs index 62b092929fd..393e1f0b9a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,11 +102,7 @@ pub use crate::builder::Command; pub use crate::builder::ValueHint; pub use crate::builder::{Arg, ArgGroup}; pub use crate::parser::ArgMatches; -#[cfg(feature = "color")] pub use crate::util::color::ColorChoice; -#[cfg(not(feature = "color"))] -#[allow(unused_imports)] -pub(crate) use crate::util::color::ColorChoice; pub use crate::util::Id; /// Command Line Argument Parser Error diff --git a/src/util/color.rs b/src/util/color.rs index c13d20d3ea8..7c7468eafd7 100644 --- a/src/util/color.rs +++ b/src/util/color.rs @@ -64,6 +64,28 @@ impl Default for ColorChoice { } } +impl std::fmt::Display for ColorChoice { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.to_possible_value() + .expect("no values are skipped") + .get_name() + .fmt(f) + } +} + +impl std::str::FromStr for ColorChoice { + type Err = String; + + fn from_str(s: &str) -> Result { + for variant in Self::value_variants() { + if variant.to_possible_value().unwrap().matches(s, false) { + return Ok(*variant); + } + } + Err(format!("Invalid variant: {}", s)) + } +} + impl ValueEnum for ColorChoice { fn value_variants<'a>() -> &'a [Self] { &[Self::Auto, Self::Always, Self::Never]