From ad655eda52840c8ee4ea3c39ee3506ace3dad93f Mon Sep 17 00:00:00 2001 From: sxyazi Date: Fri, 3 Apr 2026 09:13:52 +0800 Subject: [PATCH] refactor: simplify `FromStr` implementations with `strum` --- Cargo.lock | 35 +++++++++++------- Cargo.toml | 2 +- yazi-actor/Cargo.toml | 1 + yazi-actor/src/core/preflight.rs | 2 +- yazi-actor/src/lives/preference.rs | 5 +-- yazi-actor/src/mgr/search.rs | 3 +- yazi-adapter/Cargo.toml | 2 ++ yazi-adapter/src/adapter.rs | 20 +++-------- yazi-adapter/src/drivers/ueberzug.rs | 3 +- yazi-binding/Cargo.toml | 1 + yazi-binding/src/elements/pos.rs | 3 +- yazi-binding/src/layer.rs | 3 +- yazi-binding/src/scheme.rs | 3 +- yazi-config/Cargo.toml | 1 + yazi-config/src/popup/origin.rs | 31 ++-------------- yazi-core/Cargo.toml | 1 + yazi-core/src/mgr/search.rs | 24 ++----------- yazi-fs/Cargo.toml | 1 + yazi-fs/src/sorting.rs | 53 +++++----------------------- yazi-parser/Cargo.toml | 19 +++++----- yazi-parser/src/mgr/copy.rs | 14 +++----- yazi-parser/src/spark/kind.rs | 36 ++----------------- yazi-runner/Cargo.toml | 1 + yazi-runner/src/plugin/option.rs | 14 +++----- yazi-shared/src/data/de.rs | 4 +-- yazi-shared/src/data/de_owned.rs | 4 +-- yazi-shared/src/layer.rs | 34 +++--------------- yazi-shim/Cargo.toml | 6 ++-- yazi-shim/src/lib.rs | 2 +- yazi-shim/src/strum/mod.rs | 1 + yazi-shim/src/strum/traits.rs | 10 ++++++ 31 files changed, 108 insertions(+), 231 deletions(-) create mode 100644 yazi-shim/src/strum/mod.rs create mode 100644 yazi-shim/src/strum/traits.rs diff --git a/Cargo.lock b/Cargo.lock index 5f246022..cd4a7d16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1946,9 +1946,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -3075,7 +3075,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64", - "indexmap 2.13.0", + "indexmap 2.13.1", "quick-xml", "serde", "time", @@ -3938,7 +3938,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.13.1", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -4578,7 +4578,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde_core", "serde_spanned", "toml_datetime", @@ -4998,7 +4998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.0", + "indexmap 2.13.1", "wasm-encoder", "wasmparser", ] @@ -5011,7 +5011,7 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.13.1", "semver", ] @@ -5507,7 +5507,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap 2.13.0", + "indexmap 2.13.1", "prettyplease", "syn 2.0.117", "wasm-metadata", @@ -5538,7 +5538,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "serde", "serde_derive", @@ -5557,7 +5557,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "semver", "serde", @@ -5613,6 +5613,7 @@ dependencies = [ "yazi-runner", "yazi-scheduler", "yazi-shared", + "yazi-shim", "yazi-term", "yazi-tty", "yazi-vfs", @@ -5633,6 +5634,7 @@ dependencies = [ "palette", "quantette", "ratatui", + "strum 0.28.0", "tokio", "tracing", "yazi-config", @@ -5640,6 +5642,7 @@ dependencies = [ "yazi-fs", "yazi-macro", "yazi-shared", + "yazi-shim", "yazi-tty", ] @@ -5668,6 +5671,7 @@ dependencies = [ "yazi-fs", "yazi-macro", "yazi-shared", + "yazi-shim", "yazi-vfs", "yazi-widgets", ] @@ -5742,10 +5746,11 @@ dependencies = [ "crossterm 0.29.0", "globset", "hashbrown 0.16.1", - "indexmap 2.13.0", + "indexmap 2.13.1", "ratatui", "regex", "serde", + "strum 0.28.0", "tokio", "toml", "tracing", @@ -5763,12 +5768,13 @@ dependencies = [ "anyhow", "crossterm 0.29.0", "hashbrown 0.16.1", - "indexmap 2.13.0", + "indexmap 2.13.1", "mlua", "parking_lot", "ratatui", "serde", "serde_with", + "strum 0.28.0", "syntect", "tokio", "tokio-stream", @@ -5798,7 +5804,7 @@ version = "26.2.2" dependencies = [ "anyhow", "hashbrown 0.16.1", - "indexmap 2.13.0", + "indexmap 2.13.1", "mlua", "ordered-float 5.3.0", "parking_lot", @@ -5907,6 +5913,7 @@ dependencies = [ "regex", "scopeguard", "serde", + "strum 0.28.0", "tokio", "tracing", "trash", @@ -5939,6 +5946,7 @@ dependencies = [ "paste", "ratatui", "serde", + "strum 0.28.0", "tokio", "yazi-binding", "yazi-boot", @@ -6021,6 +6029,7 @@ dependencies = [ "mlua", "parking_lot", "serde", + "strum 0.28.0", "thiserror 2.0.18", "tokio", "tokio-util", diff --git a/Cargo.toml b/Cargo.toml index 78dc3849..daccf54f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,7 +50,7 @@ foldhash = "0.2.0" futures = "0.3.32" globset = "0.4.18" hashbrown = { version = "0.16.1", features = [ "serde" ] } -indexmap = { version = "2.13.0", features = [ "serde" ] } +indexmap = { version = "2.13.1", features = [ "serde" ] } libc = "0.2.184" lru = "0.16.3" mlua = { version = "0.11.6", features = [ "anyhow", "async", "error-send", "lua55", "macros", "serde" ] } diff --git a/yazi-actor/Cargo.toml b/yazi-actor/Cargo.toml index 14c4fc12..747dd84a 100644 --- a/yazi-actor/Cargo.toml +++ b/yazi-actor/Cargo.toml @@ -31,6 +31,7 @@ yazi-proxy = { path = "../yazi-proxy", version = "26.2.2" } yazi-runner = { path = "../yazi-runner", version = "26.2.2" } yazi-scheduler = { path = "../yazi-scheduler", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" } +yazi-shim = { path = "../yazi-shim", version = "26.2.2" } yazi-term = { path = "../yazi-term", version = "26.2.2" } yazi-tty = { path = "../yazi-tty", version = "26.2.2" } yazi-vfs = { path = "../yazi-vfs", version = "26.2.2" } diff --git a/yazi-actor/src/core/preflight.rs b/yazi-actor/src/core/preflight.rs index 51596aba..56f6e4d0 100644 --- a/yazi-actor/src/core/preflight.rs +++ b/yazi-actor/src/core/preflight.rs @@ -12,7 +12,7 @@ pub struct Preflight; impl Preflight { pub fn act<'a>(cx: &mut Ctx, opt: (SparkKind, Spark<'a>)) -> Result> { let kind = opt.0; - let Some(handlers) = LOCAL.read().get(kind.as_ref()).filter(|&m| !m.is_empty()).cloned() else { + let Some(handlers) = LOCAL.read().get(kind.into()).filter(|&m| !m.is_empty()).cloned() else { return Ok(opt.1); }; diff --git a/yazi-actor/src/lives/preference.rs b/yazi-actor/src/lives/preference.rs index db96544c..01dff8a7 100644 --- a/yazi-actor/src/lives/preference.rs +++ b/yazi-actor/src/lives/preference.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use mlua::{AnyUserData, UserData, UserDataFields, Value}; use yazi_binding::cached_field; +use yazi_shim::strum::IntoStr; use super::{Lives, PtrCell}; @@ -41,11 +42,11 @@ impl UserData for Preference { fields.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden)); // Sorting - cached_field!(fields, sort_by, |_, me| Ok(me.sort_by.to_string())); + cached_field!(fields, sort_by, |_, me| Ok(me.sort_by.into_str())); fields.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive)); fields.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse)); fields.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first)); fields.add_field_method_get("sort_translit", |_, me| Ok(me.sort_translit)); - fields.add_field_method_get("sort_fallback", |_, me| Ok(me.sort_fallback.to_string())); + fields.add_field_method_get("sort_fallback", |_, me| Ok(me.sort_fallback.into_str())); } } diff --git a/yazi-actor/src/mgr/search.rs b/yazi-actor/src/mgr/search.rs index 2dae9fcb..b8e45af5 100644 --- a/yazi-actor/src/mgr/search.rs +++ b/yazi-actor/src/mgr/search.rs @@ -28,8 +28,7 @@ impl Actor for Search { handle.abort(); } - let mut input = - InputProxy::show(InputCfg::search(opt.via.into_str()).with_value(&*opt.subject)); + let mut input = InputProxy::show(InputCfg::search(opt.via.into()).with_value(&*opt.subject)); tokio::spawn(async move { if let Some(InputEvent::Submit(subject)) = input.recv().await { diff --git a/yazi-adapter/Cargo.toml b/yazi-adapter/Cargo.toml index 400c75e5..1ca04429 100644 --- a/yazi-adapter/Cargo.toml +++ b/yazi-adapter/Cargo.toml @@ -18,6 +18,7 @@ yazi-emulator = { path = "../yazi-emulator", version = "26.2.2" } yazi-fs = { path = "../yazi-fs", version = "26.2.2" } yazi-macro = { path = "../yazi-macro", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" } +yazi-shim = { path = "../yazi-shim", version = "26.2.2" } yazi-tty = { path = "../yazi-tty", version = "26.2.2" } # External dependencies @@ -30,6 +31,7 @@ moxcms = "0.8.1" palette = { version = "0.7.6", default-features = false } quantette = { version = "0.5.1", default-features = false } ratatui = { workspace = true } +strum = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } diff --git a/yazi-adapter/src/adapter.rs b/yazi-adapter/src/adapter.rs index f04765c8..f3fc75b2 100644 --- a/yazi-adapter/src/adapter.rs +++ b/yazi-adapter/src/adapter.rs @@ -1,14 +1,16 @@ -use std::{env, fmt::Display, path::PathBuf}; +use std::{env, path::PathBuf}; use anyhow::Result; use ratatui::layout::Rect; +use strum::{Display, IntoStaticStr}; use tracing::warn; use yazi_emulator::{Emulator, TMUX}; use yazi_shared::env_exists; use crate::{Adapters, SHOWN, drivers}; -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Display, Eq, IntoStaticStr, PartialEq)] +#[strum(serialize_all = "kebab-case")] pub enum Adapter { Kgp, KgpOld, @@ -21,20 +23,6 @@ pub enum Adapter { Chafa, } -impl Display for Adapter { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - Self::Kgp => write!(f, "kgp"), - Self::KgpOld => write!(f, "kgp-old"), - Self::Iip => write!(f, "iip"), - Self::Sixel => write!(f, "sixel"), - Self::X11 => write!(f, "x11"), - Self::Wayland => write!(f, "wayland"), - Self::Chafa => write!(f, "chafa"), - } - } -} - impl Adapter { pub async fn image_show

(self, path: P, max: Rect) -> Result where diff --git a/yazi-adapter/src/drivers/ueberzug.rs b/yazi-adapter/src/drivers/ueberzug.rs index 54c64526..0c86073c 100644 --- a/yazi-adapter/src/drivers/ueberzug.rs +++ b/yazi-adapter/src/drivers/ueberzug.rs @@ -8,6 +8,7 @@ use tracing::{debug, warn}; use yazi_config::YAZI; use yazi_emulator::Dimension; use yazi_shared::{LOG_LEVEL, RoCell, env_exists}; +use yazi_shim::strum::IntoStr; use crate::Adapter; @@ -86,7 +87,7 @@ impl Ueberzug { fn create_demon(adapter: Adapter) -> Result { let result = Command::new("ueberzugpp") - .args(["layer", "-so", &adapter.to_string()]) + .args(["layer", "-so", adapter.into_str()]) .env("SPDLOG_LEVEL", if LOG_LEVEL.get().is_none() { "" } else { "debug" }) .kill_on_drop(true) .stdin(Stdio::piped()) diff --git a/yazi-binding/Cargo.toml b/yazi-binding/Cargo.toml index f28d6d9d..56abb918 100644 --- a/yazi-binding/Cargo.toml +++ b/yazi-binding/Cargo.toml @@ -23,6 +23,7 @@ yazi-config = { path = "../yazi-config", version = "26.2.2" } yazi-fs = { path = "../yazi-fs", version = "26.2.2" } yazi-macro = { path = "../yazi-macro", version = "26.2.2" } yazi-shared = { path = "../yazi-shared", version = "26.2.2" } +yazi-shim = { path = "../yazi-shim", version = "26.2.2" } yazi-vfs = { path = "../yazi-vfs", version = "26.2.2" } yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" } diff --git a/yazi-binding/src/elements/pos.rs b/yazi-binding/src/elements/pos.rs index 15fe8d3d..ba7d12bd 100644 --- a/yazi-binding/src/elements/pos.rs +++ b/yazi-binding/src/elements/pos.rs @@ -1,6 +1,7 @@ use std::{ops::Deref, str::FromStr}; use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value}; +use yazi_shim::strum::IntoStr; use super::Pad; @@ -82,7 +83,7 @@ impl Pos { impl UserData for Pos { fn add_fields>(fields: &mut F) { // TODO: cache - fields.add_field_method_get("1", |_, me| Ok(me.origin.to_string())); + fields.add_field_method_get("1", |_, me| Ok(me.origin.into_str())); fields.add_field_method_get("x", |_, me| Ok(me.offset.x)); fields.add_field_method_get("y", |_, me| Ok(me.offset.y)); fields.add_field_method_get("w", |_, me| Ok(me.offset.width)); diff --git a/yazi-binding/src/layer.rs b/yazi-binding/src/layer.rs index e666ab95..002b248f 100644 --- a/yazi-binding/src/layer.rs +++ b/yazi-binding/src/layer.rs @@ -1,4 +1,5 @@ use mlua::{MetaMethod, UserData}; +use yazi_shim::strum::IntoStr; #[derive(Clone, Copy)] pub struct Layer(yazi_shared::Layer); @@ -9,6 +10,6 @@ impl From for Layer { impl UserData for Layer { fn add_methods>(methods: &mut M) { - methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.0.to_string())); + methods.add_meta_method(MetaMethod::ToString, |_, me, ()| Ok(me.0.into_str())); } } diff --git a/yazi-binding/src/scheme.rs b/yazi-binding/src/scheme.rs index b0199dad..93bc9fd8 100644 --- a/yazi-binding/src/scheme.rs +++ b/yazi-binding/src/scheme.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use mlua::{UserData, UserDataFields, Value}; use yazi_fs::FsScheme; use yazi_shared::scheme::SchemeLike; +use yazi_shim::strum::IntoStr; use crate::{Path, cached_field}; @@ -27,7 +28,7 @@ impl Scheme { impl UserData for Scheme { fn add_fields>(fields: &mut F) { - cached_field!(fields, kind, |_, me| Ok(Into::<&'static str>::into(me.kind()))); + cached_field!(fields, kind, |_, me| Ok(me.kind().into_str())); cached_field!(fields, cache, |_, me| Ok(me.cache().map(Path::new))); fields.add_field_method_get("is_virtual", |_, me| Ok(me.is_virtual())); diff --git a/yazi-config/Cargo.toml b/yazi-config/Cargo.toml index e728cac6..013e1fd4 100644 --- a/yazi-config/Cargo.toml +++ b/yazi-config/Cargo.toml @@ -29,6 +29,7 @@ indexmap = { workspace = true } ratatui = { workspace = true } regex = { workspace = true } serde = { workspace = true } +strum = { workspace = true } tokio = { workspace = true } toml = { workspace = true } tracing = { workspace = true } diff --git a/yazi-config/src/popup/origin.rs b/yazi-config/src/popup/origin.rs index b11b6df4..0da9bd3a 100644 --- a/yazi-config/src/popup/origin.rs +++ b/yazi-config/src/popup/origin.rs @@ -1,9 +1,9 @@ -use std::{fmt::Display, str::FromStr}; - use serde::Deserialize; +use strum::{EnumString, IntoStaticStr}; -#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Default, Deserialize, EnumString, Eq, IntoStaticStr, PartialEq)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum Origin { #[default] TopLeft, @@ -17,28 +17,3 @@ pub enum Origin { Center, Hovered, } - -impl Display for Origin { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::TopLeft => "top-left", - Self::TopCenter => "top-center", - Self::TopRight => "top-right", - - Self::BottomLeft => "bottom-left", - Self::BottomCenter => "bottom-center", - Self::BottomRight => "bottom-right", - - Self::Center => "center", - Self::Hovered => "hovered", - }) - } -} - -impl FromStr for Origin { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} diff --git a/yazi-core/Cargo.toml b/yazi-core/Cargo.toml index acd187c0..d2ff6ba9 100644 --- a/yazi-core/Cargo.toml +++ b/yazi-core/Cargo.toml @@ -38,6 +38,7 @@ parking_lot = { workspace = true } ratatui = { workspace = true } serde = { workspace = true } serde_with = { workspace = true } +strum = { workspace = true } syntect = { workspace = true } tokio = { workspace = true } tokio-stream = { workspace = true } diff --git a/yazi-core/src/mgr/search.rs b/yazi-core/src/mgr/search.rs index fcd81774..3ee60c58 100644 --- a/yazi-core/src/mgr/search.rs +++ b/yazi-core/src/mgr/search.rs @@ -1,7 +1,6 @@ -use std::str::FromStr; - use anyhow::bail; use serde::Deserialize; +use strum::{EnumString, IntoStaticStr}; use yazi_shared::{SStr, event::ActionCow, url::{UrlCow, UrlLike}}; #[derive(Clone, Debug)] @@ -39,28 +38,11 @@ impl TryFrom for SearchOpt { } // Via -#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Deserialize, EnumString, Eq, IntoStaticStr, PartialEq)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum SearchVia { Rg, Rga, Fd, } - -impl FromStr for SearchVia { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} - -impl SearchVia { - pub fn into_str(self) -> &'static str { - match self { - Self::Rg => "rg", - Self::Rga => "rga", - Self::Fd => "fd", - } - } -} diff --git a/yazi-fs/Cargo.toml b/yazi-fs/Cargo.toml index 3457c881..51d858ad 100644 --- a/yazi-fs/Cargo.toml +++ b/yazi-fs/Cargo.toml @@ -32,6 +32,7 @@ rand = { workspace = true } regex = { workspace = true } scopeguard = { workspace = true } serde = { workspace = true } +strum = { workspace = true } tokio = { workspace = true } tracing = { workspace = true } typed-path = { workspace = true } diff --git a/yazi-fs/src/sorting.rs b/yazi-fs/src/sorting.rs index 1497c000..40ab39d8 100644 --- a/yazi-fs/src/sorting.rs +++ b/yazi-fs/src/sorting.rs @@ -1,10 +1,12 @@ -use std::{fmt::Display, str::FromStr}; - use serde::{Deserialize, Serialize}; +use strum::{EnumString, IntoStaticStr}; // --- by -#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[derive( + Clone, Copy, Debug, Default, Deserialize, EnumString, Eq, IntoStaticStr, PartialEq, Serialize, +)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum SortBy { #[default] None, @@ -17,51 +19,14 @@ pub enum SortBy { Random, } -impl FromStr for SortBy { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} - -impl Display for SortBy { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::None => "none", - Self::Mtime => "mtime", - Self::Btime => "btime", - Self::Extension => "extension", - Self::Alphabetical => "alphabetical", - Self::Natural => "natural", - Self::Size => "size", - Self::Random => "random", - }) - } -} - // --- fallback -#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] +#[derive( + Clone, Copy, Debug, Default, Deserialize, EnumString, Eq, IntoStaticStr, PartialEq, Serialize, +)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum SortFallback { #[default] Alphabetical, Natural, } - -impl FromStr for SortFallback { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} - -impl Display for SortFallback { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::Alphabetical => "alphabetical", - Self::Natural => "natural", - }) - } -} diff --git a/yazi-parser/Cargo.toml b/yazi-parser/Cargo.toml index e872ebdb..0ed440d3 100644 --- a/yazi-parser/Cargo.toml +++ b/yazi-parser/Cargo.toml @@ -31,15 +31,16 @@ yazi-vfs = { path = "../yazi-vfs", version = "26.2.2" } yazi-widgets = { path = "../yazi-widgets", version = "26.2.2" } # External dependencies -anyhow = { workspace = true } -bitflags = { workspace = true } -crossterm = { workspace = true } -hashbrown = { workspace = true } -mlua = { workspace = true } -paste = { workspace = true } -ratatui = { workspace = true } -serde = { workspace = true } -tokio = { workspace = true } +anyhow = { workspace = true } +bitflags = { workspace = true } +crossterm = { workspace = true } +hashbrown = { workspace = true } +mlua = { workspace = true } +paste = { workspace = true } +ratatui = { workspace = true } +serde = { workspace = true } +strum = { workspace = true } +tokio = { workspace = true } [target.'cfg(target_os = "macos")'.dependencies] crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] } diff --git a/yazi-parser/src/mgr/copy.rs b/yazi-parser/src/mgr/copy.rs index 48876ce5..030331a9 100644 --- a/yazi-parser/src/mgr/copy.rs +++ b/yazi-parser/src/mgr/copy.rs @@ -1,7 +1,8 @@ -use std::{borrow::Cow, str::FromStr}; +use std::borrow::Cow; use mlua::{ExternalError, FromLua, IntoLua, Lua, Value}; use serde::Deserialize; +use strum::EnumString; use yazi_shared::{SStr, event::ActionCow, strand::AsStrand}; #[derive(Debug)] @@ -30,22 +31,15 @@ impl IntoLua for CopyForm { } // --- Separator -#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Deserialize)] +#[derive(Clone, Copy, Debug, Default, Deserialize, EnumString, Eq, PartialEq)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum CopySeparator { #[default] Auto, Unix, } -impl FromStr for CopySeparator { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} - impl CopySeparator { pub fn transform(self, s: &T) -> Cow<'_, [u8]> where diff --git a/yazi-parser/src/spark/kind.rs b/yazi-parser/src/spark/kind.rs index ad323327..eb111a5e 100644 --- a/yazi-parser/src/spark/kind.rs +++ b/yazi-parser/src/spark/kind.rs @@ -1,6 +1,7 @@ -use std::fmt::Display; +use strum::{Display, IntoStaticStr}; -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Display, Eq, IntoStaticStr, PartialEq)] +#[strum(serialize_all = "kebab-case")] pub enum SparkKind { // app:title IndAppTitle, @@ -23,34 +24,3 @@ pub enum SparkKind { // notify:push RelayNotifyPush, } - -impl AsRef for SparkKind { - fn as_ref(&self) -> &str { - match self { - // app:title - Self::IndAppTitle => "ind-app-title", - - // mgr:hidden - Self::KeyHidden => "key-hidden", - Self::IndHidden => "ind-hidden", - // mgr:sort - Self::KeySort => "key-sort", - Self::IndSort => "ind-sort", - // mgr:stash - Self::IndStash => "ind-stash", - Self::RelayStash => "relay-stash", - // mgr:quit - Self::KeyQuit => "key-quit", - - // which:activate - Self::IndWhichActivate => "ind-which-activate", - - // notify:push - Self::RelayNotifyPush => "relay-notify-push", - } - } -} - -impl Display for SparkKind { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_str(self.as_ref()) } -} diff --git a/yazi-runner/Cargo.toml b/yazi-runner/Cargo.toml index 3fa21886..eafdb096 100644 --- a/yazi-runner/Cargo.toml +++ b/yazi-runner/Cargo.toml @@ -28,6 +28,7 @@ hashbrown = { workspace = true } mlua = { workspace = true } parking_lot = { workspace = true } serde = { workspace = true } +strum = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } diff --git a/yazi-runner/src/plugin/option.rs b/yazi-runner/src/plugin/option.rs index 45fb210c..824080be 100644 --- a/yazi-runner/src/plugin/option.rs +++ b/yazi-runner/src/plugin/option.rs @@ -1,10 +1,11 @@ -use std::{borrow::Cow, fmt, fmt::Debug, str::FromStr}; +use std::{borrow::Cow, fmt, fmt::Debug}; use anyhow::bail; use dyn_clone::DynClone; use hashbrown::HashMap; use mlua::{Lua, Table}; use serde::Deserialize; +use strum::EnumString; use yazi_shared::{SStr, data::{Data, DataKey}, event::{Action, ActionCow}}; #[derive(Clone, Debug, Default)] @@ -57,8 +58,9 @@ impl PluginOpt { } // --- Mode -#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Default, Deserialize, EnumString, Eq, PartialEq)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum PluginMode { #[default] Auto, @@ -66,14 +68,6 @@ pub enum PluginMode { Async, } -impl FromStr for PluginMode { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} - impl PluginMode { pub fn auto_then(self, sync: bool) -> Self { if self != Self::Auto { diff --git a/yazi-shared/src/data/de.rs b/yazi-shared/src/data/de.rs index 2f988354..c0539fd9 100644 --- a/yazi-shared/src/data/de.rs +++ b/yazi-shared/src/data/de.rs @@ -268,11 +268,11 @@ impl<'de> Deserializer<'de> for &'de Data { Err(Error::custom("identifier not supported")) } - fn deserialize_ignored_any(self, _visitor: V) -> Result + fn deserialize_ignored_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { - Err(Error::custom("ignored any not supported")) + visitor.visit_unit() } } diff --git a/yazi-shared/src/data/de_owned.rs b/yazi-shared/src/data/de_owned.rs index 863c1150..205bda49 100644 --- a/yazi-shared/src/data/de_owned.rs +++ b/yazi-shared/src/data/de_owned.rs @@ -273,11 +273,11 @@ impl<'de> Deserializer<'de> for Data { Err(Error::custom("identifier not supported")) } - fn deserialize_ignored_any(self, _visitor: V) -> Result + fn deserialize_ignored_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { - Err(Error::custom("ignored any not supported")) + visitor.visit_unit() } } diff --git a/yazi-shared/src/layer.rs b/yazi-shared/src/layer.rs index b5d50d3a..e0c15ea1 100644 --- a/yazi-shared/src/layer.rs +++ b/yazi-shared/src/layer.rs @@ -1,9 +1,11 @@ -use std::{fmt::Display, str::FromStr}; - use serde::Deserialize; +use strum::{Display, EnumString, IntoStaticStr}; -#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy, Deserialize)] +#[derive( + Clone, Copy, Debug, Default, Deserialize, Display, EnumString, Eq, Hash, IntoStaticStr, PartialEq, +)] #[serde(rename_all = "kebab-case")] +#[strum(serialize_all = "kebab-case")] pub enum Layer { #[default] App, @@ -18,29 +20,3 @@ pub enum Layer { Which, Notify, } - -impl Display for Layer { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(match self { - Self::App => "app", - Self::Mgr => "mgr", - Self::Tasks => "tasks", - Self::Spot => "spot", - Self::Pick => "pick", - Self::Input => "input", - Self::Confirm => "confirm", - Self::Help => "help", - Self::Cmp => "cmp", - Self::Which => "which", - Self::Notify => "notify", - }) - } -} - -impl FromStr for Layer { - type Err = serde::de::value::Error; - - fn from_str(s: &str) -> Result { - Self::deserialize(serde::de::value::StrDeserializer::new(s)) - } -} diff --git a/yazi-shim/Cargo.toml b/yazi-shim/Cargo.toml index 49dd1891..a50e6fcd 100644 --- a/yazi-shim/Cargo.toml +++ b/yazi-shim/Cargo.toml @@ -16,9 +16,9 @@ workspace = true yazi-macro = { path = "../yazi-macro", version = "26.2.2" } # External dependencies -crossterm = { workspace = true } -ratatui = { workspace = true } -twox-hash = { workspace = true } +crossterm = { workspace = true } +ratatui = { workspace = true } +twox-hash = { workspace = true } unicode-width = { workspace = true } [dependencies.unicode-segmentation] diff --git a/yazi-shim/src/lib.rs b/yazi-shim/src/lib.rs index a9933ddc..39a61a39 100644 --- a/yazi-shim/src/lib.rs +++ b/yazi-shim/src/lib.rs @@ -1,3 +1,3 @@ -yazi_macro::mod_pub!(crossterm ratatui); +yazi_macro::mod_pub!(crossterm ratatui strum); yazi_macro::mod_flat!(twox); diff --git a/yazi-shim/src/strum/mod.rs b/yazi-shim/src/strum/mod.rs new file mode 100644 index 00000000..ff9b6f21 --- /dev/null +++ b/yazi-shim/src/strum/mod.rs @@ -0,0 +1 @@ +yazi_macro::mod_flat!(traits); diff --git a/yazi-shim/src/strum/traits.rs b/yazi-shim/src/strum/traits.rs new file mode 100644 index 00000000..4977cf53 --- /dev/null +++ b/yazi-shim/src/strum/traits.rs @@ -0,0 +1,10 @@ +pub trait IntoStr { + fn into_str(self) -> &'static str; +} + +impl IntoStr for T +where + T: Into<&'static str>, +{ + fn into_str(self) -> &'static str { self.into() } +}