mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-04 22:15:44 -04:00
refactor(base): Create the state_events::collect_* response processors.
This patch creates the `state_events::collect_sync` and `collect_stripped` response processors. It removes the `BaseClient::deserialize_state_events` and `deserialize_stripped_state_events` methods. It also removes a couple of `Vec` allocations and a couple of clones.
This commit is contained in:
@@ -636,19 +636,19 @@ impl BaseClient {
|
||||
&self,
|
||||
context: &mut Context,
|
||||
room: &Room,
|
||||
events: &[(Raw<AnyStrippedStateEvent>, AnyStrippedStateEvent)],
|
||||
events: (Vec<Raw<AnyStrippedStateEvent>>, Vec<AnyStrippedStateEvent>),
|
||||
push_rules: &Ruleset,
|
||||
room_info: &mut RoomInfo,
|
||||
notifications: &mut BTreeMap<OwnedRoomId, Vec<Notification>>,
|
||||
) -> Result<()> {
|
||||
let mut state_events = BTreeMap::new();
|
||||
|
||||
for (raw_event, event) in events {
|
||||
room_info.handle_stripped_state_event(event);
|
||||
for (raw_event, event) in events.0.into_iter().zip(events.1.into_iter()) {
|
||||
room_info.handle_stripped_state_event(&event);
|
||||
state_events
|
||||
.entry(event.event_type())
|
||||
.or_insert_with(BTreeMap::new)
|
||||
.insert(event.state_key().to_owned(), raw_event.clone());
|
||||
.insert(event.state_key().to_owned(), raw_event);
|
||||
}
|
||||
|
||||
context
|
||||
@@ -1018,9 +1018,8 @@ impl BaseClient {
|
||||
room_info.mark_state_fully_synced();
|
||||
room_info.handle_encryption_state(requested_required_states.for_room(&room_id));
|
||||
|
||||
let state_events = Self::deserialize_state_events(&new_info.state.events);
|
||||
let (raw_state_events, state_events): (Vec<_>, Vec<_>) =
|
||||
state_events.into_iter().unzip();
|
||||
let (raw_state_events, state_events) =
|
||||
processors::state_events::collect_sync(&mut context, &new_info.state.events);
|
||||
|
||||
let mut new_user_ids = self
|
||||
.handle_state(
|
||||
@@ -1128,9 +1127,8 @@ impl BaseClient {
|
||||
room_info.mark_state_partially_synced();
|
||||
room_info.handle_encryption_state(requested_required_states.for_room(&room_id));
|
||||
|
||||
let state_events = Self::deserialize_state_events(&new_info.state.events);
|
||||
let (raw_state_events, state_events): (Vec<_>, Vec<_>) =
|
||||
state_events.into_iter().unzip();
|
||||
let (raw_state_events, state_events) =
|
||||
processors::state_events::collect_sync(&mut context, &new_info.state.events);
|
||||
|
||||
let mut user_ids = self
|
||||
.handle_state(
|
||||
@@ -1184,8 +1182,10 @@ impl BaseClient {
|
||||
self.room_info_notable_update_sender.clone(),
|
||||
);
|
||||
|
||||
let invite_state =
|
||||
Self::deserialize_stripped_state_events(&new_info.invite_state.events);
|
||||
let invite_state = processors::state_events::collect_stripped(
|
||||
&mut context,
|
||||
&new_info.invite_state.events,
|
||||
);
|
||||
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_as_invited();
|
||||
@@ -1194,7 +1194,7 @@ impl BaseClient {
|
||||
self.handle_invited_state(
|
||||
&mut context,
|
||||
&room,
|
||||
&invite_state,
|
||||
invite_state,
|
||||
&push_rules,
|
||||
&mut room_info,
|
||||
&mut notifications,
|
||||
@@ -1213,7 +1213,10 @@ impl BaseClient {
|
||||
self.room_info_notable_update_sender.clone(),
|
||||
);
|
||||
|
||||
let knock_state = Self::deserialize_stripped_state_events(&new_info.knock_state.events);
|
||||
let knock_state = processors::state_events::collect_stripped(
|
||||
&mut context,
|
||||
&new_info.knock_state.events,
|
||||
);
|
||||
|
||||
let mut room_info = room.clone_info();
|
||||
room_info.mark_as_knocked();
|
||||
@@ -1222,7 +1225,7 @@ impl BaseClient {
|
||||
self.handle_invited_state(
|
||||
&mut context,
|
||||
&room,
|
||||
&knock_state,
|
||||
knock_state,
|
||||
&push_rules,
|
||||
&mut room_info,
|
||||
&mut notifications,
|
||||
@@ -1666,36 +1669,6 @@ impl BaseClient {
|
||||
self.ignore_user_list_changes.subscribe()
|
||||
}
|
||||
|
||||
pub(crate) fn deserialize_state_events(
|
||||
raw_events: &[Raw<AnySyncStateEvent>],
|
||||
) -> Vec<(Raw<AnySyncStateEvent>, AnySyncStateEvent)> {
|
||||
raw_events
|
||||
.iter()
|
||||
.filter_map(|raw_event| match raw_event.deserialize() {
|
||||
Ok(event) => Some((raw_event.clone(), event)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't deserialize state event: {e}");
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn deserialize_stripped_state_events(
|
||||
raw_events: &[Raw<AnyStrippedStateEvent>],
|
||||
) -> Vec<(Raw<AnyStrippedStateEvent>, AnyStrippedStateEvent)> {
|
||||
raw_events
|
||||
.iter()
|
||||
.filter_map(|raw_event| match raw_event.deserialize() {
|
||||
Ok(event) => Some((raw_event.clone(), event)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't deserialize stripped state event: {e}");
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Returns a new receiver that gets future room info notable updates.
|
||||
///
|
||||
/// Learn more by reading the [`RoomInfoNotableUpdate`] type.
|
||||
|
||||
@@ -19,6 +19,7 @@ pub mod e2ee;
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub mod latest_event;
|
||||
pub mod profiles;
|
||||
pub mod state_events;
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
pub mod verification;
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2025 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use ruma::{
|
||||
events::{AnyStrippedStateEvent, AnySyncStateEvent},
|
||||
serde::Raw,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use tracing::warn;
|
||||
|
||||
use super::Context;
|
||||
|
||||
pub fn collect_sync(
|
||||
_context: &mut Context,
|
||||
raw_events: &[Raw<AnySyncStateEvent>],
|
||||
) -> (Vec<Raw<AnySyncStateEvent>>, Vec<AnySyncStateEvent>) {
|
||||
collect(raw_events)
|
||||
}
|
||||
|
||||
pub fn collect_stripped(
|
||||
_context: &mut Context,
|
||||
raw_events: &[Raw<AnyStrippedStateEvent>],
|
||||
) -> (Vec<Raw<AnyStrippedStateEvent>>, Vec<AnyStrippedStateEvent>) {
|
||||
collect(raw_events)
|
||||
}
|
||||
|
||||
fn collect<'a, T>(raw_events: &'a [Raw<T>]) -> (Vec<Raw<T>>, Vec<T>)
|
||||
where
|
||||
T: Deserialize<'a>,
|
||||
{
|
||||
raw_events
|
||||
.iter()
|
||||
.filter_map(|raw_event| match raw_event.deserialize() {
|
||||
Ok(event) => Some((raw_event.clone(), event)),
|
||||
Err(e) => {
|
||||
warn!("Couldn't deserialize stripped state event: {e}");
|
||||
None
|
||||
}
|
||||
})
|
||||
.unzip()
|
||||
}
|
||||
@@ -363,32 +363,28 @@ impl BaseClient {
|
||||
Option<InvitedRoom>,
|
||||
Option<KnockedRoom>,
|
||||
)> {
|
||||
let (raw_state_events, state_events): (Vec<_>, Vec<_>) = {
|
||||
// Read state events from the `required_state` field.
|
||||
let state_events = Self::deserialize_state_events(&room_data.required_state);
|
||||
|
||||
// Don't read state events from the `timeline` field, because they might be
|
||||
// incomplete or staled already. We must only read state events from
|
||||
// `required_state`.
|
||||
|
||||
state_events.into_iter().unzip()
|
||||
};
|
||||
// Read state events from the `required_state` field.
|
||||
//
|
||||
// Don't read state events from the `timeline` field, because they might be
|
||||
// incomplete or staled already. We must only read state events from
|
||||
// `required_state`.
|
||||
let (raw_state_events, state_events) =
|
||||
processors::state_events::collect_sync(context, &room_data.required_state);
|
||||
|
||||
// Find or create the room in the store
|
||||
let is_new_room = !state_store.room_exists(room_id);
|
||||
|
||||
let stripped_state: Option<Vec<(Raw<AnyStrippedStateEvent>, AnyStrippedStateEvent)>> =
|
||||
room_data
|
||||
.invite_state
|
||||
.as_ref()
|
||||
.map(|invite_state| Self::deserialize_stripped_state_events(invite_state));
|
||||
let stripped_state = room_data
|
||||
.invite_state
|
||||
.as_ref()
|
||||
.map(|invite_state| processors::state_events::collect_stripped(context, invite_state));
|
||||
|
||||
#[allow(unused_mut)] // Required for some feature flag combinations
|
||||
let (mut room, mut room_info, invited_room, knocked_room) = self
|
||||
.process_sliding_sync_room_membership(
|
||||
context,
|
||||
&state_events,
|
||||
stripped_state.as_ref(),
|
||||
&stripped_state,
|
||||
state_store,
|
||||
user_id,
|
||||
room_id,
|
||||
@@ -413,7 +409,7 @@ impl BaseClient {
|
||||
let push_rules = self.get_push_rules(account_data_processor).await?;
|
||||
|
||||
// This will be used for both invited and knocked rooms.
|
||||
if let Some(invite_state) = &stripped_state {
|
||||
if let Some(invite_state) = stripped_state {
|
||||
self.handle_invited_state(
|
||||
context,
|
||||
&room,
|
||||
@@ -524,7 +520,7 @@ impl BaseClient {
|
||||
&self,
|
||||
context: &mut processors::Context,
|
||||
state_events: &[AnySyncStateEvent],
|
||||
stripped_state: Option<&Vec<(Raw<AnyStrippedStateEvent>, AnyStrippedStateEvent)>>,
|
||||
stripped_state: &Option<(Vec<Raw<AnyStrippedStateEvent>>, Vec<AnyStrippedStateEvent>)>,
|
||||
store: &BaseStateStore,
|
||||
user_id: &UserId,
|
||||
room_id: &RoomId,
|
||||
@@ -539,7 +535,7 @@ impl BaseClient {
|
||||
|
||||
// We need to find the membership event since it could be for either an invited
|
||||
// or knocked room
|
||||
let membership_event_content = stripped_state.iter().find_map(|(_, event)| {
|
||||
let membership_event_content = stripped_state.1.iter().find_map(|event| {
|
||||
if let AnyStrippedStateEvent::RoomMember(membership_event) = event {
|
||||
if membership_event.state_key == user_id {
|
||||
return Some(membership_event.content.clone());
|
||||
@@ -552,7 +548,7 @@ impl BaseClient {
|
||||
if membership_event_content.membership == MembershipState::Knock {
|
||||
// If we have a `Knock` membership state, set the room as such
|
||||
room_info.mark_as_knocked();
|
||||
let raw_events = stripped_state.iter().map(|(raw, _)| raw.clone()).collect();
|
||||
let raw_events = stripped_state.0.clone();
|
||||
let knock_state = assign!(v3::KnockState::default(), { events: raw_events });
|
||||
let knocked_room =
|
||||
assign!(KnockedRoom::default(), { knock_state: knock_state });
|
||||
@@ -562,7 +558,7 @@ impl BaseClient {
|
||||
|
||||
// Otherwise assume it's an invited room
|
||||
room_info.mark_as_invited();
|
||||
let raw_events = stripped_state.iter().map(|(raw, _)| raw.clone()).collect::<Vec<_>>();
|
||||
let raw_events = stripped_state.0.clone();
|
||||
let invited_room = InvitedRoom::from(v3::InviteState::from(raw_events));
|
||||
(room, room_info, Some(invited_room), None)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user