Skip to content

Commit

Permalink
Make the matrix-sdk-ui crate support wasm32-unknown-unknown
Browse files Browse the repository at this point in the history
This commit adjusts types and traits to support targeting wasm32.
  • Loading branch information
Daniel Salinas authored and Daniel Salinas committed Oct 12, 2024
1 parent 41a2ad0 commit 55f7b61
Show file tree
Hide file tree
Showing 26 changed files with 190 additions and 153 deletions.
3 changes: 0 additions & 3 deletions crates/matrix-sdk-base/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ use std::{
};

use eyeball::{SharedObservable, Subscriber};
#[cfg(not(target_arch = "wasm32"))]
use eyeball_im::{Vector, VectorDiff};
#[cfg(not(target_arch = "wasm32"))]
use futures_util::Stream;
#[cfg(feature = "e2e-encryption")]
use matrix_sdk_crypto::{
Expand Down Expand Up @@ -228,7 +226,6 @@ impl BaseClient {

/// Get a stream of all the rooms changes, in addition to the existing
/// rooms.
#[cfg(not(target_arch = "wasm32"))]
pub fn rooms_stream(&self) -> (Vector<Room>, impl Stream<Item = Vec<VectorDiff<Room>>>) {
self.store.rooms_stream()
}
Expand Down
3 changes: 1 addition & 2 deletions crates/matrix-sdk-base/src/event_cache_store/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use std::{fmt, sync::Arc};

use async_trait::async_trait;
use matrix_sdk_common::AsyncTraitDeps;
use ruma::MxcUri;

use super::EventCacheStoreError;
Expand All @@ -25,7 +24,7 @@ use crate::media::MediaRequest;
/// for the event cache of the SDK.
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait EventCacheStore: AsyncTraitDeps {
pub trait EventCacheStore: Send + Sync {
/// The error type used by this event cache store.
type Error: fmt::Debug + Into<EventCacheStoreError>;

Expand Down
9 changes: 9 additions & 0 deletions crates/matrix-sdk-base/src/read_receipts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,21 @@ impl RoomReadReceipts {
}

/// Provider for timeline events prior to the current sync.
#[cfg(not(target_arch = "wasm32"))]
pub trait PreviousEventsProvider: Send + Sync {
/// Returns the list of known timeline events, in sync order, for the given
/// room.
fn for_room(&self, room_id: &RoomId) -> Vector<SyncTimelineEvent>;
}

/// Provider for timeline events prior to the current sync.
#[cfg(target_arch = "wasm32")]
pub trait PreviousEventsProvider {
/// Returns the list of known timeline events, in sync order, for the given
/// room.
fn for_room(&self, room_id: &RoomId) -> Vector<SyncTimelineEvent>;
}

impl PreviousEventsProvider for () {
fn for_room(&self, _: &RoomId) -> Vector<SyncTimelineEvent> {
Vector::new()
Expand Down
3 changes: 1 addition & 2 deletions crates/matrix-sdk-base/src/store/memory_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ impl MemoryStore {
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[async_trait]
impl StateStore for MemoryStore {
type Error = StoreError;

Expand Down
9 changes: 3 additions & 6 deletions crates/matrix-sdk-base/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ use std::{
sync::{Arc, RwLock as StdRwLock},
};

#[cfg(not(target_arch = "wasm32"))]
use eyeball_im::{Vector, VectorDiff};
#[cfg(not(target_arch = "wasm32"))]
use futures_util::Stream;
use once_cell::sync::OnceCell;

Expand Down Expand Up @@ -60,9 +58,9 @@ use tokio::sync::{broadcast, Mutex, RwLock};
use tracing::warn;

use crate::{
event_cache_store::{DynEventCacheStore, IntoEventCacheStore},
rooms::{normal::RoomInfoNotableUpdate, RoomInfo, RoomState},
MinimalRoomMemberEvent, Room, RoomStateFilter, SessionMeta,
event_cache_store::{DynEventCacheStore, IntoEventCacheStore},
rooms::{normal::RoomInfoNotableUpdate, RoomInfo, RoomState},
MinimalRoomMemberEvent, Room, RoomStateFilter, SessionMeta
};

pub(crate) mod ambiguity_map;
Expand Down Expand Up @@ -263,7 +261,6 @@ impl Store {

/// Get a stream of all the rooms changes, in addition to the existing
/// rooms.
#[cfg(not(target_arch = "wasm32"))]
pub fn rooms_stream(&self) -> (Vector<Room>, impl Stream<Item = Vec<VectorDiff<Room>>>) {
self.rooms.read().unwrap().stream()
}
Expand Down
10 changes: 10 additions & 0 deletions crates/matrix-sdk-base/src/store/observable_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ mod impl_non_wasm32 {
#[cfg(target_arch = "wasm32")]
mod impl_wasm32 {
use std::{borrow::Borrow, collections::BTreeMap, hash::Hash};
use futures_util::stream;
use futures_util::{Stream, StreamExt};
use eyeball_im::{Vector, VectorDiff};

/// An observable map for Wasm. It's a simple wrapper around `BTreeMap`.
#[derive(Debug)]
Expand Down Expand Up @@ -184,6 +187,13 @@ mod impl_wasm32 {
pub(crate) fn iter(&self) -> impl Iterator<Item = &V> {
self.0.values()
}

/// Get a [`Stream`] of the values.
pub(crate) fn stream(&self) -> (Vector<V>, impl Stream<Item = Vec<VectorDiff<V>>>) {
let values: Vector<V> = self.0.values().cloned().collect();
let stream = stream::iter(vec![values.clone()]).map(|v| vec![VectorDiff::Reset{ values: v }]);
(values, stream)
}
}
}

Expand Down
9 changes: 3 additions & 6 deletions crates/matrix-sdk-base/src/store/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use std::{
use as_variant::as_variant;
use async_trait::async_trait;
use growable_bloom_filter::GrowableBloom;
use matrix_sdk_common::AsyncTraitDeps;
use ruma::{
api::MatrixVersion,
events::{
Expand All @@ -50,9 +49,8 @@ use crate::{

/// An abstract state store trait that can be used to implement different stores
/// for the SDK.
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait StateStore: AsyncTraitDeps {
#[async_trait]
pub trait StateStore: fmt::Debug + Send + Sync {
/// The error type used by this state store.
type Error: fmt::Debug + Into<StoreError> + From<serde_json::Error>;

Expand Down Expand Up @@ -452,8 +450,7 @@ impl<T: fmt::Debug> fmt::Debug for EraseStateStoreError<T> {
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[async_trait]
impl<T: StateStore> StateStore for EraseStateStoreError<T> {
type Error = StoreError;

Expand Down
90 changes: 84 additions & 6 deletions crates/matrix-sdk-common/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,28 @@

//! Abstraction over an executor so we can spawn tasks under WASM the same way
//! we do usually.

#[cfg(target_arch = "wasm32")]
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};

use futures_util::FutureExt;
#[cfg(target_arch = "wasm32")]
pub use futures_util::future::Aborted as JoinError;
#[cfg(target_arch = "wasm32")]
use futures_util::{
future::{AbortHandle, Abortable, RemoteHandle},
FutureExt,
};
use futures_util::future::{AbortHandle, Abortable, RemoteHandle};
#[cfg(not(target_arch = "wasm32"))]
pub use tokio::task::{spawn, JoinError, JoinHandle};


/// A `Box::pin` future that is `Send` on non-wasm, and without `Send` on wasm.
#[cfg(target_arch = "wasm32")]
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
#[cfg(not(target_arch = "wasm32"))]
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;


#[cfg(target_arch = "wasm32")]
pub fn spawn<F, T>(future: F) -> JoinHandle<T>
where
Expand All @@ -50,6 +54,32 @@ where
JoinHandle { remote_handle, abort_handle }
}

pub trait BoxFutureExt<'a, T: 'a> {
fn box_future(self) -> BoxFuture<'a, T>;
}

#[cfg(not(target_arch = "wasm32"))]
impl<'a, F, T> BoxFutureExt<'a, T> for F
where
F: Future<Output = T> + 'a + Send,
T: 'a,
{
fn box_future(self) -> BoxFuture<'a, T> {
self.boxed()
}
}

#[cfg(target_arch = "wasm32")]
impl<'a, F, T> BoxFutureExt<'a, T> for F
where
F: Future<Output = T> + 'a,
T: 'a,
{
fn box_future(self) -> BoxFuture<'a, T> {
self.boxed_local()
}
}

#[cfg(target_arch = "wasm32")]
#[derive(Debug)]
pub struct JoinHandle<T> {
Expand Down Expand Up @@ -78,6 +108,54 @@ impl<T: 'static> Future for JoinHandle<T> {
}
}

#[derive(Debug)]
pub struct AbortOnDrop<T>(JoinHandle<T>);

impl<T> AbortOnDrop<T> {
pub fn new(join_handle: JoinHandle<T>) -> Self {
Self(join_handle)
}
}

impl<T> Drop for AbortOnDrop<T> {
fn drop(&mut self) {
self.0.abort();
}
}

#[cfg(not(target_arch = "wasm32"))]
impl<T> Future for AbortOnDrop<T> {
type Output = Result<T, JoinError>;

fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::new(&mut self.0).poll(cx)
}
}

#[cfg(target_arch = "wasm32")]
impl<T: 'static> Future for AbortOnDrop<T> {
type Output = Result<T, JoinError>;

fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if self.0.abort_handle.is_aborted() {
// The future has been aborted. It is not possible to poll it again.
Poll::Ready(Err(JoinError))
} else {
Pin::new(&mut self.0.remote_handle).poll(cx).map(Ok)
}
}
}

/// Trait to create a `AbortOnDrop` from a `JoinHandle`.
pub trait JoinHandleExt<T> {
fn abort_on_drop(self) -> AbortOnDrop<T>;
}

impl<T> JoinHandleExt<T> for JoinHandle<T> {
fn abort_on_drop(self) -> AbortOnDrop<T> {
AbortOnDrop::new(self)
}
}
#[cfg(test)]
mod tests {
use assert_matches::assert_matches;
Expand Down
9 changes: 0 additions & 9 deletions crates/matrix-sdk-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
#![doc = include_str!("../README.md")]
#![warn(missing_debug_implementations)]

use std::pin::Pin;

use futures_core::Future;
#[doc(no_inline)]
pub use ruma;

Expand Down Expand Up @@ -90,11 +87,5 @@ macro_rules! boxed_into_future {
};
}

/// A `Box::pin` future that is `Send` on non-wasm, and without `Send` on wasm.
#[cfg(target_arch = "wasm32")]
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;
#[cfg(not(target_arch = "wasm32"))]
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;

#[cfg(feature = "uniffi")]
uniffi::setup_scaffolding!();
2 changes: 1 addition & 1 deletion crates/matrix-sdk-crypto/src/machine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use matrix_sdk_common::{
AlgorithmInfo, DecryptedRoomEvent, DeviceLinkProblem, EncryptionInfo, UnableToDecryptInfo,
UnsignedDecryptionResult, UnsignedEventLocation, VerificationLevel, VerificationState,
},
BoxFuture,
executor::BoxFuture,
};
use ruma::{
api::client::{
Expand Down
3 changes: 1 addition & 2 deletions crates/matrix-sdk-crypto/src/store/memorystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ impl MemoryStore {

type Result<T> = std::result::Result<T, Infallible>;

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[async_trait]
impl CryptoStore for MemoryStore {
type Error = Infallible;

Expand Down
9 changes: 3 additions & 6 deletions crates/matrix-sdk-crypto/src/store/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use std::{collections::HashMap, fmt, sync::Arc};

use async_trait::async_trait;
use matrix_sdk_common::AsyncTraitDeps;
use ruma::{
events::secret::request::SecretName, DeviceId, OwnedDeviceId, RoomId, TransactionId, UserId,
};
Expand All @@ -37,9 +36,8 @@ use crate::{

/// Represents a store that the `OlmMachine` uses to store E2EE data (such as
/// cryptographic keys).
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait CryptoStore: AsyncTraitDeps {
#[async_trait]
pub trait CryptoStore: fmt::Debug + Send + Sync {
/// The error type used by this crypto store.
type Error: fmt::Debug + Into<CryptoStoreError>;

Expand Down Expand Up @@ -369,8 +367,7 @@ impl<T: fmt::Debug> fmt::Debug for EraseCryptoStoreError<T> {
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[async_trait]
impl<T: CryptoStore> CryptoStore for EraseCryptoStoreError<T> {
type Error = CryptoStoreError;

Expand Down
3 changes: 3 additions & 0 deletions crates/matrix-sdk-ui/src/room_list_service/filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,10 @@ pub trait Filter: Fn(&Room) -> bool {}
impl<F> Filter for F where F: Fn(&Room) -> bool {}

/// Type alias for a boxed filter function.
#[cfg(not(target_arch = "wasm32"))]
pub type BoxedFilterFn = Box<dyn Filter + Send + Sync>;
#[cfg(target_arch = "wasm32")]
pub type BoxedFilterFn = Box<dyn Filter>;

/// Normalize a string, i.e. decompose it into NFD (Normalization Form D, i.e. a
/// canonical decomposition, see http://www.unicode.org/reports/tr15/) and
Expand Down
10 changes: 4 additions & 6 deletions crates/matrix-sdk-ui/src/sync_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@ use futures_core::Future;
use futures_util::{pin_mut, StreamExt as _};
use matrix_sdk::Client;
use thiserror::Error;
use tokio::{
sync::{
mpsc::{Receiver, Sender},
Mutex as AsyncMutex, OwnedMutexGuard,
},
task::{spawn, JoinHandle},
use matrix_sdk_base::executor::{spawn, JoinHandle};
use tokio::sync::{
mpsc::{Receiver, Sender},
Mutex as AsyncMutex, OwnedMutexGuard,
};
use tracing::{error, info, instrument, trace, warn, Instrument, Level};

Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-ui/src/timeline/event_item/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub(in crate::timeline) struct LocalEventTimelineItem {
pub send_state: EventSendState,
/// The transaction ID.
pub transaction_id: OwnedTransactionId,
/// A handle to manipulate this event before it is sent, if possible.
// A handle to manipulate this event before it is sent, if possible.
pub send_handle: Option<SendHandle>,
}

Expand Down
Loading

0 comments on commit 55f7b61

Please sign in to comment.