Skip to content

Commit 510cb14

Browse files
authored
feat: copy-on-write support for field caching (#2629)
1 parent 56d6e4a commit 510cb14

File tree

12 files changed

+53
-57
lines changed

12 files changed

+53
-57
lines changed

yazi-binding/src/macros.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22
macro_rules! cached_field {
33
($fields:ident, $key:ident, $value:expr) => {
44
$fields.add_field_function_get(stringify!($key), |lua, ud| {
5-
use mlua::IntoLua;
6-
ud.borrow_mut_scoped::<Self, mlua::Result<mlua::Value>>(|me| {
7-
match paste::paste! { &me.[<v_ $key>] } {
8-
Some(v) => Ok(v.clone()),
9-
None => {
10-
let v: mlua::Result<_> = $value(lua, me);
11-
let v = v?.into_lua(lua)?;
12-
paste::paste! { me.[<v_ $key>] = Some(v.clone()) };
13-
Ok(v)
14-
}
5+
use mlua::{Error::UserDataDestructed, IntoLua, Lua, Result, Value, Value::UserData};
6+
ud.borrow_mut_scoped::<Self, Result<Value>>(|me| match paste::paste! { &me.[<v_ $key>] } {
7+
Some(v) if !v.is_userdata() => Ok(v.clone()),
8+
Some(v @ UserData(ud)) if !matches!(ud.borrow::<()>(), Err(UserDataDestructed)) => {
9+
Ok(v.clone())
10+
}
11+
_ => {
12+
let v = ($value as fn(&Lua, &Self) -> Result<_>)(lua, me)?.into_lua(lua)?;
13+
paste::paste! { me.[<v_ $key>] = Some(v.clone()) };
14+
Ok(v)
1515
}
1616
})?
1717
});

yazi-binding/src/url.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,31 +62,31 @@ impl Url {
6262
impl FromLua for Url {
6363
fn from_lua(value: Value, _: &Lua) -> mlua::Result<Self> {
6464
Ok(match value {
65-
Value::UserData(ud) => Self::new(ud.take::<Self>()?.inner),
65+
Value::UserData(ud) => ud.take()?,
6666
_ => Err("Expected a Url".into_lua_err())?,
6767
})
6868
}
6969
}
7070

7171
impl UserData for Url {
7272
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
73-
cached_field!(fields, name, |lua: &Lua, me: &Self| {
73+
cached_field!(fields, name, |lua, me| {
7474
Some(me.name())
7575
.filter(|&s| !s.is_empty())
7676
.map(|s| lua.create_string(s.as_encoded_bytes()))
7777
.transpose()
7878
});
79-
cached_field!(fields, stem, |lua: &Lua, me: &Self| {
79+
cached_field!(fields, stem, |lua, me| {
8080
me.file_stem().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
8181
});
82-
cached_field!(fields, ext, |lua: &Lua, me: &Self| {
82+
cached_field!(fields, ext, |lua, me| {
8383
me.extension().map(|s| lua.create_string(s.as_encoded_bytes())).transpose()
8484
});
85-
cached_field!(fields, parent, |_, me: &Self| Ok(me.parent_url().map(Self::new)));
86-
cached_field!(fields, base, |_, me: &Self| {
85+
cached_field!(fields, parent, |_, me| Ok(me.parent_url().map(Self::new)));
86+
cached_field!(fields, base, |_, me| {
8787
Ok(if me.base().as_os_str().is_empty() { None } else { Some(Self::new(me.base())) })
8888
});
89-
cached_field!(fields, frag, |lua: &Lua, me: &Self| lua.create_string(me.frag()));
89+
cached_field!(fields, frag, |lua, me| lua.create_string(me.frag()));
9090

9191
fields.add_field_method_get("is_regular", |_, me| Ok(me.is_regular()));
9292
fields.add_field_method_get("is_search", |_, me| Ok(me.is_search()));

yazi-fm/src/lives/files.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl Files {
3232

3333
impl UserData for Files {
3434
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
35-
cached_field!(fields, filter, |_, me: &Self| me.filter().map(Filter::make).transpose());
35+
cached_field!(fields, filter, |_, me| me.filter().map(Filter::make).transpose());
3636
}
3737

3838
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {

yazi-fm/src/lives/folder.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ops::{Deref, Range};
22

3-
use mlua::{AnyUserData, Lua, UserData, UserDataFields, Value};
3+
use mlua::{AnyUserData, UserData, UserDataFields, Value};
44
use yazi_binding::{FolderStage, Url, cached_field};
55
use yazi_config::LAYOUT;
66

@@ -55,14 +55,14 @@ impl Folder {
5555

5656
impl UserData for Folder {
5757
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
58-
cached_field!(fields, cwd, |_, me: &Self| Ok(Url::new(me.url.to_owned())));
59-
cached_field!(fields, files, |_, me: &Self| Files::make(0..me.files.len(), me, &me.tab));
60-
cached_field!(fields, stage, |_: &Lua, me: &Self| Ok(FolderStage::new(me.stage)));
61-
cached_field!(fields, window, |_, me: &Self| Files::make(me.window.clone(), me, &me.tab));
58+
cached_field!(fields, cwd, |_, me| Ok(Url::new(me.url.to_owned())));
59+
cached_field!(fields, files, |_, me| Files::make(0..me.files.len(), me, &me.tab));
60+
cached_field!(fields, stage, |_, me| Ok(FolderStage::new(me.stage)));
61+
cached_field!(fields, window, |_, me| Files::make(me.window.clone(), me, &me.tab));
6262

6363
fields.add_field_method_get("offset", |_, me| Ok(me.offset));
6464
fields.add_field_method_get("cursor", |_, me| Ok(me.cursor));
65-
cached_field!(fields, hovered, |_, me: &Self| {
65+
cached_field!(fields, hovered, |_, me| {
6666
me.hovered().map(|_| File::make(me.cursor, me, &me.tab)).transpose()
6767
});
6868
}

yazi-fm/src/lives/preference.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ impl Preference {
2727

2828
impl UserData for Preference {
2929
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
30-
cached_field!(fields, sort_by, |_, me: &Self| Ok(me.sort_by.to_string()));
30+
cached_field!(fields, sort_by, |_, me| Ok(me.sort_by.to_string()));
3131
fields.add_field_method_get("sort_sensitive", |_, me| Ok(me.sort_sensitive));
3232
fields.add_field_method_get("sort_reverse", |_, me| Ok(me.sort_reverse));
3333
fields.add_field_method_get("sort_dir_first", |_, me| Ok(me.sort_dir_first));
3434
fields.add_field_method_get("sort_translit", |_, me| Ok(me.sort_translit));
3535

36-
cached_field!(fields, linemode, |_, me: &Self| Ok(me.linemode.to_string()));
36+
cached_field!(fields, linemode, |_, me| Ok(me.linemode.to_string()));
3737
fields.add_field_method_get("show_hidden", |_, me| Ok(me.show_hidden));
3838
}
3939
}

yazi-fm/src/lives/preview.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl Preview {
2828
impl UserData for Preview {
2929
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
3030
fields.add_field_method_get("skip", |_, me| Ok(me.skip));
31-
cached_field!(fields, folder, |_, me: &Self| {
31+
cached_field!(fields, folder, |_, me| {
3232
me.tab
3333
.hovered_folder()
3434
.map(|f| {

yazi-fm/src/lives/tab.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ops::Deref;
22

3-
use mlua::{AnyUserData, Lua, UserData, UserDataFields, UserDataMethods, Value};
3+
use mlua::{AnyUserData, UserData, UserDataFields, UserDataMethods, Value};
44
use yazi_binding::{UrlRef, cached_field};
55
use yazi_plugin::Id;
66

@@ -46,21 +46,21 @@ impl Tab {
4646
impl UserData for Tab {
4747
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
4848
fields.add_field_method_get("id", |_, me| Ok(Id(me.id)));
49-
cached_field!(fields, name, |lua: &Lua, me: &Self| {
49+
cached_field!(fields, name, |lua, me| {
5050
lua.create_string(me.current.url.name().as_encoded_bytes())
5151
});
5252

53-
cached_field!(fields, mode, |_, me: &Self| Mode::make(&me.mode));
54-
cached_field!(fields, pref, |_, me: &Self| Preference::make(&me.pref));
55-
cached_field!(fields, current, |_, me: &Self| Folder::make(None, &me.current, me));
56-
cached_field!(fields, parent, |_, me: &Self| {
53+
cached_field!(fields, mode, |_, me| Mode::make(&me.mode));
54+
cached_field!(fields, pref, |_, me| Preference::make(&me.pref));
55+
cached_field!(fields, current, |_, me| Folder::make(None, &me.current, me));
56+
cached_field!(fields, parent, |_, me| {
5757
me.parent.as_ref().map(|f| Folder::make(None, f, me)).transpose()
5858
});
5959

60-
cached_field!(fields, selected, |_, me: &Self| Selected::make(&me.selected));
60+
cached_field!(fields, selected, |_, me| Selected::make(&me.selected));
6161

62-
cached_field!(fields, preview, |_, me: &Self| Preview::make(me));
63-
cached_field!(fields, finder, |_, me: &Self| me.finder.as_ref().map(Finder::make).transpose());
62+
cached_field!(fields, preview, |_, me| Preview::make(me));
63+
cached_field!(fields, finder, |_, me| me.finder.as_ref().map(Finder::make).transpose());
6464
}
6565

6666
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {

yazi-fm/src/lives/tasks.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ops::Deref;
22

3-
use mlua::{AnyUserData, Lua, LuaSerdeExt, UserData, UserDataFields, Value};
3+
use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value};
44
use yazi_binding::cached_field;
55

66
use super::{Lives, PtrCell};
@@ -26,6 +26,6 @@ impl Tasks {
2626

2727
impl UserData for Tasks {
2828
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
29-
cached_field!(fields, progress, |lua: &Lua, me: &Self| lua.to_value(&me.progress));
29+
cached_field!(fields, progress, |lua, me| lua.to_value(&me.progress));
3030
}
3131
}

yazi-plugin/src/bindings/icon.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ops::Deref;
22

3-
use mlua::{Lua, UserData, UserDataFields, Value};
3+
use mlua::{UserData, UserDataFields, Value};
44
use yazi_binding::cached_field;
55

66
use crate::elements::Style;
@@ -26,7 +26,7 @@ impl From<&'static yazi_shared::theme::Icon> for Icon {
2626

2727
impl UserData for Icon {
2828
fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
29-
cached_field!(fields, text, |lua: &Lua, me: &Self| lua.create_string(&me.text));
30-
cached_field!(fields, style, |_, me: &Self| Ok(Style::from(me.style)));
29+
cached_field!(fields, text, |lua, me| lua.create_string(&me.text));
30+
cached_field!(fields, style, |_, me| Ok(Style::from(me.style)));
3131
}
3232
}

yazi-plugin/src/config/plugin.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl Fetcher {
5858

5959
impl UserData for Fetcher {
6060
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
61-
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
61+
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
6262
}
6363
}
6464

@@ -75,7 +75,7 @@ impl Spotter {
7575

7676
impl UserData for Spotter {
7777
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
78-
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
78+
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
7979
}
8080
}
8181

@@ -92,7 +92,7 @@ impl Preloader {
9292

9393
impl UserData for Preloader {
9494
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
95-
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
95+
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
9696
}
9797
}
9898

@@ -109,6 +109,6 @@ impl Previewer {
109109

110110
impl UserData for Previewer {
111111
fn add_fields<F: mlua::UserDataFields<Self>>(fields: &mut F) {
112-
cached_field!(fields, cmd, |lua: &Lua, me: &Self| lua.create_string(&me.inner.run.name));
112+
cached_field!(fields, cmd, |lua, me| lua.create_string(&me.inner.run.name));
113113
}
114114
}

0 commit comments

Comments
 (0)