mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 14:51:03 +00:00
106 lines
2.9 KiB
Rust
106 lines
2.9 KiB
Rust
use std::{borrow::Cow, fmt::Display, io};
|
|
|
|
use mlua::{ExternalError, Lua, LuaString, MetaMethod, UserData, UserDataFields, UserDataMethods, Value};
|
|
use yazi_codegen::FromLuaOwned;
|
|
use yazi_shim::SStr;
|
|
|
|
#[derive(FromLuaOwned)]
|
|
pub enum Error {
|
|
Io(std::io::Error),
|
|
Fs(yazi_shim::fs::Error),
|
|
Serde(serde_json::Error),
|
|
Custom(SStr),
|
|
}
|
|
|
|
impl From<Error> for io::Error {
|
|
fn from(value: Error) -> Self {
|
|
match value {
|
|
Error::Io(e) => e,
|
|
Error::Fs(e) => e.into(),
|
|
Error::Serde(e) => Self::other(e),
|
|
Error::Custom(s) => Self::other(s.into_owned()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Error {
|
|
pub fn install(lua: &Lua) -> mlua::Result<()> {
|
|
let custom = lua.create_function(|_, msg: String| Ok(Self::custom(msg)))?;
|
|
|
|
let fs = lua.create_function(|_, value: Value| {
|
|
Ok(Self::Fs(match value {
|
|
Value::Table(t) => yazi_shim::fs::Error::custom(
|
|
&t.raw_get::<LuaString>("kind")?.to_str()?,
|
|
t.raw_get("code")?,
|
|
&t.raw_get::<LuaString>("message")?.to_str()?,
|
|
)?,
|
|
_ => Err("expected a table".into_lua_err())?,
|
|
}))
|
|
})?;
|
|
|
|
lua.globals().raw_set("Error", lua.create_table_from([("custom", custom), ("fs", fs)])?)
|
|
}
|
|
|
|
pub fn custom(msg: impl Into<SStr>) -> Self { Self::Custom(msg.into()) }
|
|
|
|
pub fn into_string(self) -> SStr {
|
|
match self {
|
|
Self::Io(e) => Cow::Owned(e.to_string()),
|
|
Self::Fs(e) => Cow::Owned(e.to_string()),
|
|
Self::Serde(e) => Cow::Owned(e.to_string()),
|
|
Self::Custom(s) => s,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for Error {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Io(e) => write!(f, "{e}"),
|
|
Self::Fs(e) => write!(f, "{e}"),
|
|
Self::Serde(e) => write!(f, "{e}"),
|
|
Self::Custom(s) => write!(f, "{s}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl UserData for Error {
|
|
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
|
|
fields.add_field_method_get("code", |_, me| {
|
|
Ok(match me {
|
|
Self::Io(e) => e.raw_os_error(),
|
|
Self::Fs(e) => e.raw_os_error(),
|
|
_ => None,
|
|
})
|
|
});
|
|
fields.add_field_method_get("kind", |_, me| {
|
|
Ok(match me {
|
|
Self::Io(e) => Some(yazi_shim::fs::Error::from(e.kind()).kind_str()),
|
|
Self::Fs(e) => Some(e.kind_str()),
|
|
_ => None,
|
|
})
|
|
});
|
|
}
|
|
|
|
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
|
methods.add_meta_method(MetaMethod::ToString, |lua, me, ()| {
|
|
Ok(match me {
|
|
Self::Io(_) | Self::Fs(_) | Self::Serde(_) => lua.create_external_string(me.to_string()),
|
|
Self::Custom(s) => lua.create_string(&**s),
|
|
})
|
|
});
|
|
methods.add_meta_function(MetaMethod::Concat, |lua, (lhs, rhs): (Value, Value)| {
|
|
match (lhs, rhs) {
|
|
(Value::String(l), Value::UserData(r)) => {
|
|
let r = r.borrow::<Self>()?;
|
|
lua.create_external_string([&l.as_bytes(), r.to_string().as_bytes()].concat())
|
|
}
|
|
(Value::UserData(l), Value::String(r)) => {
|
|
let l = l.borrow::<Self>()?;
|
|
lua.create_external_string([l.to_string().as_bytes(), &r.as_bytes()].concat())
|
|
}
|
|
_ => Err("only string can be concatenated with Error".into_lua_err()),
|
|
}
|
|
});
|
|
}
|
|
}
|