feat!: use an Error userdata instead of a plain error code for I/O errors

This commit is contained in:
sxyazi 2024-11-23 15:49:07 +08:00
parent 99d6c81fbb
commit 143d13019f
No known key found for this signature in database
6 changed files with 34 additions and 23 deletions

View file

@ -1,6 +1,7 @@
use mlua::{Lua, MetaMethod, UserData, UserDataMethods};
use mlua::{IntoLua, Lua, MetaMethod, UserData, UserDataFields, UserDataMethods};
pub enum Error {
Io(std::io::Error),
Serde(serde_json::Error),
Custom(String),
}
@ -14,11 +15,21 @@ impl Error {
}
impl UserData for Error {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| {
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
fields.add_field_method_get("code", |_, me| {
Ok(match me {
Error::Serde(e) => e.to_string(),
Error::Custom(s) => s.clone(),
Error::Io(e) => e.raw_os_error(),
_ => None,
})
});
}
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method(MetaMethod::ToString, |lua, me, ()| {
Ok(match me {
Error::Io(e) => e.to_string().into_lua(lua),
Error::Serde(e) => e.to_string().into_lua(lua),
Error::Custom(s) => lua.create_string(s)?.into_lua(lua),
})
});
}

View file

@ -3,7 +3,7 @@ use mlua::{ExternalError, ExternalResult, Function, IntoLua, IntoLuaMulti, Lua,
use tokio::fs;
use yazi_shared::fs::remove_dir_clean;
use crate::{bindings::{Cast, Cha}, file::File, url::{Url, UrlRef}};
use crate::{Error, bindings::{Cast, Cha}, file::File, url::{Url, UrlRef}};
pub fn compose(lua: &Lua) -> mlua::Result<Table> {
let index = lua.create_function(|lua, (ts, key): (Table, mlua::String)| {
@ -37,7 +37,7 @@ fn cha(lua: &Lua) -> mlua::Result<Function> {
match meta {
Ok(m) => (Cha::from(m), Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
})
}
@ -46,7 +46,7 @@ fn write(lua: &Lua) -> mlua::Result<Function> {
lua.create_async_function(|lua, (url, data): (UrlRef, mlua::String)| async move {
match fs::write(&*url, data.as_bytes()).await {
Ok(_) => (true, Value::Nil).into_lua_multi(&lua),
Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
}
})
}
@ -63,7 +63,7 @@ fn remove(lua: &Lua) -> mlua::Result<Function> {
match result {
Ok(_) => (true, Value::Nil).into_lua_multi(&lua),
Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
}
})
}
@ -90,7 +90,7 @@ fn read_dir(lua: &Lua) -> mlua::Result<Function> {
let mut it = match fs::read_dir(&*dir).await {
Ok(it) => it,
Err(e) => return (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => return (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
};
let mut files = vec![];
@ -128,7 +128,7 @@ fn unique_name(lua: &Lua) -> mlua::Result<Function> {
lua.create_async_function(|lua, url: UrlRef| async move {
match yazi_shared::fs::unique_name(url.clone(), async { false }).await {
Ok(u) => (Url::cast(&lua, u)?, Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
})
}

View file

@ -5,7 +5,7 @@ use mlua::{AnyUserData, ExternalError, IntoLua, IntoLuaMulti, Table, UserData, V
use tokio::{io::{self, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter}, process::{ChildStderr, ChildStdin, ChildStdout}, select};
use super::Status;
use crate::process::Output;
use crate::{Error, process::Output};
pub struct Child {
inner: tokio::process::Child,
@ -83,7 +83,7 @@ impl UserData for Child {
};
match stdin.write_all(&src.as_bytes()).await {
Ok(()) => (true, Value::Nil).into_lua_multi(&lua),
Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
}
});
methods.add_async_method_mut("flush", |lua, mut me, ()| async move {
@ -92,7 +92,7 @@ impl UserData for Child {
};
match stdin.flush().await {
Ok(()) => (true, Value::Nil).into_lua_multi(&lua),
Err(e) => (false, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (false, Error::Io(e)).into_lua_multi(&lua),
}
});
@ -100,7 +100,7 @@ impl UserData for Child {
drop(me.stdin.take());
match me.inner.wait().await {
Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
});
methods.add_async_function("wait_with_output", |lua, ud: AnyUserData| async move {
@ -129,12 +129,12 @@ impl UserData for Child {
(Output::new(std::process::Output { status, stdout, stderr }), Value::Nil)
.into_lua_multi(&lua)
}
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
});
methods.add_method_mut("start_kill", |lua, me, ()| match me.inner.start_kill() {
Ok(_) => (true, Value::Nil).into_lua_multi(lua),
Err(e) => (false, e.raw_os_error()).into_lua_multi(lua),
Err(e) => (false, Error::Io(e)).into_lua_multi(lua),
});
methods.add_method_mut("take_stdin", |lua, me, ()| match me.stdin.take() {

View file

@ -4,7 +4,7 @@ use mlua::{AnyUserData, ExternalError, IntoLuaMulti, Lua, Table, UserData, Value
use tokio::process::{ChildStderr, ChildStdin, ChildStdout};
use super::{Child, output::Output};
use crate::process::Status;
use crate::{Error, process::Status};
pub struct Command {
inner: tokio::process::Command,
@ -103,18 +103,18 @@ impl UserData for Command {
});
methods.add_method_mut("spawn", |lua, me, ()| match me.inner.spawn() {
Ok(child) => (Child::new(child), Value::Nil).into_lua_multi(lua),
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(lua),
});
methods.add_async_method_mut("output", |lua, mut me, ()| async move {
match me.inner.output().await {
Ok(output) => (Output::new(output), Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
});
methods.add_async_method_mut("status", |lua, mut me, ()| async move {
match me.inner.status().await {
Ok(status) => (Status::new(status), Value::Nil).into_lua_multi(&lua),
Err(e) => (Value::Nil, e.raw_os_error()).into_lua_multi(&lua),
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
}
});
}

View file

@ -18,7 +18,7 @@ pub async fn maybe_exists(p: impl AsRef<Path>) -> bool {
#[inline]
pub async fn must_be_dir(p: impl AsRef<Path>) -> bool {
fs::metadata(p).await.map_or(false, |m| m.is_dir())
fs::metadata(p).await.is_ok_and(|m| m.is_dir())
}
#[inline]

View file

@ -16,7 +16,7 @@ impl Urn {
#[cfg(unix)]
#[inline]
pub fn is_hidden(&self) -> bool {
self.name().map_or(false, |s| s.as_encoded_bytes().starts_with(b"."))
self.name().is_some_and(|s| s.as_encoded_bytes().starts_with(b"."))
}
}