diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index 4dade2e0d..ecd59b0e7 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -47,7 +47,10 @@ use ruma::{ receipt::{Receipt, ReceiptEventContent, ReceiptType}, room::member::{StrippedRoomMemberEvent, SyncRoomMemberEvent}, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnyStrippedStateEvent, - AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType, + AnySyncStateEvent, GlobalAccountDataEvent, GlobalAccountDataEventContent, + GlobalAccountDataEventType, RedactContent, RedactedEventContent, RoomAccountDataEvent, + RoomAccountDataEventContent, RoomAccountDataEventType, StateEventContent, StateEventType, + StaticEventContent, SyncStateEvent, }, serde::Raw, EventId, MxcUri, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId, @@ -375,6 +378,81 @@ pub trait StateStore: AsyncTraitDeps { ) -> Result>, Option)>>; } +/// Convenience functionality for state stores. +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait StateStoreExt: StateStore { + /// Get a specific state event of statically-known type. + /// + /// # Arguments + /// + /// * `room_id` - The id of the room the state event was received for. + async fn get_state_event_static( + &self, + room_id: &RoomId, + state_key: &str, + ) -> Result>>> + where + C: StaticEventContent + StateEventContent + RedactContent, + C::Redacted: StateEventContent + RedactedEventContent, + { + Ok(self.get_state_event(room_id, C::TYPE.into(), state_key).await?.map(Raw::cast)) + } + + /// Get a list of state events of a statically-known type for a given room. + /// + /// # Arguments + /// + /// * `room_id` - The id of the room to find events for. + async fn get_state_events_static( + &self, + room_id: &RoomId, + ) -> Result>>> + where + C: StaticEventContent + StateEventContent + RedactContent, + C::Redacted: StateEventContent + RedactedEventContent, + { + // FIXME: Could be more efficient, if we had streaming store accessor functions + Ok(self + .get_state_events(room_id, C::TYPE.into()) + .await? + .into_iter() + .map(Raw::cast) + .collect()) + } + + /// Get an event of a statically-known type from the account data store. + async fn get_account_data_event_static( + &self, + ) -> Result>>> + where + C: StaticEventContent + GlobalAccountDataEventContent, + { + Ok(self.get_account_data_event(C::TYPE.into()).await?.map(Raw::cast)) + } + + /// Get an event of a statically-known type from the room account data + /// store. + /// + /// # Arguments + /// + /// * `room_id` - The id of the room for which the room account data event + /// should be fetched. + async fn get_room_account_data_event_static( + &self, + room_id: &RoomId, + ) -> Result>>> + where + C: StaticEventContent + RoomAccountDataEventContent, + { + Ok(self.get_room_account_data_event(room_id, C::TYPE.into()).await?.map(Raw::cast)) + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl StateStoreExt for T {} + /// A type that can be type-erased into `Arc`. /// /// This trait is not meant to be implemented directly outside diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 0780992fc..50cb32a07 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -4,7 +4,10 @@ use futures_channel::mpsc; #[cfg(feature = "experimental-timeline")] use futures_core::stream::Stream; use futures_util::{SinkExt, TryStreamExt}; -use matrix_sdk_base::deserialized_responses::{MembersResponse, RoomEvent}; +use matrix_sdk_base::{ + deserialized_responses::{MembersResponse, RoomEvent}, + store::StateStoreExt, +}; #[cfg(feature = "experimental-timeline")] use matrix_sdk_base::{ deserialized_responses::{SyncRoomEvent, TimelineSlice}, @@ -790,8 +793,7 @@ impl Common { C: StaticEventContent + StateEventContent + RedactContent, C::Redacted: StateEventContent + RedactedEventContent, { - // FIXME: Could be more efficient, if we had streaming store accessor functions - Ok(self.get_state_events(C::TYPE.into()).await?.into_iter().map(Raw::cast).collect()) + Ok(self.client.store().get_state_events_static(self.room_id()).await?) } /// Get a specific state event in this room. @@ -832,7 +834,7 @@ impl Common { C: StaticEventContent + StateEventContent + RedactContent, C::Redacted: StateEventContent + RedactedEventContent, { - Ok(self.get_state_event(C::TYPE.into(), state_key).await?.map(Raw::cast)) + Ok(self.client.store().get_state_event_static(self.room_id(), state_key).await?) } /// Get account data in this room.