use std::{borrow::Cow, ops::Deref}; use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods, Value}; use yazi_binding::{Id, UrlRef, cached_field}; use super::{Finder, Folder, Lives, Mode, Preference, Preview, PtrCell, Selected}; pub(super) struct Tab { inner: PtrCell, v_name: Option, v_mode: Option, v_pref: Option, v_current: Option, v_parent: Option, v_selected: Option, v_preview: Option, v_finder: Option, } impl Deref for Tab { type Target = yazi_core::tab::Tab; fn deref(&self) -> &Self::Target { &self.inner } } impl Tab { pub(super) fn make(inner: &yazi_core::tab::Tab) -> mlua::Result { Lives::scoped_userdata(Self { inner: inner.into(), v_name: None, v_mode: None, v_pref: None, v_current: None, v_parent: None, v_selected: None, v_preview: None, v_finder: None, }) } } impl UserData for Tab { fn add_fields>(fields: &mut F) { fields.add_field_method_get("id", |_, me| Ok(Id(me.id))); cached_field!(fields, name, |lua, me| { match me.name() { Cow::Borrowed(s) => lua.create_string(s), Cow::Owned(s) => lua.create_external_string(s), } }); cached_field!(fields, mode, |_, me| Mode::make(&me.mode)); cached_field!(fields, pref, |_, me| Preference::make(&me.pref)); cached_field!(fields, current, |_, me| Folder::make(None, &me.current, me)); cached_field!(fields, parent, |_, me| { me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose() }); cached_field!(fields, selected, |_, me| Selected::make(&me.selected)); cached_field!(fields, preview, |_, me| Preview::make(me)); cached_field!(fields, finder, |_, me| me.finder.as_ref().map(Finder::make).transpose()); } fn add_methods>(methods: &mut M) { methods.add_method("history", |_, me, url: UrlRef| { me.history.get(url.as_ref()).map(|f| Folder::make(None, f, me)).transpose() }); } }