From 98e040194ef098fe72ebc3ae6b52040310c5fc06 Mon Sep 17 00:00:00 2001 From: Dave Patrick Caberto Date: Sat, 27 Jan 2024 15:37:08 +0800 Subject: [PATCH 1/4] feat!: drop async_trait usage Replace with native async function in trait Closes #4 --- Cargo.toml | 2 +- README.md | 3 --- examples/local_server.rs | 5 ----- examples/server.rs | 5 ----- src/lib.rs | 38 ++------------------------------------ src/local_server.rs | 5 ----- src/player.rs | 3 --- 7 files changed, 3 insertions(+), 58 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 95b9429..839daf0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,9 @@ edition = "2021" [dependencies] async-channel = "2.2" -async-trait = "0.1" futures-channel = "0.3" serde = "1.0" +trait-variant = "0.1.2" zbus = "4.0" [dev-dependencies] diff --git a/README.md b/README.md index c1ee60e..48ffa7b 100644 --- a/README.md +++ b/README.md @@ -38,14 +38,12 @@ If you want to have more control, it is recommended to manually create your own use std::future; use mpris_server::{ - async_trait, zbus::{fdo, Result}, Metadata, PlayerInterface, Property, RootInterface, Server, Signal, Time, Volume, }; pub struct MyPlayer; -#[async_trait] impl RootInterface for MyPlayer { async fn identity(&self) -> fdo::Result { Ok("MyPlayer".into()) @@ -54,7 +52,6 @@ impl RootInterface for MyPlayer { // Other methods... } -#[async_trait] impl PlayerInterface for MyPlayer { async fn set_volume(&self, volume: Volume) -> Result<()> { self.volume.set(volume); diff --git a/examples/local_server.rs b/examples/local_server.rs index f4d88b4..742f615 100644 --- a/examples/local_server.rs +++ b/examples/local_server.rs @@ -1,7 +1,6 @@ use std::future; use mpris_server::{ - async_trait, zbus::{fdo, Result}, LocalPlayerInterface, LocalPlaylistsInterface, LocalRootInterface, LocalServer, LocalTrackListInterface, LoopStatus, Metadata, PlaybackRate, PlaybackStatus, Playlist, @@ -10,7 +9,6 @@ use mpris_server::{ pub struct Player; -#[async_trait(?Send)] impl LocalRootInterface for Player { async fn raise(&self) -> fdo::Result<()> { println!("Raise"); @@ -73,7 +71,6 @@ impl LocalRootInterface for Player { } } -#[async_trait(?Send)] impl LocalPlayerInterface for Player { async fn next(&self) -> fdo::Result<()> { println!("Next"); @@ -216,7 +213,6 @@ impl LocalPlayerInterface for Player { } } -#[async_trait(?Send)] impl LocalTrackListInterface for Player { async fn get_tracks_metadata(&self, track_ids: Vec) -> fdo::Result> { println!("GetTracksMetadata({:?})", track_ids); @@ -254,7 +250,6 @@ impl LocalTrackListInterface for Player { } } -#[async_trait(?Send)] impl LocalPlaylistsInterface for Player { async fn activate_playlist(&self, playlist_id: PlaylistId) -> fdo::Result<()> { println!("ActivatePlaylist({})", playlist_id); diff --git a/examples/server.rs b/examples/server.rs index be921d8..5515473 100644 --- a/examples/server.rs +++ b/examples/server.rs @@ -1,7 +1,6 @@ use std::future; use mpris_server::{ - async_trait, zbus::{fdo, Result}, LoopStatus, Metadata, PlaybackRate, PlaybackStatus, PlayerInterface, Playlist, PlaylistId, PlaylistOrdering, PlaylistsInterface, Property, RootInterface, Server, Signal, Time, TrackId, @@ -10,7 +9,6 @@ use mpris_server::{ pub struct Player; -#[async_trait] impl RootInterface for Player { async fn raise(&self) -> fdo::Result<()> { println!("Raise"); @@ -73,7 +71,6 @@ impl RootInterface for Player { } } -#[async_trait] impl PlayerInterface for Player { async fn next(&self) -> fdo::Result<()> { println!("Next"); @@ -216,7 +213,6 @@ impl PlayerInterface for Player { } } -#[async_trait] impl TrackListInterface for Player { async fn get_tracks_metadata(&self, track_ids: Vec) -> fdo::Result> { println!("GetTracksMetadata({:?})", track_ids); @@ -254,7 +250,6 @@ impl TrackListInterface for Player { } } -#[async_trait] impl PlaylistsInterface for Player { async fn activate_playlist(&self, playlist_id: PlaylistId) -> fdo::Result<()> { println!("ActivatePlaylist({})", playlist_id); diff --git a/src/lib.rs b/src/lib.rs index bd160ed..6a917af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,40 +33,6 @@ pub mod builder { pub use crate::{metadata::MetadataBuilder, player::PlayerBuilder}; } -/// Retrofits support for `async fn` in trait impls and declarations. -/// -/// Any trait declaration or trait `impl` decorated with `#[async_trait]` or -/// `#[async_trait(?Send)]` is retrofitted with support for `async fn`s: -/// -/// # Examples -/// -/// ```ignore -/// use mpris_server::{async_trait, LocalRootInterface, RootInterface}; -/// use zbus::fdo; -/// -/// struct MyPlayer; -/// -/// #[async_trait] -/// impl RootInterface for MyPlayer { -/// async fn identity(&self) -> fdo::Result { -/// Ok("MyPlayer".into()) -/// } -/// -/// // Other methods... -/// } -/// -/// struct MyLocalPlayer; -/// -/// #[async_trait(?Send)] -/// impl LocalRootInterface for MyLocalPlayer { -/// async fn identity(&self) -> fdo::Result { -/// Ok("MyLocalPlayer".into()) -/// } -/// -/// // Other methods... -/// } -/// ``` -pub use async_trait::async_trait; pub use zbus; use zbus::{fdo, zvariant::OwnedObjectPath, Result}; @@ -1167,7 +1133,7 @@ macro_rules! define_iface { } define_iface!( - #[async_trait], + #[trait_variant::make(Send + Sync)], RootInterface: Send + Sync extra_docs "", PlayerInterface extra_docs "", TrackListInterface extra_docs "", @@ -1175,7 +1141,7 @@ define_iface!( ); define_iface!( - #[async_trait(?Send)], + #[trait_variant::make], LocalRootInterface extra_docs "Local version of [`RootInterface`] to be used with [`LocalServer`].", LocalPlayerInterface extra_docs "Local version of [`PlayerInterface`] to be used with [`LocalServer`].", LocalTrackListInterface extra_docs "Local version of [`TrackListInterface`] to be used with [`LocalServer`].", diff --git a/src/local_server.rs b/src/local_server.rs index bc90e0f..99e034e 100644 --- a/src/local_server.rs +++ b/src/local_server.rs @@ -9,7 +9,6 @@ use std::{ }; use async_channel::{Receiver, Sender}; -use async_trait::async_trait; use futures_channel::oneshot; use zbus::{fdo, Connection, Result}; @@ -137,7 +136,6 @@ impl InnerImp { } } -#[async_trait] impl RootInterface for InnerImp { async fn raise(&self) -> fdo::Result<()> { let (tx, rx) = oneshot::channel(); @@ -213,7 +211,6 @@ impl RootInterface for InnerImp { } } -#[async_trait] impl PlayerInterface for InnerImp { async fn next(&self) -> fdo::Result<()> { let (tx, rx) = oneshot::channel(); @@ -387,7 +384,6 @@ impl PlayerInterface for InnerImp { } } -#[async_trait] impl TrackListInterface for InnerImp where T: LocalTrackListInterface, @@ -444,7 +440,6 @@ where } } -#[async_trait] impl PlaylistsInterface for InnerImp where T: LocalPlaylistsInterface, diff --git a/src/player.rs b/src/player.rs index 93e9327..2f94748 100644 --- a/src/player.rs +++ b/src/player.rs @@ -3,7 +3,6 @@ use std::{ rc::{Rc, Weak}, }; -use async_trait::async_trait; use zbus::{fdo, Result}; use crate::{ @@ -87,7 +86,6 @@ impl State { } } -#[async_trait(?Send)] impl LocalRootInterface for State { async fn raise(&self) -> fdo::Result<()> { let player = self.player(); @@ -150,7 +148,6 @@ impl LocalRootInterface for State { } } -#[async_trait(?Send)] impl LocalPlayerInterface for State { async fn next(&self) -> fdo::Result<()> { let player = self.player(); From de5b9868bbb75ae3d74a816a0d2e5b44f20c10de Mon Sep 17 00:00:00 2001 From: Dave Patrick Caberto Date: Wed, 14 Feb 2024 22:46:13 +0800 Subject: [PATCH 2/4] misc: don't use trait_variant::make on Local versions --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 6a917af..0987217 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1141,7 +1141,7 @@ define_iface!( ); define_iface!( - #[trait_variant::make], + #[allow(async_fn_in_trait)], LocalRootInterface extra_docs "Local version of [`RootInterface`] to be used with [`LocalServer`].", LocalPlayerInterface extra_docs "Local version of [`PlayerInterface`] to be used with [`LocalServer`].", LocalTrackListInterface extra_docs "Local version of [`TrackListInterface`] to be used with [`LocalServer`].", From 5847fd23c31d6c244090f23c6f14e1b699018545 Mon Sep 17 00:00:00 2001 From: Dave Patrick Caberto Date: Wed, 14 Feb 2024 22:49:28 +0800 Subject: [PATCH 3/4] fix: drop redundant trait bounds Send + Sync is already set by trait_variant --- src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0987217..c8b9239 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -53,7 +53,7 @@ pub use crate::{ macro_rules! define_iface { (#[$attr:meta], - $root_iface_ident:ident$(: $bound:tt $(+ $other_bounds:tt)* )? extra_docs $extra_root_docs:literal, + $root_iface_ident:ident extra_docs $extra_root_docs:literal, $player_iface_ident:ident extra_docs $extra_player_docs:literal, $track_list_iface_ident:ident extra_docs $extra_track_list_docs:literal, $playlists_iface_ident:ident extra_docs $extra_playlists_docs:literal) => { @@ -63,7 +63,7 @@ macro_rules! define_iface { /// /// [org.mpris.MediaPlayer2]: https://specifications.freedesktop.org/mpris-spec/2.2/Media_Player.html #[$attr] - pub trait $root_iface_ident$(: $bound $(+ $other_bounds)* )? { + pub trait $root_iface_ident { /// Brings the media player's user interface to the front using any /// appropriate mechanism available. /// @@ -1134,7 +1134,7 @@ macro_rules! define_iface { define_iface!( #[trait_variant::make(Send + Sync)], - RootInterface: Send + Sync extra_docs "", + RootInterface extra_docs "", PlayerInterface extra_docs "", TrackListInterface extra_docs "", PlaylistsInterface extra_docs "" From 05ac7c9e3b1ba93d8a355d404de54e9e0dbbeae0 Mon Sep 17 00:00:00 2001 From: Dave Patrick Caberto Date: Wed, 14 Feb 2024 22:52:29 +0800 Subject: [PATCH 4/4] misc(tests): ensure that non-local interfaces implement Send + Sync --- src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index c8b9239..291b4d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1192,6 +1192,11 @@ mod tests { use super::*; + assert_trait_sub_all!(RootInterface: Send, Sync); + assert_trait_sub_all!(PlayerInterface: Send, Sync); + assert_trait_sub_all!(TrackListInterface: Send, Sync); + assert_trait_sub_all!(PlaylistsInterface: Send, Sync); + assert_trait_sub_all!(PlayerInterface: RootInterface); assert_trait_sub_all!(TrackListInterface: PlayerInterface, RootInterface); assert_trait_sub_all!(PlaylistsInterface: PlayerInterface, RootInterface);