Skip to content

Commit fab520a

Browse files
zecakehHywan
authored andcommitted
refactor(base): Add methods on StateChanges to get a member or power level event
To reduce duplication. Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
1 parent 435553c commit fab520a

File tree

4 files changed

+113
-84
lines changed

4 files changed

+113
-84
lines changed

crates/matrix-sdk-base/src/response_processors/room/msc4186/mod.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ use std::collections::BTreeSet;
2020

2121
#[cfg(feature = "e2e-encryption")]
2222
use matrix_sdk_common::deserialized_responses::TimelineEvent;
23-
#[cfg(feature = "e2e-encryption")]
24-
use ruma::events::StateEventType;
2523
use ruma::{
2624
api::client::sync::sync_events::{
2725
v3::{InviteState, InvitedRoom, KnockState, KnockedRoom},
@@ -441,19 +439,9 @@ pub(crate) async fn cache_latest_events(
441439
let mut encrypted_events =
442440
Vec::with_capacity(room.latest_encrypted_events.read().unwrap().capacity());
443441

444-
// Try to get room power levels from the current changes
445-
let power_levels_from_changes = || {
446-
let state_changes = changes?.state.get(room_info.room_id())?;
447-
let room_power_levels_state =
448-
state_changes.get(&StateEventType::RoomPowerLevels)?.values().next()?;
449-
match room_power_levels_state.deserialize().ok()? {
450-
AnySyncStateEvent::RoomPowerLevels(ev) => Some(ev.power_levels()),
451-
_ => None,
452-
}
453-
};
454-
455-
// If we didn't get any info, try getting it from local data
456-
let power_levels = match power_levels_from_changes() {
442+
// Try to get room power levels from the current changes. If we didn't get any
443+
// info, try getting it from local data.
444+
let power_levels = match changes.and_then(|changes| changes.power_levels(room_info.room_id())) {
457445
Some(power_levels) => Some(power_levels),
458446
None => room.power_levels().await.ok(),
459447
};

crates/matrix-sdk-base/src/response_processors/timeline.rs

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@ use matrix_sdk_common::deserialized_responses::TimelineEvent;
1717
use ruma::events::SyncMessageLikeEvent;
1818
use ruma::{
1919
events::{
20-
room::power_levels::{
21-
RoomPowerLevelsEvent, RoomPowerLevelsEventContent, StrippedRoomPowerLevelsEvent,
22-
},
23-
AnyStrippedStateEvent, AnySyncMessageLikeEvent, AnySyncStateEvent, AnySyncTimelineEvent,
24-
StateEventType,
20+
room::power_levels::RoomPowerLevelsEventContent, AnySyncMessageLikeEvent,
21+
AnySyncTimelineEvent,
2522
},
2623
push::{Action, PushConditionRoomCtx},
2724
UInt, UserId,
@@ -207,23 +204,13 @@ fn update_push_room_context(
207204
push_rules.member_count = UInt::new(room_info.active_members_count()).unwrap_or(UInt::MAX);
208205

209206
// TODO: Use if let chain once stable
210-
if let Some(AnySyncStateEvent::RoomMember(member)) =
211-
context.state_changes.state.get(room_id).and_then(|events| {
212-
events.get(&StateEventType::RoomMember)?.get(user_id.as_str())?.deserialize().ok()
213-
})
214-
{
215-
push_rules.user_display_name = member
216-
.as_original()
217-
.and_then(|ev| ev.content.displayname.clone())
218-
.unwrap_or_else(|| user_id.localpart().to_owned())
207+
if let Some(member) = context.state_changes.member(room_id, user_id) {
208+
push_rules.user_display_name =
209+
member.content.displayname.unwrap_or_else(|| user_id.localpart().to_owned())
219210
}
220211

221-
if let Some(AnySyncStateEvent::RoomPowerLevels(event)) =
222-
context.state_changes.state.get(room_id).and_then(|types| {
223-
types.get(&StateEventType::RoomPowerLevels)?.get("")?.deserialize().ok()
224-
})
225-
{
226-
push_rules.power_levels = Some(event.power_levels().into());
212+
if let Some(power_levels) = context.state_changes.power_levels(room_id) {
213+
push_rules.power_levels = Some(power_levels.into());
227214
}
228215
}
229216

@@ -246,19 +233,7 @@ pub async fn get_push_room_context(
246233
let member_count = room_info.active_members_count();
247234

248235
// TODO: Use if let chain once stable
249-
let user_display_name = if let Some(AnySyncStateEvent::RoomMember(member)) =
250-
context.state_changes.state.get(room_id).and_then(|events| {
251-
events.get(&StateEventType::RoomMember)?.get(user_id.as_str())?.deserialize().ok()
252-
}) {
253-
member
254-
.as_original()
255-
.and_then(|ev| ev.content.displayname.clone())
256-
.unwrap_or_else(|| user_id.localpart().to_owned())
257-
} else if let Some(AnyStrippedStateEvent::RoomMember(member)) =
258-
context.state_changes.stripped_state.get(room_id).and_then(|events| {
259-
events.get(&StateEventType::RoomMember)?.get(user_id.as_str())?.deserialize().ok()
260-
})
261-
{
236+
let user_display_name = if let Some(member) = context.state_changes.member(room_id, user_id) {
262237
member.content.displayname.unwrap_or_else(|| user_id.localpart().to_owned())
263238
} else if let Some(member) = Box::pin(room.get_member(user_id)).await? {
264239
member.name().to_owned()
@@ -267,38 +242,21 @@ pub async fn get_push_room_context(
267242
return Ok(None);
268243
};
269244

270-
let power_levels = if let Some(event) =
271-
context.state_changes.state.get(room_id).and_then(|types| {
272-
types
273-
.get(&StateEventType::RoomPowerLevels)?
274-
.get("")?
275-
.deserialize_as::<RoomPowerLevelsEvent>()
276-
.ok()
277-
}) {
278-
Some(event.power_levels().into())
279-
} else if let Some(event) =
280-
context.state_changes.stripped_state.get(room_id).and_then(|types| {
281-
types
282-
.get(&StateEventType::RoomPowerLevels)?
283-
.get("")?
284-
.deserialize_as::<StrippedRoomPowerLevelsEvent>()
285-
.ok()
286-
})
287-
{
288-
Some(event.power_levels().into())
245+
let power_levels = if let Some(power_levels) = context.state_changes.power_levels(room_id) {
246+
Some(power_levels)
289247
} else {
290248
state_store
291249
.get_state_event_static::<RoomPowerLevelsEventContent>(room_id)
292250
.await?
293251
.and_then(|e| e.deserialize().ok())
294-
.map(|event| event.power_levels().into())
252+
.map(|event| event.power_levels())
295253
};
296254

297255
Ok(Some(PushConditionRoomCtx {
298256
user_id: user_id.to_owned(),
299257
room_id: room_id.to_owned(),
300258
member_count: UInt::new(member_count).unwrap_or(UInt::MAX),
301259
user_display_name,
302-
power_levels,
260+
power_levels: power_levels.map(Into::into),
303261
}))
304262
}

crates/matrix-sdk-base/src/store/ambiguity_map.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,14 @@ use std::{
1818
};
1919

2020
use ruma::{
21-
events::{
22-
room::member::{MembershipState, SyncRoomMemberEvent},
23-
StateEventType,
24-
},
21+
events::room::member::{MembershipState, SyncRoomMemberEvent},
2522
OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId,
2623
};
2724
use tracing::{instrument, trace};
2825

2926
use super::{DynStateStore, Result, StateChanges};
3027
use crate::{
31-
deserialized_responses::{AmbiguityChange, DisplayName, RawMemberEvent},
28+
deserialized_responses::{AmbiguityChange, DisplayName, SyncOrStrippedState},
3229
store::StateStoreExt,
3330
};
3431

@@ -188,17 +185,13 @@ impl AmbiguityCache {
188185
) -> Result<Option<String>> {
189186
let user_id = new_event.state_key();
190187

191-
let old_event = if let Some(m) = changes
192-
.state
193-
.get(room_id)
194-
.and_then(|events| events.get(&StateEventType::RoomMember)?.get(user_id.as_str()))
195-
{
196-
Some(RawMemberEvent::Sync(m.clone().cast()))
188+
let old_event = if let Some(member) = changes.member(room_id, user_id) {
189+
Some(SyncOrStrippedState::Stripped(member))
197190
} else {
198-
self.store.get_member_event(room_id, user_id).await?
191+
self.store.get_member_event(room_id, user_id).await?.and_then(|r| r.deserialize().ok())
199192
};
200193

201-
let Some(Ok(old_event)) = old_event.map(|r| r.deserialize()) else { return Ok(None) };
194+
let Some(old_event) = old_event else { return Ok(None) };
202195

203196
if is_member_active(old_event.membership()) {
204197
let display_name = if let Some(d) = changes

crates/matrix-sdk-base/src/store/mod.rs

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
//! store.
2222
2323
use std::{
24+
borrow::Borrow,
2425
collections::{BTreeMap, BTreeSet, HashMap},
2526
fmt,
2627
ops::Deref,
@@ -47,13 +48,20 @@ use ruma::{
4748
events::{
4849
presence::PresenceEvent,
4950
receipt::ReceiptEventContent,
50-
room::{member::StrippedRoomMemberEvent, redaction::SyncRoomRedactionEvent},
51+
room::{
52+
member::{RoomMemberEventContent, StrippedRoomMemberEvent},
53+
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
54+
redaction::SyncRoomRedactionEvent,
55+
},
5156
AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnyStrippedStateEvent,
52-
AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType,
57+
AnySyncStateEvent, EmptyStateKey, GlobalAccountDataEventType, RedactContent,
58+
RedactedStateEventContent, RoomAccountDataEventType, StateEventType, StaticEventContent,
59+
StaticStateEventContent, StrippedStateEvent, SyncStateEvent,
5360
},
5461
serde::Raw,
5562
EventId, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId,
5663
};
64+
use serde::de::DeserializeOwned;
5765
use tokio::sync::{broadcast, Mutex, RwLock};
5866
use tracing::warn;
5967

@@ -556,6 +564,88 @@ impl StateChanges {
556564
pub fn add_receipts(&mut self, room_id: &RoomId, event: ReceiptEventContent) {
557565
self.receipts.insert(room_id.to_owned(), event);
558566
}
567+
568+
/// Get a specific state event of statically-known type with the given state
569+
/// key in the given room, if it is present in the `state` map of these
570+
/// `StateChanges`.
571+
pub(crate) fn state_static_for_key<C, K>(
572+
&self,
573+
room_id: &RoomId,
574+
state_key: &K,
575+
) -> Option<&Raw<SyncStateEvent<C>>>
576+
where
577+
C: StaticEventContent + StaticStateEventContent + RedactContent,
578+
C::Redacted: RedactedStateEventContent,
579+
C::StateKey: Borrow<K>,
580+
K: AsRef<str> + ?Sized,
581+
{
582+
self.state.get(room_id)?.get(&C::TYPE.into())?.get(state_key.as_ref()).map(Raw::cast_ref)
583+
}
584+
585+
/// Get a specific stripped state event of statically-known type with the
586+
/// given state key in the given room, if it is present in the
587+
/// `stripped_state` map of these `StateChanges`.
588+
pub(crate) fn stripped_state_static_for_key<C, K>(
589+
&self,
590+
room_id: &RoomId,
591+
state_key: &K,
592+
) -> Option<&Raw<StrippedStateEvent<C::PossiblyRedacted>>>
593+
where
594+
C: StaticEventContent + StaticStateEventContent,
595+
C::StateKey: Borrow<K>,
596+
K: AsRef<str> + ?Sized,
597+
{
598+
self.stripped_state
599+
.get(room_id)?
600+
.get(&C::TYPE.into())?
601+
.get(state_key.as_ref())
602+
.map(Raw::cast_ref)
603+
}
604+
605+
/// Get a specific state event of statically-known type with the given state
606+
/// key in the given room, if it is present in the `state` or
607+
/// `stripped_state` map of these `StateChanges` and it deserializes
608+
/// successfully.
609+
pub(crate) fn any_state_static_for_key<C, K>(
610+
&self,
611+
room_id: &RoomId,
612+
state_key: &K,
613+
) -> Option<StrippedStateEvent<C::PossiblyRedacted>>
614+
where
615+
C: StaticEventContent + StaticStateEventContent + RedactContent,
616+
C::Redacted: RedactedStateEventContent,
617+
C::PossiblyRedacted: DeserializeOwned,
618+
C::StateKey: Borrow<K>,
619+
K: AsRef<str> + ?Sized,
620+
{
621+
self.state_static_for_key::<C, K>(room_id, state_key)
622+
.map(Raw::cast_ref)
623+
.or_else(|| self.stripped_state_static_for_key::<C, K>(room_id, state_key))?
624+
.deserialize()
625+
.ok()
626+
}
627+
628+
/// Get the member for the given user in the given room from an event
629+
/// contained in these `StateChanges`, if any.
630+
pub(crate) fn member(
631+
&self,
632+
room_id: &RoomId,
633+
user_id: &UserId,
634+
) -> Option<StrippedRoomMemberEvent> {
635+
self.any_state_static_for_key::<RoomMemberEventContent, _>(room_id, user_id)
636+
}
637+
638+
/// Get the power levels for the given room from an event contained in these
639+
/// `StateChanges`, if any.
640+
pub(crate) fn power_levels(&self, room_id: &RoomId) -> Option<RoomPowerLevels> {
641+
Some(
642+
self.any_state_static_for_key::<RoomPowerLevelsEventContent, _>(
643+
room_id,
644+
&EmptyStateKey,
645+
)?
646+
.power_levels(),
647+
)
648+
}
559649
}
560650

561651
/// Configuration for the various stores.

0 commit comments

Comments
 (0)