From c9c85130e12e5d6236b6b353077dee379927ba0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Fri, 11 Jul 2025 08:55:56 +0800 Subject: [PATCH] refactor: pull DDS events out into a macro (#2977) --- Cargo.lock | 29 +-- Cargo.toml | 4 +- yazi-boot/Cargo.toml | 4 +- yazi-cli/Cargo.toml | 4 +- yazi-core/src/mgr/commands/bulk_rename.rs | 4 +- yazi-core/src/mgr/commands/rename.rs | 2 +- yazi-core/src/mgr/tabs.rs | 2 +- yazi-core/src/mgr/watcher.rs | 2 +- yazi-core/src/mgr/yanked.rs | 2 +- yazi-core/src/tab/commands/cd.rs | 2 +- yazi-core/src/tab/commands/hover.rs | 2 +- yazi-core/src/tab/folder.rs | 2 +- yazi-dds/Cargo.toml | 1 + yazi-dds/src/body/bulk.rs | 24 ++- yazi-dds/src/body/bye.rs | 1 - yazi-dds/src/body/cd.rs | 17 +- yazi-dds/src/body/custom.rs | 2 - yazi-dds/src/body/delete.rs | 2 - yazi-dds/src/body/hey.rs | 2 +- yazi-dds/src/body/hi.rs | 17 +- yazi-dds/src/body/hover.rs | 17 +- yazi-dds/src/body/load.rs | 10 +- yazi-dds/src/body/mount.rs | 3 +- yazi-dds/src/body/move.rs | 2 - yazi-dds/src/body/rename.rs | 12 +- yazi-dds/src/body/tab.rs | 3 +- yazi-dds/src/body/trash.rs | 2 - yazi-dds/src/body/yank.rs | 6 +- yazi-dds/src/client.rs | 8 +- yazi-dds/src/pubsub.rs | 215 ++++++++-------------- yazi-dds/src/pump.rs | 6 +- yazi-shared/src/url/url.rs | 12 ++ 32 files changed, 168 insertions(+), 253 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 63673596..8286087d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -388,9 +388,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" +checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" dependencies = [ "clap_builder", "clap_derive", @@ -398,9 +398,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" +checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" dependencies = [ "anstream", "anstyle", @@ -410,9 +410,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.54" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677" +checksum = "a5abde44486daf70c5be8b8f8f1b66c49f86236edf6fa2abadb4d961c4c6229a" dependencies = [ "clap", ] @@ -429,9 +429,9 @@ dependencies = [ [[package]] name = "clap_complete_nushell" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb8335b398d197fb3176efe9400c6c053a41733c26794316c73423d212b2f3d" +checksum = "0a0c951694691e65bf9d421d597d68416c22de9632e884c28412cb8cd8b73dce" dependencies = [ "clap", "clap_complete", @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.40" +version = "4.5.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" +checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" dependencies = [ "heck", "proc-macro2", @@ -2739,9 +2739,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f271e09bde39ab52250160a67e88577e0559ad77e9085de6e9051a2c4353f8f8" +checksum = "0207d6ed1852c2a124c1fbec61621acb8330d2bf969a5d0643131e9affd985a5" dependencies = [ "indexmap", "serde", @@ -3544,7 +3544,7 @@ dependencies = [ "serde", "serde_json", "tokio", - "toml 0.9.0", + "toml 0.9.1", "twox-hash", "vergen-gitcl", "yazi-boot", @@ -3575,7 +3575,7 @@ dependencies = [ "ratatui", "regex", "serde", - "toml 0.9.0", + "toml 0.9.1", "tracing", "yazi-codegen", "yazi-fs", @@ -3627,6 +3627,7 @@ dependencies = [ "mlua", "ordered-float 5.0.0", "parking_lot", + "paste", "serde", "serde_json", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 44882855..8d54c226 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ ansi-to-tui = "7.0.0" anyhow = "1.0.98" base64 = "0.22.1" bitflags = "2.9.1" -clap = { version = "4.5.40", features = [ "derive" ] } +clap = { version = "4.5.41", features = [ "derive" ] } core-foundation-sys = "0.8.7" crossterm = { version = "0.29.0", features = [ "event-stream" ] } dirs = "6.0.0" @@ -48,7 +48,7 @@ syntect = { version = "5.2.0", default-features = false, features = tokio = { version = "1.46.1", features = [ "full" ] } tokio-stream = "0.1.17" tokio-util = "0.7.15" -toml = { version = "0.9.0" } +toml = { version = "0.9.1" } tracing = { version = "0.1.41", features = [ "max_level_debug", "release_max_level_debug" ] } twox-hash = { version = "2.1.1", default-features = false, features = [ "std", "random", "xxhash3_128" ] } unicode-width = { version = "0.2.0", default-features = false } diff --git a/yazi-boot/Cargo.toml b/yazi-boot/Cargo.toml index e30aa7c0..48c885a0 100644 --- a/yazi-boot/Cargo.toml +++ b/yazi-boot/Cargo.toml @@ -25,7 +25,7 @@ yazi-shared = { path = "../yazi-shared", version = "25.6.11" } # External dependencies clap = { workspace = true } -clap_complete = "4.5.54" +clap_complete = "4.5.55" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.7" +clap_complete_nushell = "4.5.8" vergen-gitcl = { version = "1.0.8", features = [ "build", "rustc" ] } diff --git a/yazi-cli/Cargo.toml b/yazi-cli/Cargo.toml index 5743ffa8..cafe1aae 100644 --- a/yazi-cli/Cargo.toml +++ b/yazi-cli/Cargo.toml @@ -41,9 +41,9 @@ yazi-shared = { path = "../yazi-shared", version = "25.6.11" } # External build dependencies anyhow = { workspace = true } clap = { workspace = true } -clap_complete = "4.5.54" +clap_complete = "4.5.55" clap_complete_fig = "4.5.2" -clap_complete_nushell = "4.5.7" +clap_complete_nushell = "4.5.8" serde_json = { workspace = true } vergen-gitcl = { version = "1.0.8", features = [ "build" ] } diff --git a/yazi-core/src/mgr/commands/bulk_rename.rs b/yazi-core/src/mgr/commands/bulk_rename.rs index 6e0e8044..11048137 100644 --- a/yazi-core/src/mgr/commands/bulk_rename.rs +++ b/yazi-core/src/mgr/commands/bulk_rename.rs @@ -103,8 +103,8 @@ impl Mgr { } if !succeeded.is_empty() { - let map = succeeded.iter().map(|(o, n)| (o, &n.url)).collect(); - err!(Pubsub::pub_from_bulk(map)); + let it = succeeded.iter().map(|(o, n)| (o, &n.url)); + err!(Pubsub::pub_after_bulk(it)); FilesOp::rename(succeeded); } drop(permit); diff --git a/yazi-core/src/mgr/commands/rename.rs b/yazi-core/src/mgr/commands/rename.rs index 4f3701e1..a753b1a2 100644 --- a/yazi-core/src/mgr/commands/rename.rs +++ b/yazi-core/src/mgr/commands/rename.rs @@ -74,7 +74,7 @@ impl Mgr { } TabProxy::reveal(&new); - err!(Pubsub::pub_from_rename(tab, &old, &new)); + err!(Pubsub::pub_after_rename(tab, &old, &new)); Ok(()) } diff --git a/yazi-core/src/mgr/tabs.rs b/yazi-core/src/mgr/tabs.rs index 86827dbd..f26294b9 100644 --- a/yazi-core/src/mgr/tabs.rs +++ b/yazi-core/src/mgr/tabs.rs @@ -40,7 +40,7 @@ impl Tabs { self.cursor = idx; MgrProxy::refresh(); MgrProxy::peek(true); - err!(Pubsub::pub_from_tab(self.active().id)); + err!(Pubsub::pub_after_tab(self.active().id)); } } diff --git a/yazi-core/src/mgr/watcher.rs b/yazi-core/src/mgr/watcher.rs index 0ef4eaee..69d405e5 100644 --- a/yazi-core/src/mgr/watcher.rs +++ b/yazi-core/src/mgr/watcher.rs @@ -44,7 +44,7 @@ impl Watcher { #[cfg(any(target_os = "linux", target_os = "macos"))] yazi_fs::mounts::Partitions::monitor(yazi_fs::mounts::PARTITIONS.clone(), || { - yazi_macro::err!(yazi_dds::Pubsub::pub_from_mount()) + yazi_macro::err!(yazi_dds::Pubsub::pub_after_mount()) }); tokio::spawn(Self::fan_out(out_rx)); diff --git a/yazi-core/src/mgr/yanked.rs b/yazi-core/src/mgr/yanked.rs index 0d16bb4c..11ba3235 100644 --- a/yazi-core/src/mgr/yanked.rs +++ b/yazi-core/src/mgr/yanked.rs @@ -66,7 +66,7 @@ impl Yanked { } self.version = self.revision; - err!(Pubsub::pub_from_yank(self.cut, &self.urls)); + err!(Pubsub::pub_after_yank(self.cut, &self.urls)); true } } diff --git a/yazi-core/src/tab/commands/cd.rs b/yazi-core/src/tab/commands/cd.rs index 8961ee9c..8f8f659e 100644 --- a/yazi-core/src/tab/commands/cd.rs +++ b/yazi-core/src/tab/commands/cd.rs @@ -54,7 +54,7 @@ impl Tab { self.parent = Some(self.history.remove_or(&parent)); } - err!(Pubsub::pub_from_cd(self.id, self.cwd())); + err!(Pubsub::pub_after_cd(self.id, self.cwd())); self.hover(None); MgrProxy::refresh(); diff --git a/yazi-core/src/tab/commands/hover.rs b/yazi-core/src/tab/commands/hover.rs index 0091767a..179df338 100644 --- a/yazi-core/src/tab/commands/hover.rs +++ b/yazi-core/src/tab/commands/hover.rs @@ -15,7 +15,7 @@ impl Tab { } // Publish through DDS - err!(Pubsub::pub_from_hover(self.id, self.hovered().map(|h| &h.url))); + err!(Pubsub::pub_after_hover(self.id, self.hovered().map(|h| &h.url))); } fn hover_do(&mut self, url: Url) { diff --git a/yazi-core/src/tab/folder.rs b/yazi-core/src/tab/folder.rs index a228d7be..c1e28091 100644 --- a/yazi-core/src/tab/folder.rs +++ b/yazi-core/src/tab/folder.rs @@ -90,7 +90,7 @@ impl Folder { if !self.update(op) { return false; } else if self.stage != old { - err!(Pubsub::pub_from_load(tab, &self.url, self.stage)); + err!(Pubsub::pub_after_load(tab, &self.url, self.stage)); } true } diff --git a/yazi-dds/Cargo.toml b/yazi-dds/Cargo.toml index 7be073ce..c62fb67d 100644 --- a/yazi-dds/Cargo.toml +++ b/yazi-dds/Cargo.toml @@ -24,6 +24,7 @@ anyhow = { workspace = true } mlua = { workspace = true } ordered-float = { workspace = true } parking_lot = { workspace = true } +paste = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true } diff --git a/yazi-dds/src/body/bulk.rs b/yazi-dds/src/body/bulk.rs index 11f9828f..d15972a6 100644 --- a/yazi-dds/src/body/bulk.rs +++ b/yazi-dds/src/body/bulk.rs @@ -12,23 +12,21 @@ pub struct BodyBulk<'a> { } impl<'a> BodyBulk<'a> { - #[inline] - pub fn borrowed(changes: &HashMap<&'a Url, &'a Url>) -> Body<'a> { - let iter = changes.iter().map(|(&from, &to)| (Cow::Borrowed(from), Cow::Borrowed(to))); - - Self { changes: iter.collect() }.into() + pub fn borrowed(changes: I) -> Body<'a> + where + I: Iterator, + { + Self { changes: changes.map(|(from, to)| (from.into(), to.into())).collect() }.into() } } impl BodyBulk<'static> { - #[inline] - pub fn owned(changes: &HashMap<&Url, &Url>) -> Body<'static> { - let changes = changes - .iter() - .map(|(&from, &to)| (Cow::Owned(from.clone()), Cow::Owned(to.clone()))) - .collect(); - - Self { changes }.into() + pub fn owned<'a, I>(changes: I) -> Body<'static> + where + I: Iterator, + { + Self { changes: changes.map(|(from, to)| (from.clone().into(), to.clone().into())).collect() } + .into() } } diff --git a/yazi-dds/src/body/bye.rs b/yazi-dds/src/body/bye.rs index ef047add..21ec6e93 100644 --- a/yazi-dds/src/body/bye.rs +++ b/yazi-dds/src/body/bye.rs @@ -7,7 +7,6 @@ use super::Body; pub struct BodyBye; impl BodyBye { - #[inline] pub fn owned() -> Body<'static> { Self.into() } } diff --git a/yazi-dds/src/body/cd.rs b/yazi-dds/src/body/cd.rs index e14f2cba..f897bcdf 100644 --- a/yazi-dds/src/body/cd.rs +++ b/yazi-dds/src/body/cd.rs @@ -15,15 +15,13 @@ pub struct BodyCd<'a> { } impl<'a> BodyCd<'a> { - #[inline] pub fn borrowed(tab: Id, url: &'a Url) -> Body<'a> { - Self { tab, url: Cow::Borrowed(url), dummy: false }.into() + Self { tab, url: url.into(), dummy: false }.into() } } impl BodyCd<'static> { - #[inline] - pub fn dummy(tab: Id) -> Body<'static> { + pub fn owned(tab: Id, _: &Url) -> Body<'static> { Self { tab, url: Default::default(), dummy: true }.into() } } @@ -34,14 +32,11 @@ impl<'a> From> for Body<'a> { impl IntoLua for BodyCd<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { - if let Some(Cow::Owned(url)) = Some(self.url).filter(|_| !self.dummy) { - lua.create_table_from([ + lua + .create_table_from([ ("tab", self.tab.get().into_lua(lua)?), - ("url", yazi_binding::Url::new(url).into_lua(lua)?), + ("url", Some(self.url).filter(|_| !self.dummy).map(yazi_binding::Url::new).into_lua(lua)?), ])? - } else { - lua.create_table_from([("tab", self.tab.get())])? - } - .into_lua(lua) + .into_lua(lua) } } diff --git a/yazi-dds/src/body/custom.rs b/yazi-dds/src/body/custom.rs index 1d6b131c..ec19e2be 100644 --- a/yazi-dds/src/body/custom.rs +++ b/yazi-dds/src/body/custom.rs @@ -12,12 +12,10 @@ pub struct BodyCustom { } impl BodyCustom { - #[inline] pub fn from_str(kind: &str, data: &str) -> anyhow::Result> { Ok(Self { kind: kind.to_owned(), data: serde_json::from_str(data)? }.into()) } - #[inline] pub fn from_lua(kind: &str, data: Value) -> mlua::Result> { Ok(Self { kind: kind.to_owned(), data: Sendable::value_to_data(data)? }.into()) } diff --git a/yazi-dds/src/body/delete.rs b/yazi-dds/src/body/delete.rs index 4259b083..a88ee19f 100644 --- a/yazi-dds/src/body/delete.rs +++ b/yazi-dds/src/body/delete.rs @@ -12,12 +12,10 @@ pub struct BodyDelete<'a> { } impl<'a> BodyDelete<'a> { - #[inline] pub fn borrowed(urls: &'a Vec) -> Body<'a> { Self { urls: Cow::Borrowed(urls) }.into() } } impl BodyDelete<'static> { - #[inline] pub fn owned(urls: Vec) -> Body<'static> { Self { urls: Cow::Owned(urls) }.into() } } diff --git a/yazi-dds/src/body/hey.rs b/yazi-dds/src/body/hey.rs index f56c888f..1c80aadc 100644 --- a/yazi-dds/src/body/hey.rs +++ b/yazi-dds/src/body/hey.rs @@ -7,6 +7,7 @@ use yazi_shared::{Id, SStr}; use super::{Body, BodyHi}; use crate::Peer; +/// Server handshake #[derive(Debug, Serialize, Deserialize)] pub struct BodyHey { pub peers: HashMap, @@ -14,7 +15,6 @@ pub struct BodyHey { } impl BodyHey { - #[inline] pub fn owned(peers: HashMap) -> Body<'static> { Self { peers, version: BodyHi::version().into() }.into() } diff --git a/yazi-dds/src/body/hi.rs b/yazi-dds/src/body/hi.rs index a10a46d9..ced272ed 100644 --- a/yazi-dds/src/body/hi.rs +++ b/yazi-dds/src/body/hi.rs @@ -6,25 +6,22 @@ use yazi_shared::SStr; use super::Body; -/// The client handshake +/// Client handshake #[derive(Debug, Serialize, Deserialize)] pub struct BodyHi<'a> { - /// Specifies the kinds of events that the client can handle + /// Kinds of events the client can handle pub abilities: HashSet>, pub version: SStr, } impl<'a> BodyHi<'a> { - #[inline] - pub fn borrowed(abilities: HashSet<&'a str>) -> Body<'a> { - Self { - abilities: abilities.into_iter().map(Cow::Borrowed).collect(), - version: Self::version().into(), - } - .into() + pub fn borrowed(abilities: I) -> Body<'a> + where + I: Iterator, + { + Self { abilities: abilities.map(Into::into).collect(), version: Self::version().into() }.into() } - #[inline] pub fn version() -> &'static str { concat!(env!("CARGO_PKG_VERSION"), " ", env!("VERGEN_GIT_SHA")) } diff --git a/yazi-dds/src/body/hover.rs b/yazi-dds/src/body/hover.rs index c2541775..6b479f79 100644 --- a/yazi-dds/src/body/hover.rs +++ b/yazi-dds/src/body/hover.rs @@ -13,15 +13,13 @@ pub struct BodyHover<'a> { } impl<'a> BodyHover<'a> { - #[inline] pub fn borrowed(tab: Id, url: Option<&'a Url>) -> Body<'a> { - Self { tab, url: url.map(Cow::Borrowed) }.into() + Self { tab, url: url.map(Into::into) }.into() } } impl BodyHover<'static> { - #[inline] - pub fn dummy(tab: Id) -> Body<'static> { Self { tab, url: None }.into() } + pub fn owned(tab: Id, _: Option<&Url>) -> Body<'static> { Self { tab, url: None }.into() } } impl<'a> From> for Body<'a> { @@ -30,14 +28,11 @@ impl<'a> From> for Body<'a> { impl IntoLua for BodyHover<'static> { fn into_lua(self, lua: &Lua) -> mlua::Result { - if let Some(Cow::Owned(url)) = self.url { - lua.create_table_from([ + lua + .create_table_from([ ("tab", self.tab.get().into_lua(lua)?), - ("url", yazi_binding::Url::new(url).into_lua(lua)?), + ("url", self.url.map(yazi_binding::Url::new).into_lua(lua)?), ])? - } else { - lua.create_table_from([("tab", self.tab.get())])? - } - .into_lua(lua) + .into_lua(lua) } } diff --git a/yazi-dds/src/body/load.rs b/yazi-dds/src/body/load.rs index 203cc1c1..85e89dce 100644 --- a/yazi-dds/src/body/load.rs +++ b/yazi-dds/src/body/load.rs @@ -15,16 +15,14 @@ pub struct BodyLoad<'a> { } impl<'a> BodyLoad<'a> { - #[inline] pub fn borrowed(tab: Id, url: &'a Url, stage: FolderStage) -> Body<'a> { - Self { tab, url: Cow::Borrowed(url), stage }.into() + Self { tab, url: url.into(), stage }.into() } } impl BodyLoad<'static> { - #[inline] - pub fn dummy(tab: Id, url: &Url, stage: FolderStage) -> Body<'static> { - Self { tab, url: Cow::Owned(url.clone()), stage }.into() + pub fn owned(tab: Id, url: &Url, stage: FolderStage) -> Body<'static> { + Self { tab, url: url.clone().into(), stage }.into() } } @@ -37,7 +35,7 @@ impl IntoLua for BodyLoad<'static> { lua .create_table_from([ ("tab", self.tab.get().into_lua(lua)?), - ("url", yazi_binding::Url::new(self.url.into_owned()).into_lua(lua)?), + ("url", yazi_binding::Url::new(self.url).into_lua(lua)?), ("stage", yazi_binding::FolderStage::new(self.stage).into_lua(lua)?), ])? .into_lua(lua) diff --git a/yazi-dds/src/body/mount.rs b/yazi-dds/src/body/mount.rs index 50c44b6e..5a7af57f 100644 --- a/yazi-dds/src/body/mount.rs +++ b/yazi-dds/src/body/mount.rs @@ -7,8 +7,9 @@ use super::Body; pub struct BodyMount; impl BodyMount { - #[inline] pub fn owned() -> Body<'static> { Self.into() } + + pub fn borrowed() -> Body<'static> { Self::owned() } } impl From for Body<'_> { diff --git a/yazi-dds/src/body/move.rs b/yazi-dds/src/body/move.rs index 9323c40b..ad1ea44b 100644 --- a/yazi-dds/src/body/move.rs +++ b/yazi-dds/src/body/move.rs @@ -12,14 +12,12 @@ pub struct BodyMove<'a> { } impl<'a> BodyMove<'a> { - #[inline] pub fn borrowed(items: &'a Vec) -> Body<'a> { Self { items: Cow::Borrowed(items) }.into() } } impl BodyMove<'static> { - #[inline] pub fn owned(items: Vec) -> Body<'static> { Self { items: Cow::Owned(items) }.into() } diff --git a/yazi-dds/src/body/rename.rs b/yazi-dds/src/body/rename.rs index d793b56d..1f6ce75a 100644 --- a/yazi-dds/src/body/rename.rs +++ b/yazi-dds/src/body/rename.rs @@ -14,16 +14,14 @@ pub struct BodyRename<'a> { } impl<'a> BodyRename<'a> { - #[inline] pub fn borrowed(tab: Id, from: &'a Url, to: &'a Url) -> Body<'a> { - Self { tab, from: Cow::Borrowed(from), to: Cow::Borrowed(to) }.into() + Self { tab, from: from.into(), to: to.into() }.into() } } impl BodyRename<'static> { - #[inline] - pub fn dummy(tab: Id, from: &Url, to: &Url) -> Body<'static> { - Self { tab, from: Cow::Owned(from.clone()), to: Cow::Owned(to.clone()) }.into() + pub fn owned(tab: Id, from: &Url, to: &Url) -> Body<'static> { + Self { tab, from: from.clone().into(), to: to.clone().into() }.into() } } @@ -36,8 +34,8 @@ impl IntoLua for BodyRename<'static> { lua .create_table_from([ ("tab", self.tab.get().into_lua(lua)?), - ("from", yazi_binding::Url::new(self.from.into_owned()).into_lua(lua)?), - ("to", yazi_binding::Url::new(self.to.into_owned()).into_lua(lua)?), + ("from", yazi_binding::Url::new(self.from).into_lua(lua)?), + ("to", yazi_binding::Url::new(self.to).into_lua(lua)?), ])? .into_lua(lua) } diff --git a/yazi-dds/src/body/tab.rs b/yazi-dds/src/body/tab.rs index fcc95849..84533963 100644 --- a/yazi-dds/src/body/tab.rs +++ b/yazi-dds/src/body/tab.rs @@ -10,8 +10,9 @@ pub struct BodyTab { } impl BodyTab { - #[inline] pub fn owned(id: Id) -> Body<'static> { Self { id }.into() } + + pub fn borrowed(id: Id) -> Body<'static> { Self::owned(id) } } impl From for Body<'_> { diff --git a/yazi-dds/src/body/trash.rs b/yazi-dds/src/body/trash.rs index 5e429c26..92991661 100644 --- a/yazi-dds/src/body/trash.rs +++ b/yazi-dds/src/body/trash.rs @@ -12,12 +12,10 @@ pub struct BodyTrash<'a> { } impl<'a> BodyTrash<'a> { - #[inline] pub fn borrowed(urls: &'a Vec) -> Body<'a> { Self { urls: Cow::Borrowed(urls) }.into() } } impl BodyTrash<'static> { - #[inline] pub fn owned(urls: Vec) -> Body<'static> { Self { urls: Cow::Owned(urls) }.into() } } diff --git a/yazi-dds/src/body/yank.rs b/yazi-dds/src/body/yank.rs index 111d311f..fb6885ad 100644 --- a/yazi-dds/src/body/yank.rs +++ b/yazi-dds/src/body/yank.rs @@ -15,16 +15,14 @@ pub struct BodyYank<'a> { } impl<'a> BodyYank<'a> { - #[inline] pub fn borrowed(cut: bool, urls: &'a HashSet) -> Body<'a> { Self { cut, urls: Cow::Borrowed(urls), dummy: false }.into() } } impl BodyYank<'static> { - #[inline] - pub fn dummy() -> Body<'static> { - Self { cut: false, urls: Default::default(), dummy: true }.into() + pub fn owned(cut: bool, _: &HashSet) -> Body<'static> { + Self { cut, urls: Default::default(), dummy: true }.into() } } diff --git a/yazi-dds/src/client.rs b/yazi-dds/src/client.rs index 4b7234ff..6a5aa345 100644 --- a/yazi-dds/src/client.rs +++ b/yazi-dds/src/client.rs @@ -1,4 +1,4 @@ -use std::{collections::{HashMap, HashSet}, mem, str::FromStr}; +use std::{collections::{HashMap, HashSet}, iter, mem, str::FromStr}; use anyhow::{Context, Result, bail}; use parking_lot::RwLock; @@ -71,7 +71,7 @@ impl Client { let payload = try_format!( "{}\n{kind},{receiver},{ID},{body}\n{}\n", - Payload::new(BodyHi::borrowed(Default::default())), + Payload::new(BodyHi::borrowed(iter::empty())), Payload::new(BodyBye::owned()) )?; @@ -129,7 +129,7 @@ impl Client { pub async fn draw(kinds: HashSet<&str>) -> Result<()> { async fn make(kinds: &HashSet<&str>) -> Result { let (lines, mut writer) = Stream::connect().await?; - let hi = Payload::new(BodyHi::borrowed(kinds.clone())); + let hi = Payload::new(BodyHi::borrowed(kinds.iter().copied())); writer.write_all(try_format!("{hi}\n")?.as_bytes()).await?; writer.flush().await?; Ok(lines) @@ -167,7 +167,7 @@ impl Client { let mut first = true; loop { if let Ok(conn) = Stream::connect().await { - Pubsub::pub_from_hi(); + Pubsub::pub_inner_hi(); return conn; } diff --git a/yazi-dds/src/pubsub.rs b/yazi-dds/src/pubsub.rs index 40caa0ac..e2db0362 100644 --- a/yazi-dds/src/pubsub.rs +++ b/yazi-dds/src/pubsub.rs @@ -7,7 +7,7 @@ use yazi_boot::BOOT; use yazi_fs::FolderStage; use yazi_shared::{Id, RoCell, url::Url}; -use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyCd, BodyDelete, BodyHi, BodyHover, BodyLoad, BodyMount, BodyMove, BodyMoveItem, BodyRename, BodyTab, BodyTrash, BodyYank}}; +use crate::{Client, ID, PEERS, body::{Body, BodyBulk, BodyHi, BodyMoveItem}}; pub static LOCAL: RoCell>>> = RoCell::new(); @@ -48,19 +48,53 @@ macro_rules! unsub { }; } +macro_rules! pub_after { + (&impl $name:ident ($($param:ident: $param_ty:ty),*), ($($borrowed:expr),*), ($($owned:expr),*), $static:literal) => { + paste::paste! { + pub fn []($($param: $param_ty),*) -> Result<()> { + use crate::body::[] as B; + + let n = if $static { concat!("@", stringify!($name)) } else { stringify!($name) }; + if BOOT.local_events.contains(n) { + B::borrowed($($borrowed),*).with_receiver(*ID).flush()?; + } + if ($static && Self::any_remote_own(n)) || (!$static && PEERS.read().values().any(|p| p.able(n))) { + Client::push(B::borrowed($($borrowed),*))?; + } + if LOCAL.read().contains_key(n) { + Self::r#pub(B::owned($($owned),*))?; + } + Ok(()) + } + } + }; + ($name:ident ($($param:ident: $param_ty:ty),*), ($($borrowed:expr),*)) => { + pub_after!(&impl $name($($param: $param_ty),*), ($($borrowed),*), ($($borrowed),*), false); + }; + ($name:ident ($($param:ident: $param_ty:ty),*), ($($borrowed:expr),*), ($($owned:expr),*)) => { + pub_after!(&impl $name($($param: $param_ty),*), ($($borrowed),*), ($($owned),*), false); + }; + (@ $name:ident ($($param:ident: $param_ty:ty),*), ($($borrowed:expr),*)) => { + pub_after!(&impl $name($($param: $param_ty),*), ($($borrowed),*), ($($borrowed),*), true); + }; + (@ $name:ident ($($param:ident: $param_ty:ty),*), ($($borrowed:expr),*), ($($owned:expr),*)) => { + pub_after!(&impl $name($($param: $param_ty),*), ($($borrowed),*), ($($owned),*), true); + }; +} + pub struct Pubsub; impl Pubsub { pub fn sub(plugin: &str, kind: &str, f: Function) -> bool { sub!(LOCAL)(plugin, kind, f) } pub fn sub_remote(plugin: &str, kind: &str, f: Function) -> bool { - sub!(REMOTE)(plugin, kind, f) && Self::pub_from_hi() + sub!(REMOTE)(plugin, kind, f) && Self::pub_inner_hi() } pub fn unsub(plugin: &str, kind: &str) -> bool { unsub!(LOCAL)(plugin, kind) } pub fn unsub_remote(plugin: &str, kind: &str) -> bool { - unsub!(REMOTE)(plugin, kind) && Self::pub_from_hi() + unsub!(REMOTE)(plugin, kind) && Self::pub_inner_hi() } pub fn r#pub(body: Body<'static>) -> Result<()> { body.with_receiver(*ID).emit() } @@ -79,162 +113,57 @@ impl Pubsub { Ok(()) } - pub fn pub_from_hi() -> bool { + pub fn pub_inner_hi() -> bool { let abilities = REMOTE.read().keys().cloned().collect(); - let abilities = BOOT.remote_events.union(&abilities).map(|s| s.as_str()).collect(); + let abilities = BOOT.remote_events.union(&abilities).map(AsRef::as_ref); // FIXME: handle error Client::push(BodyHi::borrowed(abilities)).ok(); true } - pub fn pub_from_tab(idx: Id) -> Result<()> { - if LOCAL.read().contains_key("tab") { - Self::r#pub(BodyTab::owned(idx))?; - } - if PEERS.read().values().any(|p| p.able("tab")) { - Client::push(BodyTab::owned(idx))?; - } - if BOOT.local_events.contains("tab") { - BodyTab::owned(idx).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub fn pub_from_cd(tab: Id, url: &Url) -> Result<()> { - if LOCAL.read().contains_key("cd") { - Self::r#pub(BodyCd::dummy(tab))?; - } - if PEERS.read().values().any(|p| p.able("cd")) { - Client::push(BodyCd::borrowed(tab, url))?; - } - if BOOT.local_events.contains("cd") { - BodyCd::borrowed(tab, url).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub fn pub_from_load(tab: Id, url: &Url, stage: FolderStage) -> Result<()> { - if LOCAL.read().contains_key("load") { - Self::r#pub(BodyLoad::dummy(tab, url, stage))?; - } - if PEERS.read().values().any(|p| p.able("load")) { - Client::push(BodyLoad::borrowed(tab, url, stage))?; - } - if BOOT.local_events.contains("load") { - BodyLoad::borrowed(tab, url, stage).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub fn pub_from_hover(tab: Id, url: Option<&Url>) -> Result<()> { - if LOCAL.read().contains_key("hover") { - Self::r#pub(BodyHover::dummy(tab))?; - } - if PEERS.read().values().any(|p| p.able("hover")) { - Client::push(BodyHover::borrowed(tab, url))?; - } - if BOOT.local_events.contains("hover") { - BodyHover::borrowed(tab, url).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub fn pub_from_rename(tab: Id, from: &Url, to: &Url) -> Result<()> { - if LOCAL.read().contains_key("rename") { - Self::r#pub(BodyRename::dummy(tab, from, to))?; - } - if PEERS.read().values().any(|p| p.able("rename")) { - Client::push(BodyRename::borrowed(tab, from, to))?; - } - if BOOT.local_events.contains("rename") { - BodyRename::borrowed(tab, from, to).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub fn pub_from_bulk(changes: HashMap<&Url, &Url>) -> Result<()> { - if LOCAL.read().contains_key("bulk") { - Self::r#pub(BodyBulk::owned(&changes))?; + pub fn pub_after_bulk<'a, I>(changes: I) -> Result<()> + where + I: Iterator + Clone, + { + if BOOT.local_events.contains("bulk") { + BodyBulk::borrowed(changes.clone()).with_receiver(*ID).flush()?; } if PEERS.read().values().any(|p| p.able("bulk")) { - Client::push(BodyBulk::borrowed(&changes))?; + Client::push(BodyBulk::borrowed(changes.clone()))?; } - if BOOT.local_events.contains("bulk") { - BodyBulk::borrowed(&changes).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub fn pub_from_yank(cut: bool, urls: &HashSet) -> Result<()> { - if LOCAL.read().contains_key("@yank") { - Self::r#pub(BodyYank::dummy())?; - } - if Self::any_remote_own("@yank") { - Client::push(BodyYank::borrowed(cut, urls))?; - } - if BOOT.local_events.contains("@yank") { - BodyYank::borrowed(cut, urls).with_receiver(*ID).flush()?; - } - Ok(()) - } - - pub(super) fn pub_from_move(items: Vec) -> Result<()> { - if PEERS.read().values().any(|p| p.able("move")) { - Client::push(BodyMove::borrowed(&items))?; - } - if BOOT.local_events.contains("move") { - BodyMove::borrowed(&items).with_receiver(*ID).flush()?; - } - if LOCAL.read().contains_key("move") { - Self::r#pub(BodyMove::owned(items))?; - } - Ok(()) - } - - pub(super) fn pub_from_trash(urls: Vec) -> Result<()> { - if PEERS.read().values().any(|p| p.able("trash")) { - Client::push(BodyTrash::borrowed(&urls))?; - } - if BOOT.local_events.contains("trash") { - BodyTrash::borrowed(&urls).with_receiver(*ID).flush()?; - } - if LOCAL.read().contains_key("trash") { - Self::r#pub(BodyTrash::owned(urls))?; - } - Ok(()) - } - - pub(super) fn pub_from_delete(urls: Vec) -> Result<()> { - if PEERS.read().values().any(|p| p.able("delete")) { - Client::push(BodyDelete::borrowed(&urls))?; - } - if BOOT.local_events.contains("delete") { - BodyDelete::borrowed(&urls).with_receiver(*ID).flush()?; - } - if LOCAL.read().contains_key("delete") { - Self::r#pub(BodyDelete::owned(urls))?; - } - Ok(()) - } - - pub fn pub_from_mount() -> Result<()> { - if LOCAL.read().contains_key("mount") { - Self::r#pub(BodyMount::owned())?; - } - if PEERS.read().values().any(|p| p.able("mount")) { - Client::push(BodyMount::owned())?; - } - if BOOT.local_events.contains("mount") { - BodyMount::owned().with_receiver(*ID).flush()?; + if LOCAL.read().contains_key("bulk") { + Self::r#pub(BodyBulk::owned(changes))?; } Ok(()) } #[inline] fn any_remote_own(kind: &str) -> bool { - REMOTE.read().contains_key(kind) // Owned abilities + REMOTE.read().contains_key(kind) // Own remote abilities || PEERS.read().values().any(|p| p.able(kind)) // Remote peers' abilities - || BOOT.remote_events.contains(kind) // Owned abilities from the command-line argument + || BOOT.remote_events.contains(kind) // Own abilities from the command-line argument } } + +impl Pubsub { + pub_after!(tab(idx: Id), (idx)); + + pub_after!(cd(tab: Id, url: &Url), (tab, url)); + + pub_after!(load(tab: Id, url: &Url, stage: FolderStage), (tab, url, stage)); + + pub_after!(hover(tab: Id, url: Option<&Url>), (tab, url)); + + pub_after!(rename(tab: Id, from: &Url, to: &Url), (tab, from, to)); + + pub_after!(@yank(cut: bool, urls: &HashSet), (cut, urls)); + + pub_after!(move(items: Vec), (&items), (items)); + + pub_after!(trash(urls: Vec), (&urls), (urls)); + + pub_after!(delete(urls: Vec), (&urls), (urls)); + + pub_after!(mount(), ()); +} diff --git a/yazi-dds/src/pump.rs b/yazi-dds/src/pump.rs index 6d0def49..0609b9b1 100644 --- a/yazi-dds/src/pump.rs +++ b/yazi-dds/src/pump.rs @@ -62,9 +62,9 @@ impl Pump { loop { select! { - Some(items) = move_rx.next() => err!(Pubsub::pub_from_move(items)), - Some(urls) = trash_rx.next() => err!(Pubsub::pub_from_trash(urls)), - Some(urls) = delete_rx.next() => err!(Pubsub::pub_from_delete(urls)), + Some(items) = move_rx.next() => err!(Pubsub::pub_after_move(items)), + Some(urls) = trash_rx.next() => err!(Pubsub::pub_after_trash(urls)), + Some(urls) = delete_rx.next() => err!(Pubsub::pub_after_delete(urls)), else => { CT.cancel(); break; diff --git a/yazi-shared/src/url/url.rs b/yazi-shared/src/url/url.rs index fcf1d115..1e9bfcb8 100644 --- a/yazi-shared/src/url/url.rs +++ b/yazi-shared/src/url/url.rs @@ -122,6 +122,18 @@ impl From<&Url> for String { fn from(url: &Url) -> Self { url.to_string() } } +impl<'a> From<&'a Url> for Cow<'a, Url> { + fn from(url: &'a Url) -> Self { Cow::Borrowed(url) } +} + +impl From for Cow<'_, Url> { + fn from(url: Url) -> Self { Cow::Owned(url) } +} + +impl From> for Url { + fn from(url: Cow<'static, Url>) -> Self { url.into_owned() } +} + impl Url { #[inline] pub fn join(&self, path: impl AsRef) -> Self {