yazi/yazi-actor/src/lives/core.rs

71 lines
1.8 KiB
Rust

use std::ops::Deref;
use mlua::{AnyUserData, IntoLua, LuaString, MetaMethod, UserData, UserDataMethods, UserDataRef, Value};
use paste::paste;
use super::{Lives, PtrCell};
pub(super) type CoreRef = UserDataRef<Core>;
pub(super) struct Core {
inner: PtrCell<yazi_core::Core>,
c_active: Option<Value>,
c_tabs: Option<Value>,
c_tasks: Option<Value>,
c_yanked: Option<Value>,
c_input: Option<Value>,
c_which: Option<Value>,
c_layer: Option<Value>,
}
impl Deref for Core {
type Target = yazi_core::Core;
fn deref(&self) -> &Self::Target { &self.inner }
}
impl Core {
pub(super) fn make(inner: &yazi_core::Core) -> mlua::Result<AnyUserData> {
Lives::scoped_userdata(Self {
inner: inner.into(),
c_active: None,
c_tabs: None,
c_tasks: None,
c_yanked: None,
c_input: None,
c_which: None,
c_layer: None,
})
}
}
impl UserData for Core {
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
methods.add_meta_method_mut(MetaMethod::Index, |lua, me, key: LuaString| {
macro_rules! reuse {
($key:ident, $value:expr) => {
match paste! { &me.[<c_ $key>] } {
Some(v) => v.clone(),
None => {
let v = $value?.into_lua(lua)?;
paste! { me.[<c_ $key>] = Some(v.clone()); };
v
}
}
};
}
Ok(match &*key.as_bytes() {
b"active" => reuse!(active, super::Tab::make(me.active())),
b"tabs" => reuse!(tabs, super::Tabs::make(&me.mgr.tabs)),
b"tasks" => reuse!(tasks, super::Tasks::make(&me.tasks)),
b"yanked" => reuse!(yanked, super::Yanked::make(&me.mgr.yanked)),
b"input" => reuse!(input, super::Input::make(&me.input)),
b"which" => reuse!(which, super::Which::make(&me.which)),
b"layer" => reuse!(layer, Ok::<_, mlua::Error>(me.layer())),
_ => Value::Nil,
})
});
}
}