diff --git a/doc/src/changelog.md b/doc/src/changelog.md index 4caf39a..77b081a 100644 --- a/doc/src/changelog.md +++ b/doc/src/changelog.md @@ -1,5 +1,11 @@ # Changelog +## v0.8.1 (beta0) + +**Development**: + +- Use `strum` to implement `FromStr` for `enum ColorMode`. + ## v0.8.0 **Features**: diff --git a/src/cli.rs b/src/cli.rs index b866387..bb8975f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -8,14 +8,15 @@ use super::path; #[command(name = "garden")] #[command(author, version, about, long_about = None)] pub struct MainOptions { - /// Set the color mode + /// Use ANSI colors [auto, true, false, on, off, always, never, 1, 0] #[arg( long, require_equals = true, num_args = 0..=1, default_value_t = model::ColorMode::Auto, - default_missing_value = "on", - value_enum, + default_missing_value = "true", + value_name = "WHEN", + value_parser = model::ColorMode::parse_from_str, )] color: model::ColorMode, diff --git a/src/model.rs b/src/model.rs index 8237194..5a42516 100644 --- a/src/model.rs +++ b/src/model.rs @@ -6,11 +6,13 @@ use super::eval; use super::path; use super::syntax; -use clap::ValueEnum; use indexmap::{IndexMap, IndexSet}; use indextree::{Arena, NodeId}; use std::cell::RefCell; use std::collections::HashMap; +use std::str::FromStr; +use strum::VariantNames; +use strum_macros; use which::which; /// TreeName keys into config.trees @@ -1048,18 +1050,49 @@ impl TreeQuery { } } -#[derive(ValueEnum, Clone, Debug, Default, PartialEq, Eq)] +#[derive( + Clone, + Debug, + Default, + PartialEq, + Eq, + strum_macros::EnumString, + strum_macros::Display, + strum_macros::EnumVariantNames, +)] +#[strum(ascii_case_insensitive, serialize_all = "kebab-case")] pub enum ColorMode { /// Enable color when a tty is detected #[default] Auto, - /// Disable color - Off, /// Enable color + #[strum( + serialize = "1", + serialize = "on", + serialize = "true", + serialize = "always", + serialize = "y", + serialize = "yes" + )] On, + /// Disable color + #[strum( + serialize = "0", + serialize = "off", + serialize = "false", + serialize = "never", + serialize = "n", + serialize = "no" + )] + Off, } impl ColorMode { + /// Parse a color mode from a string using strum's from_str(). + pub fn parse_from_str(string: &str) -> Result { + ColorMode::from_str(string).map_err(|_| format!("choices are {:?}", Self::VARIANTS)) + } + pub fn is_enabled(&self) -> bool { match self { ColorMode::Auto => atty::is(atty::Stream::Stdout), @@ -1068,10 +1101,6 @@ impl ColorMode { } } - pub fn names() -> &'static str { - "auto, true, false, 1, 0, [y]es, [n]o, on, off, always, never" - } - pub fn update(&mut self) { if *self == ColorMode::Auto { // Speedup future calls to is_enabled() by performing the "auto" @@ -1089,30 +1118,6 @@ impl ColorMode { } } -impl std::str::FromStr for ColorMode { - type Err = (); // For the FromStr trait - - fn from_str(src: &str) -> Result { - match src.to_lowercase().as_ref() { - "auto" => Ok(ColorMode::Auto), - "-1" => Ok(ColorMode::Auto), - "0" => Ok(ColorMode::Off), - "1" => Ok(ColorMode::On), - "false" => Ok(ColorMode::Off), - "true" => Ok(ColorMode::On), - "never" => Ok(ColorMode::Off), - "always" => Ok(ColorMode::Off), - "off" => Ok(ColorMode::Off), - "on" => Ok(ColorMode::On), - "n" => Ok(ColorMode::Off), - "y" => Ok(ColorMode::On), - "no" => Ok(ColorMode::Off), - "yes" => Ok(ColorMode::On), - _ => Err(()), - } - } -} - // Color is an alias for yansi::Paint. pub type Color = yansi::Paint;