refactor: implement FromLua instead of TryFrom<Value>

This commit is contained in:
sxyazi 2026-03-13 20:06:51 +08:00
parent 3534ba0705
commit 18e52f6155
No known key found for this signature in database
21 changed files with 130 additions and 172 deletions

View file

@ -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<Value> for Color {
type Error = mlua::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
impl FromLua for Color {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
Ok(Self(match value {
Value::String(s) => ratatui::style::Color::from_str(&s.to_str()?).into_lua_err()?,
Value::UserData(ud) => ud.borrow::<Self>()?.0,

View file

@ -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<AnyUserData> for Area {
}
impl FromLua for Area {
fn from_lua(value: Value, _: &mlua::Lua) -> mlua::Result<Self> {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
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<mlua::Value> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
match self {
Self::Pos(pos) => pos.into_lua(lua),
Self::Rect(rect) => rect.into_lua(lua),

View file

@ -78,14 +78,14 @@ impl UserData for Border {
});
methods.add_function_mut(
"title",
|_, (ud, line, position): (AnyUserData, Value, Option<u8>)| {
|_, (ud, line, position): (AnyUserData, Line, Option<u8>)| {
let position = if position == Some(Borders::BOTTOM.bits()) {
ratatui::widgets::TitlePosition::Bottom
} else {
ratatui::widgets::TitlePosition::Top
};
ud.borrow_mut::<Self>()?.titles.push((position, Line::try_from(line)?.inner));
ud.borrow_mut::<Self>()?.titles.push((position, line.inner));
Ok(ud)
},
);

View file

@ -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<Cell> for ratatui::widgets::Cell<'static> {
}
impl FromLua for Cell {
fn from_lua(value: mlua::Value, _: &mlua::Lua) -> mlua::Result<Self> {
Ok(Self { text: Text::try_from(value).map_err(|_| EXPECTED.into_lua_err())?.inner })
fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> {
Ok(Self { text: Text::from_lua(value, lua)?.inner })
}
}

View file

@ -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::<AnyUserData>() {
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::<Renderable>() {
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:?}"),
}
}

View file

@ -61,8 +61,8 @@ impl UserData for Gauge {
Ok(ud)
});
methods.add_function_mut("label", |_, (ud, label): (AnyUserData, Value)| {
ud.borrow_mut::<Self>()?.label = Some(Span::try_from(label)?.0);
methods.add_function_mut("label", |_, (ud, label): (AnyUserData, Span)| {
ud.borrow_mut::<Self>()?.label = Some(label.0);
Ok(ud)
});

View file

@ -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<Value> {
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<Value> for Line {
type Error = mlua::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
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<Table> for Line {
type Error = mlua::Error;
@ -108,6 +84,28 @@ impl From<Line> for ratatui::text::Line<'static> {
fn from(value: Line) -> Self { value.inner }
}
impl FromLua for Line {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
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<M: UserDataMethods<Self>>(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::<Self>()?;
let max = t.raw_get("max")?;
@ -134,7 +132,7 @@ impl UserData for Line {
let ellipsis = match t.raw_get::<Value>("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)
}
};

View file

@ -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<Value> {
let new = lua.create_function(|_, (_, seq): (Table, Table)| {
let mut items = Vec::with_capacity(seq.raw_len());
for v in seq.sequence_values::<Value>() {
items.push(Text::try_from(v?).map_err(|_| EXPECTED.into_lua_err())?);
}
let new = lua.create_function(|_, (_, items): (Table, Vec<Text>)| {
Ok(Self { inner: ratatui::widgets::List::new(items), ..Default::default() })
})?;

View file

@ -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<Pos> for yazi_config::popup::Position {
fn from(value: Pos) -> Self { value.inner }
}
impl TryFrom<mlua::Table> for Pos {
impl TryFrom<Table> for Pos {
type Error = mlua::Error;
fn try_from(t: mlua::Table) -> Result<Self, Self::Error> {
fn try_from(t: Table) -> Result<Self, Self::Error> {
use yazi_config::popup::{Offset, Origin, Position};
Ok(Self::from(Position {
@ -47,10 +47,8 @@ impl TryFrom<mlua::Table> for Pos {
}
}
impl TryFrom<Value> for Pos {
type Error = mlua::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
impl FromLua for Pos {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
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<Self> {
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
}
}

View file

@ -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::<Border>() => Self::Border(ud.take()?),
Some(t) if t == TypeId::of::<Gauge>() => Self::Gauge(Box::new(ud.take()?)),
Some(t) if t == TypeId::of::<Table>() => 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<AnyUserData> for Renderable {
type Error = mlua::Error;
fn try_from(ud: AnyUserData) -> Result<Self, Self::Error> { Self::try_from(&ud) }
}
impl From<Error> for Renderable {
fn from(error: Error) -> Self {
Self::Text(Text {
@ -101,3 +95,12 @@ impl From<Error> for Renderable {
})
}
}
impl FromLua for Renderable {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
match value {
Value::UserData(ud) => Self::try_from(&ud),
_ => Err(format!("expected a renderable userdata, not: {value:#?}").into_lua_err()),
}
}
}

View file

@ -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<Row> for ratatui::widgets::Row<'static> {
}
}
impl TryFrom<Value> for Row {
type Error = mlua::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
impl FromLua for Row {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
Ok(match value {
Value::UserData(ud) => {
if let Ok(row) = ud.take() {

View file

@ -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<Value> {
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<Value> for Span {
type Error = mlua::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
impl FromLua for Span {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
Ok(Self(match value {
Value::String(s) => s.to_string_lossy().into(),
Value::UserData(ud) => {

View file

@ -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<Value> {
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::<Value>() {
rows.push(Row::try_from(v?).map_err(|_| EXPECTED.into_lua_err())?);
}
let new = lua.create_function(|_, (_, rows): (mlua::Table, Vec<Row>)| {
Ok(Self { rows, ..Default::default() })
})?;
@ -101,12 +94,12 @@ impl UserData for Table {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
crate::impl_area_method!(methods);
methods.add_function_mut("header", |_, (ud, value): (AnyUserData, Value)| {
ud.borrow_mut::<Self>()?.header = Some(Row::try_from(value)?.into());
methods.add_function_mut("header", |_, (ud, header): (AnyUserData, Row)| {
ud.borrow_mut::<Self>()?.header = Some(header.into());
Ok(ud)
});
methods.add_function_mut("footer", |_, (ud, value): (AnyUserData, Value)| {
ud.borrow_mut::<Self>()?.footer = Some(Row::try_from(value)?.into());
methods.add_function_mut("footer", |_, (ud, footer): (AnyUserData, Row)| {
ud.borrow_mut::<Self>()?.footer = Some(footer.into());
Ok(ud)
});
methods.add_function_mut("widths", |_, (ud, widths): (AnyUserData, Vec<Constraint>)| {

View file

@ -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<Value> {
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<Value> for Text {
type Error = mlua::Error;
fn try_from(value: Value) -> mlua::Result<Self> {
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::<Line>() => ud.take::<Line>()?.inner.into(),
Some(t) if t == TypeId::of::<Span>() => ud.take::<Span>()?.0.into(),
Some(t) if t == TypeId::of::<Self>() => return ud.take(),
Some(t) if t == TypeId::of::<Error>() => ud.take::<Error>()?.into_string().into(),
_ => Err(EXPECTED.into_lua_err())?,
},
_ => Err(EXPECTED.into_lua_err())?,
};
Ok(Self { inner, ..Default::default() })
}
}
impl TryFrom<Table> for Text {
type Error = mlua::Error;
@ -102,6 +82,24 @@ impl From<Text> for ratatui::widgets::Paragraph<'static> {
}
}
impl FromLua for Text {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
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::<Line>() => ud.take::<Line>()?.inner.into(),
Some(t) if t == TypeId::of::<Span>() => ud.take::<Span>()?.0.into(),
Some(t) if t == TypeId::of::<Self>() => return ud.take(),
Some(t) if t == TypeId::of::<Error>() => ud.take::<Error>()?.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<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
crate::impl_area_method!(methods);

View file

@ -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<File>;
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<Value> for File {
type Error = mlua::Error;
fn try_from(value: Value) -> Result<Self, Self::Error> {
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<AnyUserData> for File {
type Error = mlua::Error;
fn try_from(value: AnyUserData) -> Result<Self, Self::Error> {
Ok(if let Ok(me) = value.borrow::<Self>() { me.clone() } else { value.get("bare")? })
Ok(if let Ok(me) = value.take::<Self>() { me } else { value.get("bare")? })
}
}
impl FromLua for File {
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
match value {
Value::Table(tbl) => Self::try_from(tbl),
Value::UserData(ud) => Self::try_from(ud),
_ => Err(EXPECTED.into_lua_err())?,
}
}
}

View file

@ -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::<Self>()?.$($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::<Self>()?.$($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)
}
}

View file

@ -1,4 +1,4 @@
use mlua::{IntoLua, Lua};
use mlua::{IntoLua, Lua, Value};
pub struct Range<T>(std::ops::Range<T>);
@ -10,7 +10,7 @@ impl<T> IntoLua for Range<T>
where
T: IntoLua,
{
fn into_lua(self, lua: &Lua) -> mlua::Result<mlua::Value> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
lua.create_sequence_from([self.0.start, self.0.end])?.into_lua(lua)
}
}

View file

@ -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<mlua::Value> {
fn into_lua(self, lua: &Lua) -> mlua::Result<Value> {
lua.create_any_userdata(self.0)?.into_lua(lua)
}
}

View file

@ -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>("pos")?.with_height(3).into(),
realtime,
completion: false,
}));
@ -77,22 +77,15 @@ impl Utils {
}
pub(super) fn confirm(lua: &Lua) -> mlua::Result<Function> {
fn body(t: &Table) -> mlua::Result<ratatui::widgets::Paragraph<'static>> {
Ok(match t.raw_get::<Value>("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::<Value>("pos")?)?.into(),
title: Line::try_from(t.raw_get::<Value>("title")?)?.into(),
body: body(&t)?,
position: t.raw_get::<Pos>("pos")?.into(),
title: t.raw_get::<Line>("title")?.into(),
body: t.raw_get::<Option<Text>>("body")?.unwrap_or_default().into(),
list: Default::default(), // TODO
});

View file

@ -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::<AnyUserData>()
.map(|ud| ud.and_then(Renderable::try_from))
.collect::<mlua::Result<_>>()?,
Value::Table(tbl) => tbl.sequence_values::<Renderable>().collect::<mlua::Result<_>>()?,
Value::UserData(ud) => match Renderable::try_from(&ud) {
Ok(r) => vec![r],
Err(e) => {

View file

@ -36,9 +36,9 @@ impl Utils {
}
pub(super) fn spot_widgets(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|_, (t, widgets): (Table, Vec<AnyUserData>)| {
lua.create_function(|_, (t, widgets): (Table, Vec<Renderable>)| {
let mut lock = SpotLock::try_from(t)?;
lock.data = widgets.into_iter().map(Renderable::try_from).collect::<mlua::Result<_>>()?;
lock.data = widgets;
MgrProxy::update_spotted(UpdateSpottedOpt { lock });
Ok(())