From 4914c595e95b8a4202dbcf221e4dc26883e8cc2e Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 10 Aug 2022 11:19:20 +0200 Subject: [PATCH] fix(sdk): Further relax event / notification handler bounds on WASM This allows capturing non-`Send` / -`Sync` values in handler closures. --- crates/matrix-sdk-common/src/lib.rs | 9 --------- crates/matrix-sdk/src/client/mod.rs | 19 +++++++++++++++---- crates/matrix-sdk/src/event_handler.rs | 15 +++++++++++---- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/crates/matrix-sdk-common/src/lib.rs b/crates/matrix-sdk-common/src/lib.rs index ca768cd96..687e0ee13 100644 --- a/crates/matrix-sdk-common/src/lib.rs +++ b/crates/matrix-sdk-common/src/lib.rs @@ -1,8 +1,6 @@ #![doc = include_str!("../README.md")] #![warn(missing_debug_implementations)] -use std::future::Future; - pub use instant; pub mod deserialized_responses; @@ -38,13 +36,6 @@ pub trait SyncOutsideWasm {} #[cfg(target_arch = "wasm32")] impl SyncOutsideWasm for T {} -/// Alias for `Future + SendOutsideWasm`. -/// -/// Useful as a separate trait because the former trait bound can't be used -/// with `dyn`. -pub trait FutureSendOutsideWasm: Future + SendOutsideWasm {} -impl FutureSendOutsideWasm for T {} - /// Super trait that is used for our store traits, this trait will differ if /// it's used on WASM. WASM targets will not require `Send` and `Sync` to have /// implemented, while other targets will. diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index aee95c648..acfb0574f 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -32,7 +32,7 @@ use futures_signals::signal::Signal; use matrix_sdk_base::{ deserialized_responses::SyncResponse, media::{MediaEventContent, MediaFormat, MediaRequest, MediaThumbnailSize}, - BaseClient, FutureSendOutsideWasm, Session, SessionMeta, SessionTokens, StateStore, + BaseClient, SendOutsideWasm, Session, SessionMeta, SessionTokens, StateStore, SyncOutsideWasm, }; use matrix_sdk_common::{ instant::{Duration, Instant}, @@ -110,9 +110,17 @@ const MIN_UPLOAD_REQUEST_TIMEOUT: Duration = Duration::from_secs(60 * 5); type EventHandlerMap = BTreeMap>; -type NotificationHandlerFut = Pin>>; +#[cfg(not(target_arch = "wasm32"))] +type NotificationHandlerFut = Pin + Send>>; +#[cfg(target_arch = "wasm32")] +type NotificationHandlerFut = Pin>>; + +#[cfg(not(target_arch = "wasm32"))] type NotificationHandlerFn = Box NotificationHandlerFut + Send + Sync>; +#[cfg(target_arch = "wasm32")] +type NotificationHandlerFn = + Box NotificationHandlerFut>; type AnyMap = anymap2::Map; @@ -798,8 +806,11 @@ impl Client { /// [`room::Room`], [`Client`] for now. pub async fn register_notification_handler(&self, handler: H) -> &Self where - H: Fn(Notification, room::Room, Client) -> Fut + Send + Sync + 'static, - Fut: Future + Send + 'static, + H: Fn(Notification, room::Room, Client) -> Fut + + SendOutsideWasm + + SyncOutsideWasm + + 'static, + Fut: Future + SendOutsideWasm + 'static, { self.inner.notification_handlers.write().await.push(Box::new( move |notification, room, client| Box::pin((handler)(notification, room, client)), diff --git a/crates/matrix-sdk/src/event_handler.rs b/crates/matrix-sdk/src/event_handler.rs index d7d16436f..58a95d76e 100644 --- a/crates/matrix-sdk/src/event_handler.rs +++ b/crates/matrix-sdk/src/event_handler.rs @@ -45,7 +45,7 @@ use std::{ use matrix_sdk_base::{ deserialized_responses::{EncryptionInfo, SyncRoomEvent}, - FutureSendOutsideWasm, SendOutsideWasm, + SendOutsideWasm, SyncOutsideWasm, }; use ruma::{events::AnySyncStateEvent, serde::Raw, OwnedRoomId}; use serde::{de::DeserializeOwned, Deserialize}; @@ -54,8 +54,15 @@ use tracing::{error, warn}; use crate::{room, Client}; -type EventHandlerFut = Pin>>; +#[cfg(not(target_arch = "wasm32"))] +type EventHandlerFut = Pin + Send>>; +#[cfg(target_arch = "wasm32")] +type EventHandlerFut = Pin>>; + +#[cfg(not(target_arch = "wasm32"))] type EventHandlerFn = dyn Fn(EventHandlerData<'_>) -> EventHandlerFut + Send + Sync; +#[cfg(target_arch = "wasm32")] +type EventHandlerFn = dyn Fn(EventHandlerData<'_>) -> EventHandlerFut; #[doc(hidden)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -181,7 +188,7 @@ impl EventHandlerContext for EventHandlerHandle { /// /// ยน the only thing stopping such types from existing in stable Rust is that /// all manual implementations of the `Fn` traits require a Nightly feature -pub trait EventHandler: Send + Sync + 'static { +pub trait EventHandler: SendOutsideWasm + SyncOutsideWasm + 'static { /// The future returned by `handle_event`. #[doc(hidden)] type Future: Future + SendOutsideWasm + 'static; @@ -542,7 +549,7 @@ macro_rules! impl_event_handler { impl EventHandler for Fun where Ev: SyncEvent, - Fun: Fn(Ev, $($ty),*) -> Fut + Send + Sync + 'static, + Fun: Fn(Ev, $($ty),*) -> Fut + SendOutsideWasm + SyncOutsideWasm + 'static, Fut: Future + SendOutsideWasm + 'static, Fut::Output: EventHandlerResult, $($ty: EventHandlerContext),*