From a63c4ee6cae9080b4ffa2903163d1de251b5856a Mon Sep 17 00:00:00 2001 From: a-kenji Date: Sun, 15 Feb 2026 18:26:28 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9E=96Remove=20`async-trait`=20in=20favor=20?= =?UTF-8?q?of=20native=20`RPITIT`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `async-trait` crate is no longer needed since Rust 1.75 stabilized return-position impl trait in traits ([RPITIT]). This eliminates the per-call heap allocation from boxing futures while keeping the same behavior. This is slightly less ergonomic, since it's now using static dispatch and the trait can't be dynamically dispatched anymore. [RPITIT]: https://rustc-dev-guide.rust-lang.org/return-position-impl-trait-in-trait.html --- Cargo.lock | 12 ----- client/Cargo.toml | 1 - client/src/plugin/utils.rs | 107 ++++++++++++++++++++----------------- 3 files changed, 58 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e0c077..03c0255 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -301,17 +301,6 @@ version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "atomic-waker" version = "1.1.2" @@ -511,7 +500,6 @@ version = "1.1.0" dependencies = [ "anyhow", "async-channel", - "async-trait", "battery", "chrono", "clap", diff --git a/client/Cargo.toml b/client/Cargo.toml index 1d0a3e3..7dd57cd 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -31,7 +31,6 @@ eframe = { version = "0.31.1", default-features = false, features = [ ] } # plugins -async-trait = "0.1.89" smol = "2" async-channel = "2" futures-lite = "2" diff --git a/client/src/plugin/utils.rs b/client/src/plugin/utils.rs index 53a9434..dc5f7f8 100644 --- a/client/src/plugin/utils.rs +++ b/client/src/plugin/utils.rs @@ -81,7 +81,6 @@ fn fuzzy_match(query: &str, entries: Vec) -> Vec>() } -#[async_trait::async_trait] pub trait Plugin { fn id() -> &'static str; fn priority() -> u32; @@ -113,23 +112,28 @@ pub trait Plugin { } } - async fn main( + fn main( &mut self, mut plugin_channel_out: async_channel::Sender, - ) -> anyhow::Result<()> { - self.update_entries()?; - - let (mut app_channel_out, mut plugin_channel_in) = async_channel::bounded(100); - self.register_plugin(&mut plugin_channel_out, &mut app_channel_out)?; - let mut last_query = String::from(""); - - loop { - self.update( - &mut plugin_channel_out, - &mut plugin_channel_in, - &mut last_query, - ) - .await?; + ) -> impl std::future::Future> + Send + '_ + where + Self: Send, + { + async move { + self.update_entries()?; + + let (mut app_channel_out, mut plugin_channel_in) = async_channel::bounded(100); + self.register_plugin(&mut plugin_channel_out, &mut app_channel_out)?; + let mut last_query = String::from(""); + + loop { + self.update( + &mut plugin_channel_out, + &mut plugin_channel_in, + &mut last_query, + ) + .await?; + } } } @@ -145,42 +149,47 @@ pub trait Plugin { Ok(()) } - async fn update( - &mut self, - plugin_channel_out: &mut async_channel::Sender, - plugin_channel_in: &mut async_channel::Receiver, - last_query: &mut String, - ) -> anyhow::Result<()> { - let plugin_request_option = match Self::update_timeout() { - Some(update_timeout) => { - futures_lite::future::or(async { plugin_channel_in.recv().await.ok() }, async { - smol::Timer::after(update_timeout).await; - Some(crate::model::PluginRequest::Timeout) - }) - .await + fn update<'a>( + &'a mut self, + plugin_channel_out: &'a mut async_channel::Sender, + plugin_channel_in: &'a mut async_channel::Receiver, + last_query: &'a mut String, + ) -> impl std::future::Future> + Send + 'a + where + Self: Send, + { + async move { + let plugin_request_option = match Self::update_timeout() { + Some(update_timeout) => { + futures_lite::future::or(async { plugin_channel_in.recv().await.ok() }, async { + smol::Timer::after(update_timeout).await; + Some(crate::model::PluginRequest::Timeout) + }) + .await + } + None => plugin_channel_in.recv().await.ok(), + }; + if plugin_request_option.is_none() { + return Ok(()); } - None => plugin_channel_in.recv().await.ok(), - }; - if plugin_request_option.is_none() { - return Ok(()); - } - let plugin_request = plugin_request_option.unwrap(); - - match plugin_request { - crate::model::PluginRequest::Search(query) => { - self.search(&query, plugin_channel_out)?; - *last_query = query; - } - crate::model::PluginRequest::Timeout => { - self.update_entries()?; - self.search(last_query, plugin_channel_out)?; + let plugin_request = plugin_request_option.unwrap(); + + match plugin_request { + crate::model::PluginRequest::Search(query) => { + self.search(&query, plugin_channel_out)?; + *last_query = query; + } + crate::model::PluginRequest::Timeout => { + self.update_entries()?; + self.search(last_query, plugin_channel_out)?; + } + crate::model::PluginRequest::Activate(entry) => { + self.activate(entry, plugin_channel_out)? + } } - crate::model::PluginRequest::Activate(entry) => { - self.activate(entry, plugin_channel_out)? - } - } - return Ok(()); + Ok(()) + } } fn sort(&mut self) {