From fa1ee46edce52e0d3bc0c4179b9d65ca46b1efbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Fri, 13 Mar 2026 20:28:44 +0800 Subject: [PATCH] refactor: implement `FromLua` instead of `TryFrom` (#3760) --- Cargo.lock | 40 +++++++++--------- Cargo.toml | 2 +- yazi-binding/src/color.rs | 8 ++-- yazi-binding/src/elements/area.rs | 6 +-- yazi-binding/src/elements/border.rs | 4 +- yazi-binding/src/elements/cell.rs | 8 ++-- yazi-binding/src/elements/elements.rs | 19 ++++----- yazi-binding/src/elements/gauge.rs | 4 +- yazi-binding/src/elements/line.rs | 54 ++++++++++++------------- yazi-binding/src/elements/list.rs | 11 +---- yazi-binding/src/elements/pos.rs | 19 ++++----- yazi-binding/src/elements/renderable.rs | 19 +++++---- yazi-binding/src/elements/row.rs | 8 ++-- yazi-binding/src/elements/span.rs | 10 ++--- yazi-binding/src/elements/table.rs | 19 +++------ yazi-binding/src/elements/text.rs | 42 +++++++++---------- yazi-binding/src/file.rs | 31 +++++++------- yazi-binding/src/macros.rs | 6 ++- yazi-binding/src/range.rs | 4 +- yazi-boot/Cargo.toml | 4 +- yazi-cli/Cargo.toml | 4 +- yazi-fm/Cargo.toml | 2 +- yazi-plugin/src/fs/op.rs | 4 +- yazi-plugin/src/utils/layer.rs | 15 ++----- yazi-plugin/src/utils/preview.rs | 7 +--- yazi-plugin/src/utils/spot.rs | 4 +- 26 files changed, 156 insertions(+), 198 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 332e723f..c25824e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -130,9 +130,9 @@ checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -600,9 +600,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -610,9 +610,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.60" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -622,9 +622,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.66" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c757a3b7e39161a4e56f9365141ada2a6c915a8622c408ab6bb4b5d047371031" +checksum = "19c9f1dde76b736e3681f28cec9d5a61299cbaae0fce80a68e43724ad56031eb" dependencies = [ "clap", ] @@ -641,9 +641,9 @@ dependencies = [ [[package]] name = "clap_complete_nushell" -version = "4.5.10" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685bc86fd34b7467e0532a4f8435ab107960d69a243785ef0275e571b35b641a" +checksum = "fbb9e9715d29a754b468591be588f6b926f5b0a1eb6a8b62acabeb66ff84d897" dependencies = [ "clap", "clap_complete", @@ -651,9 +651,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", @@ -663,9 +663,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clipboard-win" @@ -2769,9 +2769,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "once_cell_polyfill" @@ -4755,9 +4755,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", diff --git a/Cargo.toml b/Cargo.toml index f402dde6..3394b674 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ anyhow = "1.0.102" base64 = "0.22.1" bitflags = { version = "2.11.0", features = [ "serde" ] } chrono = "0.4.44" -clap = { version = "4.5.60", features = [ "derive" ] } +clap = { version = "4.6.0", features = [ "derive" ] } core-foundation-sys = "0.8.7" crossterm = { version = "0.29.0", features = [ "event-stream" ] } dirs = "6.0.0" diff --git a/yazi-binding/src/color.rs b/yazi-binding/src/color.rs index 6a14dd2a..5f9f1aaf 100644 --- a/yazi-binding/src/color.rs +++ b/yazi-binding/src/color.rs @@ -1,14 +1,12 @@ use std::str::FromStr; -use mlua::{ExternalError, ExternalResult, UserData, Value}; +use mlua::{ExternalError, ExternalResult, FromLua, Lua, UserData, Value}; #[derive(Clone, Copy, Default)] pub struct Color(pub ratatui::style::Color); -impl TryFrom for Color { - type Error = mlua::Error; - - fn try_from(value: Value) -> Result { +impl FromLua for Color { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { Ok(Self(match value { Value::String(s) => ratatui::style::Color::from_str(&s.to_str()?).into_lua_err()?, Value::UserData(ud) => ud.borrow::()?.0, diff --git a/yazi-binding/src/elements/area.rs b/yazi-binding/src/elements/area.rs index 301276fd..f2cf04cd 100644 --- a/yazi-binding/src/elements/area.rs +++ b/yazi-binding/src/elements/area.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Value}; +use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, Value}; use super::{Pos, Rect}; @@ -70,7 +70,7 @@ impl TryFrom for Area { } impl FromLua for Area { - fn from_lua(value: Value, _: &mlua::Lua) -> mlua::Result { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { match value { Value::UserData(ud) => Self::try_from(ud), _ => Err(EXPECTED.into_lua_err()), @@ -79,7 +79,7 @@ impl FromLua for Area { } impl IntoLua for Area { - fn into_lua(self, lua: &mlua::Lua) -> mlua::Result { + fn into_lua(self, lua: &Lua) -> mlua::Result { match self { Self::Pos(pos) => pos.into_lua(lua), Self::Rect(rect) => rect.into_lua(lua), diff --git a/yazi-binding/src/elements/border.rs b/yazi-binding/src/elements/border.rs index 2460c33c..43dad5ed 100644 --- a/yazi-binding/src/elements/border.rs +++ b/yazi-binding/src/elements/border.rs @@ -78,14 +78,14 @@ impl UserData for Border { }); methods.add_function_mut( "title", - |_, (ud, line, position): (AnyUserData, Value, Option)| { + |_, (ud, line, position): (AnyUserData, Line, Option)| { let position = if position == Some(Borders::BOTTOM.bits()) { ratatui::widgets::TitlePosition::Bottom } else { ratatui::widgets::TitlePosition::Top }; - ud.borrow_mut::()?.titles.push((position, Line::try_from(line)?.inner)); + ud.borrow_mut::()?.titles.push((position, line.inner)); Ok(ud) }, ); diff --git a/yazi-binding/src/elements/cell.rs b/yazi-binding/src/elements/cell.rs index 2c13dc86..3b31b907 100644 --- a/yazi-binding/src/elements/cell.rs +++ b/yazi-binding/src/elements/cell.rs @@ -1,9 +1,7 @@ -use mlua::{ExternalError, FromLua}; +use mlua::{FromLua, Lua, Value}; use super::Text; -const EXPECTED: &str = "expected a table of strings, Texts, Lines or Spans"; - #[derive(Clone, Debug)] pub struct Cell { pub(super) text: ratatui::text::Text<'static>, @@ -14,7 +12,7 @@ impl From for ratatui::widgets::Cell<'static> { } impl FromLua for Cell { - fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result { - Ok(Self { text: Text::try_from(value).map_err(|_| EXPECTED.into_lua_err())?.inner }) + fn from_lua(value: Value, lua: &Lua) -> mlua::Result { + Ok(Self { text: Text::from_lua(value, lua)?.inner }) } } diff --git a/yazi-binding/src/elements/elements.rs b/yazi-binding/src/elements/elements.rs index 7414c145..04032c26 100644 --- a/yazi-binding/src/elements/elements.rs +++ b/yazi-binding/src/elements/elements.rs @@ -1,4 +1,4 @@ -use mlua::{AnyUserData, IntoLua, Lua, Value}; +use mlua::{IntoLua, Lua, Value}; use tracing::error; use super::Renderable; @@ -42,22 +42,17 @@ where { match value { Value::Table(tbl) => { - for widget in tbl.sequence_values::() { - let Ok(widget) = widget else { - error!("Failed to convert to renderable UserData: {}", widget.unwrap_err()); - continue; - }; - - match Renderable::try_from(widget) { + for widget in tbl.sequence_values::() { + match widget { Ok(w) => w.render_with(buf, trans), - Err(e) => error!("{e}"), + Err(e) => error!("Failed to convert to renderable elements: {e}"), } } } - Value::UserData(ud) => match Renderable::try_from(ud) { + Value::UserData(ud) => match Renderable::try_from(&ud) { Ok(w) => w.render_with(buf, trans), - Err(e) => error!("{e}"), + Err(e) => error!("Failed to convert to renderable element: {e}"), }, - _ => error!("Expected a renderable UserData, or a table of them, got: {value:?}"), + _ => error!("Expected a renderable element, or a table of them, got: {value:?}"), } } diff --git a/yazi-binding/src/elements/gauge.rs b/yazi-binding/src/elements/gauge.rs index 1a4283b1..3b4ec40d 100644 --- a/yazi-binding/src/elements/gauge.rs +++ b/yazi-binding/src/elements/gauge.rs @@ -61,8 +61,8 @@ impl UserData for Gauge { Ok(ud) }); - methods.add_function_mut("label", |_, (ud, label): (AnyUserData, Value)| { - ud.borrow_mut::()?.label = Some(Span::try_from(label)?.0); + methods.add_function_mut("label", |_, (ud, label): (AnyUserData, Span)| { + ud.borrow_mut::()?.label = Some(label.0); Ok(ud) }); diff --git a/yazi-binding/src/elements/line.rs b/yazi-binding/src/elements/line.rs index 63e8a623..2700f0e5 100644 --- a/yazi-binding/src/elements/line.rs +++ b/yazi-binding/src/elements/line.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, mem, ops::{Deref, DerefMut}}; use ansi_to_tui::IntoText; -use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; +use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; use ratatui::widgets::Widget; use unicode_width::UnicodeWidthChar; @@ -29,7 +29,7 @@ impl DerefMut for Line { impl Line { pub fn compose(lua: &Lua) -> mlua::Result { - let new = lua.create_function(|_, (_, value): (Table, Value)| Self::try_from(value))?; + let new = lua.create_function(|_, (_, line): (Table, Self)| Ok(line))?; let parse = lua.create_function(|_, code: mlua::String| { let code = code.as_bytes(); @@ -55,30 +55,6 @@ impl Line { } } -impl TryFrom for Line { - type Error = mlua::Error; - - fn try_from(value: Value) -> Result { - Ok(Self { - inner: match value { - Value::Table(tb) => return Self::try_from(tb), - Value::String(s) => s.to_string_lossy().into(), - Value::UserData(ud) => { - if let Ok(Span(span)) = ud.take() { - span.into() - } else if let Ok(line) = ud.take() { - return Ok(line); - } else { - Err(EXPECTED.into_lua_err())? - } - } - _ => Err(EXPECTED.into_lua_err())?, - }, - ..Default::default() - }) - } -} - impl TryFrom for Line { type Error = mlua::Error; @@ -108,6 +84,28 @@ impl From for ratatui::text::Line<'static> { fn from(value: Line) -> Self { value.inner } } +impl FromLua for Line { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + Ok(Self { + inner: match value { + Value::Table(tb) => return Self::try_from(tb), + Value::String(s) => s.to_string_lossy().into(), + Value::UserData(ud) => { + if let Ok(Span(span)) = ud.take() { + span.into() + } else if let Ok(line) = ud.take() { + return Ok(line); + } else { + Err(EXPECTED.into_lua_err())? + } + } + _ => Err(EXPECTED.into_lua_err())?, + }, + ..Default::default() + }) + } +} + impl UserData for Line { fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); @@ -122,7 +120,7 @@ impl UserData for Line { methods.add_method("visible", |_, me, ()| { Ok(me.iter().flat_map(|s| s.content.chars()).any(|c| c.width().unwrap_or(0) > 0)) }); - methods.add_function_mut("truncate", |_, (ud, t): (AnyUserData, Table)| { + methods.add_function_mut("truncate", |lua, (ud, t): (AnyUserData, Table)| { let mut me = ud.borrow_mut::()?; let max = t.raw_get("max")?; @@ -134,7 +132,7 @@ impl UserData for Line { let ellipsis = match t.raw_get::("ellipsis")? { Value::Nil => (1, ratatui::text::Span::raw("…")), v => { - let mut span = Span::try_from(v)?; + let mut span = Span::from_lua(v, lua)?; (span.truncate(max), span.0) } }; diff --git a/yazi-binding/src/elements/list.rs b/yazi-binding/src/elements/list.rs index a955d761..d713df94 100644 --- a/yazi-binding/src/elements/list.rs +++ b/yazi-binding/src/elements/list.rs @@ -1,10 +1,8 @@ -use mlua::{ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, Value}; +use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value}; use ratatui::widgets::Widget; use super::{Area, Text}; -const EXPECTED: &str = "expected a table of strings, Texts, Lines or Spans"; - // --- List #[derive(Clone, Debug, Default)] pub struct List { @@ -15,12 +13,7 @@ pub struct List { impl List { pub fn compose(lua: &Lua) -> mlua::Result { - let new = lua.create_function(|_, (_, seq): (Table, Table)| { - let mut items = Vec::with_capacity(seq.raw_len()); - for v in seq.sequence_values::() { - items.push(Text::try_from(v?).map_err(|_| EXPECTED.into_lua_err())?); - } - + let new = lua.create_function(|_, (_, items): (Table, Vec)| { Ok(Self { inner: ratatui::widgets::List::new(items), ..Default::default() }) })?; diff --git a/yazi-binding/src/elements/pos.rs b/yazi-binding/src/elements/pos.rs index 07304028..15fe8d3d 100644 --- a/yazi-binding/src/elements/pos.rs +++ b/yazi-binding/src/elements/pos.rs @@ -1,6 +1,6 @@ use std::{ops::Deref, str::FromStr}; -use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, Value}; +use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value}; use super::Pad; @@ -29,10 +29,10 @@ impl From for yazi_config::popup::Position { fn from(value: Pos) -> Self { value.inner } } -impl TryFrom for Pos { +impl TryFrom
for Pos { type Error = mlua::Error; - fn try_from(t: mlua::Table) -> Result { + fn try_from(t: Table) -> Result { use yazi_config::popup::{Offset, Origin, Position}; Ok(Self::from(Position { @@ -47,10 +47,8 @@ impl TryFrom for Pos { } } -impl TryFrom for Pos { - type Error = mlua::Error; - - fn try_from(value: Value) -> Result { +impl FromLua for Pos { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { Ok(match value { Value::Table(tbl) => Self::try_from(tbl)?, Value::UserData(ud) => { @@ -75,10 +73,9 @@ impl Pos { position.into_lua(lua) } - pub fn new_input(v: Value) -> mlua::Result { - let mut p = Self::try_from(v)?; - p.inner.offset.height = 3; - Ok(p) + pub fn with_height(mut self, height: u16) -> Self { + self.inner.offset.height = height; + self } } diff --git a/yazi-binding/src/elements/renderable.rs b/yazi-binding/src/elements/renderable.rs index 8d4b5578..2a33cdb1 100644 --- a/yazi-binding/src/elements/renderable.rs +++ b/yazi-binding/src/elements/renderable.rs @@ -1,6 +1,6 @@ use std::any::TypeId; -use mlua::{AnyUserData, ExternalError}; +use mlua::{AnyUserData, ExternalError, FromLua, Lua, Value}; use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text}; use crate::{Error, elements::Area}; @@ -81,17 +81,11 @@ impl TryFrom<&AnyUserData> for Renderable { Some(t) if t == TypeId::of::() => Self::Border(ud.take()?), Some(t) if t == TypeId::of::() => Self::Gauge(Box::new(ud.take()?)), Some(t) if t == TypeId::of::
() => Self::Table(Box::new(ud.take()?)), - _ => Err(format!("expected a UserData of renderable element, not: {ud:#?}").into_lua_err())?, + _ => Err(format!("expected a renderable userdata, not: {ud:#?}").into_lua_err())?, }) } } -impl TryFrom for Renderable { - type Error = mlua::Error; - - fn try_from(ud: AnyUserData) -> Result { Self::try_from(&ud) } -} - impl From for Renderable { fn from(error: Error) -> Self { Self::Text(Text { @@ -101,3 +95,12 @@ impl From for Renderable { }) } } + +impl FromLua for Renderable { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::UserData(ud) => Self::try_from(&ud), + _ => Err(format!("expected a renderable userdata, not: {value:#?}").into_lua_err()), + } + } +} diff --git a/yazi-binding/src/elements/row.rs b/yazi-binding/src/elements/row.rs index c088fa22..7e0ebbbc 100644 --- a/yazi-binding/src/elements/row.rs +++ b/yazi-binding/src/elements/row.rs @@ -1,4 +1,4 @@ -use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, Value}; +use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value}; use super::Cell; @@ -36,10 +36,8 @@ impl From for ratatui::widgets::Row<'static> { } } -impl TryFrom for Row { - type Error = mlua::Error; - - fn try_from(value: Value) -> Result { +impl FromLua for Row { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { Ok(match value { Value::UserData(ud) => { if let Ok(row) = ud.take() { diff --git a/yazi-binding/src/elements/span.rs b/yazi-binding/src/elements/span.rs index 8858a1fb..22609808 100644 --- a/yazi-binding/src/elements/span.rs +++ b/yazi-binding/src/elements/span.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, ops::{Deref, DerefMut}}; -use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; +use mlua::{AnyUserData, ExternalError, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, UserDataMethods, Value}; use unicode_width::UnicodeWidthChar; const EXPECTED: &str = "expected a string or Span"; @@ -19,7 +19,7 @@ impl DerefMut for Span { impl Span { pub fn compose(lua: &Lua) -> mlua::Result { - let new = lua.create_function(|_, (_, value): (Table, Value)| Self::try_from(value))?; + let new = lua.create_function(|_, (_, span): (Table, Self)| Ok(span))?; let span = lua.create_table()?; span.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?))?; @@ -58,10 +58,8 @@ impl Span { } } -impl TryFrom for Span { - type Error = mlua::Error; - - fn try_from(value: Value) -> Result { +impl FromLua for Span { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { Ok(Self(match value { Value::String(s) => s.to_string_lossy().into(), Value::UserData(ud) => { diff --git a/yazi-binding/src/elements/table.rs b/yazi-binding/src/elements/table.rs index 82ce5d07..6bedaa95 100644 --- a/yazi-binding/src/elements/table.rs +++ b/yazi-binding/src/elements/table.rs @@ -1,11 +1,9 @@ -use mlua::{AnyUserData, ExternalError, IntoLua, Lua, MetaMethod, UserData, Value}; +use mlua::{AnyUserData, IntoLua, Lua, MetaMethod, UserData, Value}; use ratatui::widgets::StatefulWidget; use super::{Area, Row}; use crate::{Style, elements::Constraint}; -const EXPECTED: &str = "expected a table of Rows"; - // --- Table #[derive(Clone, Debug, Default)] pub struct Table { @@ -33,12 +31,7 @@ pub struct Table { impl Table { pub fn compose(lua: &Lua) -> mlua::Result { - let new = lua.create_function(|_, (_, seq): (mlua::Table, mlua::Table)| { - let mut rows = Vec::with_capacity(seq.raw_len()); - for v in seq.sequence_values::() { - rows.push(Row::try_from(v?).map_err(|_| EXPECTED.into_lua_err())?); - } - + let new = lua.create_function(|_, (_, rows): (mlua::Table, Vec)| { Ok(Self { rows, ..Default::default() }) })?; @@ -101,12 +94,12 @@ impl UserData for Table { fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); - methods.add_function_mut("header", |_, (ud, value): (AnyUserData, Value)| { - ud.borrow_mut::()?.header = Some(Row::try_from(value)?.into()); + methods.add_function_mut("header", |_, (ud, header): (AnyUserData, Row)| { + ud.borrow_mut::()?.header = Some(header.into()); Ok(ud) }); - methods.add_function_mut("footer", |_, (ud, value): (AnyUserData, Value)| { - ud.borrow_mut::()?.footer = Some(Row::try_from(value)?.into()); + methods.add_function_mut("footer", |_, (ud, footer): (AnyUserData, Row)| { + ud.borrow_mut::()?.footer = Some(footer.into()); Ok(ud) }); methods.add_function_mut("widths", |_, (ud, widths): (AnyUserData, Vec)| { diff --git a/yazi-binding/src/elements/text.rs b/yazi-binding/src/elements/text.rs index 69147602..a1ed7f16 100644 --- a/yazi-binding/src/elements/text.rs +++ b/yazi-binding/src/elements/text.rs @@ -1,7 +1,7 @@ use std::{any::TypeId, mem}; use ansi_to_tui::IntoText; -use mlua::{AnyUserData, ExternalError, ExternalResult, IntoLua, Lua, MetaMethod, Table, UserData, Value}; +use mlua::{AnyUserData, ExternalError, ExternalResult, FromLua, IntoLua, Lua, MetaMethod, Table, UserData, Value}; use ratatui::widgets::Widget; use super::{Area, Line, Span, Wrap}; @@ -21,7 +21,7 @@ pub struct Text { impl Text { pub fn compose(lua: &Lua) -> mlua::Result { - let new = lua.create_function(|_, (_, value): (Table, Value)| Self::try_from(value))?; + let new = lua.create_function(|_, (_, text): (Table, Self)| Ok(text))?; let parse = lua.create_function(|_, code: mlua::String| { Ok(Self { inner: code.as_bytes().into_text().into_lua_err()?, ..Default::default() }) @@ -41,26 +41,6 @@ impl Text { } } -impl TryFrom for Text { - type Error = mlua::Error; - - fn try_from(value: Value) -> mlua::Result { - let inner = match value { - Value::Table(tb) => return Self::try_from(tb), - Value::String(s) => s.to_string_lossy().into(), - Value::UserData(ud) => match ud.type_id() { - Some(t) if t == TypeId::of::() => ud.take::()?.inner.into(), - Some(t) if t == TypeId::of::() => ud.take::()?.0.into(), - Some(t) if t == TypeId::of::() => return ud.take(), - Some(t) if t == TypeId::of::() => ud.take::()?.into_string().into(), - _ => Err(EXPECTED.into_lua_err())?, - }, - _ => Err(EXPECTED.into_lua_err())?, - }; - Ok(Self { inner, ..Default::default() }) - } -} - impl TryFrom
for Text { type Error = mlua::Error; @@ -102,6 +82,24 @@ impl From for ratatui::widgets::Paragraph<'static> { } } +impl FromLua for Text { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + let inner = match value { + Value::Table(tb) => return Self::try_from(tb), + Value::String(s) => s.to_string_lossy().into(), + Value::UserData(ud) => match ud.type_id() { + Some(t) if t == TypeId::of::() => ud.take::()?.inner.into(), + Some(t) if t == TypeId::of::() => ud.take::()?.0.into(), + Some(t) if t == TypeId::of::() => return ud.take(), + Some(t) if t == TypeId::of::() => ud.take::()?.into_string().into(), + _ => Err(EXPECTED.into_lua_err())?, + }, + _ => Err(EXPECTED.into_lua_err())?, + }; + Ok(Self { inner, ..Default::default() }) + } +} + impl UserData for Text { fn add_methods>(methods: &mut M) { crate::impl_area_method!(methods); diff --git a/yazi-binding/src/file.rs b/yazi-binding/src/file.rs index 62d1c5c4..d4c5761c 100644 --- a/yazi-binding/src/file.rs +++ b/yazi-binding/src/file.rs @@ -1,7 +1,6 @@ use std::ops::Deref; -use mlua::{AnyUserData, ExternalError, Lua, ObjectLike, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; -use yazi_codegen::FromLuaOwned; +use mlua::{AnyUserData, ExternalError, FromLua, Lua, ObjectLike, Table, UserData, UserDataFields, UserDataMethods, UserDataRef, Value}; use crate::{Cha, Url, impl_file_fields, impl_file_methods}; @@ -9,7 +8,7 @@ pub type FileRef = UserDataRef; const EXPECTED: &str = "expected a table, File, or fs::File"; -#[derive(Clone, FromLuaOwned)] +#[derive(Clone)] pub struct File { inner: yazi_fs::File, @@ -47,19 +46,7 @@ impl File { } pub fn install(lua: &Lua) -> mlua::Result<()> { - lua.globals().raw_set("File", lua.create_function(|_, value: Value| Self::try_from(value))?) - } -} - -impl TryFrom for File { - type Error = mlua::Error; - - fn try_from(value: Value) -> Result { - match value { - Value::Table(tbl) => Self::try_from(tbl), - Value::UserData(ud) => Self::try_from(ud), - _ => Err(EXPECTED.into_lua_err())?, - } + lua.globals().raw_set("File", lua.create_function(|_, file: Self| Ok(file))?) } } @@ -79,7 +66,17 @@ impl TryFrom for File { type Error = mlua::Error; fn try_from(value: AnyUserData) -> Result { - Ok(if let Ok(me) = value.borrow::() { me.clone() } else { value.get("bare")? }) + Ok(if let Ok(me) = value.take::() { me } else { value.get("bare")? }) + } +} + +impl FromLua for File { + fn from_lua(value: Value, _: &Lua) -> mlua::Result { + match value { + Value::Table(tbl) => Self::try_from(tbl), + Value::UserData(ud) => Self::try_from(ud), + _ => Err(EXPECTED.into_lua_err())?, + } } } diff --git a/yazi-binding/src/macros.rs b/yazi-binding/src/macros.rs index 4cb71fac..af02e660 100644 --- a/yazi-binding/src/macros.rs +++ b/yazi-binding/src/macros.rs @@ -117,6 +117,7 @@ macro_rules! impl_style_method { macro_rules! impl_style_shorthands { ($methods:ident, $($field:tt).+) => { $methods.add_function_mut("fg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| { + use mlua::FromLua; use ratatui::style::Modifier; let me = &mut ud.borrow_mut::()?.$($field).+; @@ -128,12 +129,13 @@ macro_rules! impl_style_shorthands { me.fg.map($crate::Color).into_lua(lua) } _ => { - me.fg = Some($crate::Color::try_from(value)?.0); + me.fg = Some($crate::Color::from_lua(value, lua)?.0); ud.into_lua(lua) } } }); $methods.add_function_mut("bg", |lua, (ud, value): (mlua::AnyUserData, mlua::Value)| { + use mlua::FromLua; use ratatui::style::Modifier; let me = &mut ud.borrow_mut::()?.$($field).+; @@ -145,7 +147,7 @@ macro_rules! impl_style_shorthands { me.bg.map($crate::Color).into_lua(lua) } _ => { - me.bg = Some($crate::Color::try_from(value)?.0); + me.bg = Some($crate::Color::from_lua(value, lua)?.0); ud.into_lua(lua) } } diff --git a/yazi-binding/src/range.rs b/yazi-binding/src/range.rs index aa864e04..e6a69b83 100644 --- a/yazi-binding/src/range.rs +++ b/yazi-binding/src/range.rs @@ -1,4 +1,4 @@ -use mlua::{IntoLua, Lua}; +use mlua::{IntoLua, Lua, Value}; pub struct Range(std::ops::Range); @@ -10,7 +10,7 @@ impl IntoLua for Range where T: IntoLua, { - fn into_lua(self, lua: &Lua) -> mlua::Result { + fn into_lua(self, lua: &Lua) -> mlua::Result { lua.create_sequence_from([self.0.start, self.0.end])?.into_lua(lua) } } diff --git a/yazi-boot/Cargo.toml b/yazi-boot/Cargo.toml index 23b3fafd..7933fc47 100644 --- a/yazi-boot/Cargo.toml +++ b/yazi-boot/Cargo.toml @@ -32,7 +32,7 @@ yazi-shared = { path = "../yazi-shared", version = "26.2.2" } # External dependencies clap = { workspace = true } -clap_complete = "4.5.66" +clap_complete = "4.6.0" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.10" +clap_complete_nushell = "4.6.0" vergen-gitcl = { version = "9.1.0", features = [ "build", "rustc" ] } diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index f98e7a08..ca446679 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -46,9 +46,9 @@ yazi-shared = { path = "../yazi-shared", version = "26.2.2" } # External build dependencies anyhow = { workspace = true } clap = { workspace = true } -clap_complete = "4.5.66" +clap_complete = "4.6.0" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.10" +clap_complete_nushell = "4.6.0" serde = { workspace = true } serde_json = { workspace = true } vergen-gitcl = { version = "9.1.0", features = [ "build" ] } diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index fd49971c..516b44f0 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -61,7 +61,7 @@ tokio = { workspace = true } tokio-stream = { workspace = true } tracing = { workspace = true } tracing-appender = "0.2.4" -tracing-subscriber = { version = "0.3.22", features = [ "env-filter" ] } +tracing-subscriber = { version = "0.3.23", features = [ "env-filter" ] } [target."cfg(unix)".dependencies] libc = { workspace = true } diff --git a/yazi-plugin/src/fs/op.rs b/yazi-plugin/src/fs/op.rs index 4888e92a..93dcd2c7 100644 --- a/yazi-plugin/src/fs/op.rs +++ b/yazi-plugin/src/fs/op.rs @@ -1,4 +1,4 @@ -use mlua::{IntoLua, Lua, Table}; +use mlua::{IntoLua, Lua, Table, Value}; use yazi_binding::{Cha, File, Id, Path, Url}; pub(super) struct FilesOp(yazi_fs::FilesOp); @@ -42,7 +42,7 @@ impl FilesOp { } impl IntoLua for FilesOp { - fn into_lua(self, lua: &Lua) -> mlua::Result { + fn into_lua(self, lua: &Lua) -> mlua::Result { lua.create_any_userdata(self.0)?.into_lua(lua) } } diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index 6a0b0bcf..d8f3f486 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -56,7 +56,7 @@ impl Utils { value: t.raw_get("value").unwrap_or_default(), cursor: None, // TODO obscure: t.raw_get("obscure")?, - position: Pos::new_input(t.raw_get("pos")?)?.into(), + position: t.raw_get::("pos")?.with_height(3).into(), realtime, completion: false, })); @@ -77,22 +77,15 @@ impl Utils { } pub(super) fn confirm(lua: &Lua) -> mlua::Result { - fn body(t: &Table) -> mlua::Result> { - Ok(match t.raw_get::("body")? { - Value::Nil => Default::default(), - v => Text::try_from(v)?.into(), - }) - } - lua.create_async_function(|lua, t: Table| async move { if runtime!(lua)?.blocking { return Err("Cannot call `ya.confirm()` while main thread is blocked".into_lua_err()); } let result = ConfirmProxy::show(ConfirmCfg { - position: Pos::try_from(t.raw_get::("pos")?)?.into(), - title: Line::try_from(t.raw_get::("title")?)?.into(), - body: body(&t)?, + position: t.raw_get::("pos")?.into(), + title: t.raw_get::("title")?.into(), + body: t.raw_get::>("body")?.unwrap_or_default().into(), list: Default::default(), // TODO }); diff --git a/yazi-plugin/src/utils/preview.rs b/yazi-plugin/src/utils/preview.rs index eac529c9..6e509f52 100644 --- a/yazi-plugin/src/utils/preview.rs +++ b/yazi-plugin/src/utils/preview.rs @@ -1,4 +1,4 @@ -use mlua::{AnyUserData, ExternalError, Function, IntoLuaMulti, Lua, Table, Value}; +use mlua::{ExternalError, Function, IntoLuaMulti, Lua, Table, Value}; use yazi_binding::{Error, elements::{Area, Renderable, Text}}; use yazi_config::YAZI; use yazi_fs::FsUrl; @@ -41,10 +41,7 @@ impl Utils { let mut lock = PreviewLock::try_from(t)?; lock.data = match value { Value::Nil => vec![], - Value::Table(tbl) => tbl - .sequence_values::() - .map(|ud| ud.and_then(Renderable::try_from)) - .collect::>()?, + Value::Table(tbl) => tbl.sequence_values::().collect::>()?, Value::UserData(ud) => match Renderable::try_from(&ud) { Ok(r) => vec![r], Err(e) => { diff --git a/yazi-plugin/src/utils/spot.rs b/yazi-plugin/src/utils/spot.rs index 056c1bc5..c8b68f77 100644 --- a/yazi-plugin/src/utils/spot.rs +++ b/yazi-plugin/src/utils/spot.rs @@ -36,9 +36,9 @@ impl Utils { } pub(super) fn spot_widgets(lua: &Lua) -> mlua::Result { - lua.create_function(|_, (t, widgets): (Table, Vec)| { + lua.create_function(|_, (t, widgets): (Table, Vec)| { let mut lock = SpotLock::try_from(t)?; - lock.data = widgets.into_iter().map(Renderable::try_from).collect::>()?; + lock.data = widgets; MgrProxy::update_spotted(UpdateSpottedOpt { lock }); Ok(())