diff --git a/bindings/matrix-sdk-ffi-macros/src/lib.rs b/bindings/matrix-sdk-ffi-macros/src/lib.rs index 6c55aa0c797..5a0bca7b3ee 100644 --- a/bindings/matrix-sdk-ffi-macros/src/lib.rs +++ b/bindings/matrix-sdk-ffi-macros/src/lib.rs @@ -14,65 +14,52 @@ use proc_macro::TokenStream; use quote::quote; -use syn::{spanned::Spanned as _, ImplItem, Item}; +use syn::{ImplItem, Item, TraitItem}; -/// Attribute to always specify the async runtime parameter for the `uniffi` -/// export macros. -#[proc_macro_attribute] -pub fn export_async(_attr: TokenStream, item: TokenStream) -> TokenStream { - let item = proc_macro2::TokenStream::from(item); - - quote! { - #[uniffi::export(async_runtime = "tokio")] - #item - } - .into() -} - -/// Attribute to always specify the async runtime parameter for the `uniffi` -/// export macros. +/// Attribute to specify the async runtime parameter for the `uniffi` +/// export macros if there any `async fn`s in the input. #[proc_macro_attribute] pub fn export(attr: TokenStream, item: TokenStream) -> TokenStream { - let run_checks = || { - let item: Item = syn::parse(item.clone())?; + let has_async_fn = |item| { if let Item::Fn(fun) = &item { - // Fail compilation if the function is async. if fun.sig.asyncness.is_some() { - let error = syn::Error::new( - fun.span(), - "async function must be exported with #[export_async]", - ); - return Err(error); + return true; } } else if let Item::Impl(blk) = &item { - // Fail compilation if at least one function in the impl block is async. for item in &blk.items { if let ImplItem::Fn(fun) = item { if fun.sig.asyncness.is_some() { - let error = syn::Error::new( - blk.span(), - "impl block with async functions must be exported with #[export_async]", - ); - return Err(error); + return true; + } + } + } + } else if let Item::Trait(blk) = &item { + for item in &blk.items { + if let TraitItem::Fn(fun) = item { + if fun.sig.asyncness.is_some() { + return true; } } } } - Ok(()) + false }; - let maybe_error = - if let Err(err) = run_checks() { Some(err.into_compile_error()) } else { None }; + let attr2 = proc_macro2::TokenStream::from(attr); + let item2 = proc_macro2::TokenStream::from(item.clone()); - let item = proc_macro2::TokenStream::from(item); - let attr = proc_macro2::TokenStream::from(attr); + let res = match syn::parse(item) { + Ok(item) => match has_async_fn(item) { + true => quote! { #[uniffi::export(async_runtime = "tokio", #attr2)] }, + false => quote! { #[uniffi::export(#attr2)] }, + }, + Err(e) => e.into_compile_error(), + }; quote! { - #maybe_error - - #[uniffi::export(#attr)] - #item + #res + #item2 } .into() } diff --git a/bindings/matrix-sdk-ffi/src/authentication.rs b/bindings/matrix-sdk-ffi/src/authentication.rs index 3a22244c519..8540ca3b644 100644 --- a/bindings/matrix-sdk-ffi/src/authentication.rs +++ b/bindings/matrix-sdk-ffi/src/authentication.rs @@ -62,7 +62,7 @@ pub struct SsoHandler { pub(crate) url: String, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl SsoHandler { /// Returns the URL for starting SSO authentication. The URL should be /// opened in a web view. Once the web view succeeds, call `finish` with diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index f6646b2b176..8e451b65b6e 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -260,7 +260,7 @@ impl Client { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl Client { /// Information about login options for the client's homeserver. pub async fn homeserver_login_details(&self) -> Arc { @@ -526,7 +526,7 @@ impl Client { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl Client { /// The sliding sync version. pub fn sliding_sync_version(&self) -> SlidingSyncVersion { diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 9b817dd4f66..f05b211dafc 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -270,7 +270,7 @@ pub struct ClientBuilder { request_config: Option, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl ClientBuilder { #[uniffi::constructor] pub fn new() -> Arc { diff --git a/bindings/matrix-sdk-ffi/src/encryption.rs b/bindings/matrix-sdk-ffi/src/encryption.rs index cd7c6e94fc1..25849e60e42 100644 --- a/bindings/matrix-sdk-ffi/src/encryption.rs +++ b/bindings/matrix-sdk-ffi/src/encryption.rs @@ -212,7 +212,7 @@ impl From for VerificationState { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl Encryption { /// Get the public ed25519 key of our own device. This is usually what is /// called the fingerprint of the device. @@ -432,7 +432,7 @@ pub struct UserIdentity { inner: matrix_sdk::encryption::identities::UserIdentity, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl UserIdentity { /// Remember this identity, ensuring it does not result in a pin violation. /// @@ -468,7 +468,7 @@ pub struct IdentityResetHandle { pub(crate) inner: matrix_sdk::encryption::recovery::IdentityResetHandle, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl IdentityResetHandle { /// Get the underlying [`CrossSigningResetAuthType`] this identity reset /// process is using. diff --git a/bindings/matrix-sdk-ffi/src/notification.rs b/bindings/matrix-sdk-ffi/src/notification.rs index 35d047b94a2..5c51a695150 100644 --- a/bindings/matrix-sdk-ffi/src/notification.rs +++ b/bindings/matrix-sdk-ffi/src/notification.rs @@ -88,7 +88,7 @@ pub struct NotificationClient { pub(crate) _client: Arc, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl NotificationClient { /// See also documentation of /// `MatrixNotificationClient::get_notification`. diff --git a/bindings/matrix-sdk-ffi/src/notification_settings.rs b/bindings/matrix-sdk-ffi/src/notification_settings.rs index 1a01011a889..fc1b7fbb8a4 100644 --- a/bindings/matrix-sdk-ffi/src/notification_settings.rs +++ b/bindings/matrix-sdk-ffi/src/notification_settings.rs @@ -98,7 +98,7 @@ impl Drop for NotificationSettings { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl NotificationSettings { pub fn set_delegate(&self, delegate: Option>) { if let Some(delegate) = delegate { diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index d5d36e57a19..8ecbe787623 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -82,7 +82,7 @@ impl Room { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl Room { pub fn id(&self) -> String { self.inner.room_id().to_string() diff --git a/bindings/matrix-sdk-ffi/src/room_directory_search.rs b/bindings/matrix-sdk-ffi/src/room_directory_search.rs index 0666b50e3b3..9d37b60d45e 100644 --- a/bindings/matrix-sdk-ffi/src/room_directory_search.rs +++ b/bindings/matrix-sdk-ffi/src/room_directory_search.rs @@ -79,7 +79,7 @@ impl RoomDirectorySearch { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl RoomDirectorySearch { pub async fn next_page(&self) -> Result<(), ClientError> { let mut inner = self.inner.write().await; diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 9f70e9e71f3..d8700571580 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -85,7 +85,7 @@ pub struct RoomListService { pub(crate) utd_hook: Option>, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl RoomListService { fn state(&self, listener: Box) -> Arc { let state_stream = self.inner.state(); @@ -549,7 +549,7 @@ impl RoomListItem { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl RoomListItem { fn id(&self) -> String { self.inner.id().to_string() diff --git a/bindings/matrix-sdk-ffi/src/session_verification.rs b/bindings/matrix-sdk-ffi/src/session_verification.rs index f0cf5437425..655e92d7e5f 100644 --- a/bindings/matrix-sdk-ffi/src/session_verification.rs +++ b/bindings/matrix-sdk-ffi/src/session_verification.rs @@ -58,7 +58,7 @@ pub struct SessionVerificationController { sas_verification: Arc>>, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl SessionVerificationController { pub async fn is_verified(&self) -> Result { let device = diff --git a/bindings/matrix-sdk-ffi/src/sync_service.rs b/bindings/matrix-sdk-ffi/src/sync_service.rs index 3d3d30b0a66..dd1e6b89d27 100644 --- a/bindings/matrix-sdk-ffi/src/sync_service.rs +++ b/bindings/matrix-sdk-ffi/src/sync_service.rs @@ -62,7 +62,7 @@ pub struct SyncService { utd_hook: Option>, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl SyncService { pub fn room_list_service(&self) -> Arc { Arc::new(RoomListService { @@ -110,7 +110,7 @@ impl SyncServiceBuilder { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl SyncServiceBuilder { pub fn with_cross_process_lock(self: Arc, app_identifier: Option) -> Arc { let this = unwrap_or_clone_arc(self); diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index a9dd3597698..7d3117c3b8c 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -142,7 +142,7 @@ impl Timeline { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl Timeline { pub async fn add_listener(&self, listener: Box) -> Arc { let (timeline_items, timeline_stream) = self.inner.subscribe_batched().await; @@ -688,7 +688,7 @@ pub struct SendHandle { inner: Mutex>, } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl SendHandle { /// Try to abort the sending of the current event. /// @@ -1182,7 +1182,7 @@ impl SendAttachmentJoinHandle { } } -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl SendAttachmentJoinHandle { pub async fn join(&self) -> Result<(), RoomError> { let join_hdl = self.join_hdl.clone(); diff --git a/bindings/matrix-sdk-ffi/src/widget.rs b/bindings/matrix-sdk-ffi/src/widget.rs index 2e5ca65c8a1..956670f4bb0 100644 --- a/bindings/matrix-sdk-ffi/src/widget.rs +++ b/bindings/matrix-sdk-ffi/src/widget.rs @@ -29,7 +29,7 @@ pub fn make_widget_driver(settings: WidgetSettings) -> Result>); -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl WidgetDriver { pub async fn run( &self, @@ -96,7 +96,7 @@ impl From for WidgetSettings { /// * `room` - A matrix room which is used to query the logged in username /// * `props` - Properties from the client that can be used by a widget to adapt /// to the client. e.g. language, font-scale... -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] pub async fn generate_webview_url( widget_settings: WidgetSettings, room: Arc, @@ -354,7 +354,7 @@ impl From for matrix_sdk::widget::ClientProperties { #[derive(uniffi::Object)] pub struct WidgetDriverHandle(matrix_sdk::widget::WidgetDriverHandle); -#[matrix_sdk_ffi_macros::export_async] +#[matrix_sdk_ffi_macros::export] impl WidgetDriverHandle { /// Receive a message from the widget driver. ///