From fed52d24e448cc01848724eceb74735134505b39 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 29 Sep 2025 19:54:57 +0000 Subject: [PATCH] Implement additional Matches for RoomFilter and Filter. Apply filter for rooms/not_rooms; sender filter for presence. Signed-off-by: Jason Volk --- src/api/client/sync/v3.rs | 11 ++++-- src/core/matrix/event/filter.rs | 65 +++++++++++++++++++++++++++++++-- 2 files changed, 69 insertions(+), 7 deletions(-) diff --git a/src/api/client/sync/v3.rs b/src/api/client/sync/v3.rs index 0e1a27f2..9133aa08 100644 --- a/src/api/client/sync/v3.rs +++ b/src/api/client/sync/v3.rs @@ -243,6 +243,7 @@ async fn build_sync_events( let joined_rooms = services .state_cache .rooms_joined(sender_user) + .ready_filter(|&room_id| filter.room.matches(room_id)) .map(ToOwned::to_owned) .broad_filter_map(|room_id| { load_joined_room( @@ -275,6 +276,7 @@ async fn build_sync_events( let left_rooms = services .state_cache .rooms_left(sender_user) + .ready_filter(|(room_id, _)| filter.room.matches(room_id)) .broad_filter_map(|(room_id, _)| { handle_left_room( services, @@ -294,6 +296,7 @@ async fn build_sync_events( let invited_rooms = services .state_cache .rooms_invited(sender_user) + .ready_filter(|(room_id, _)| filter.room.matches(room_id)) .fold_default(async |mut invited_rooms: BTreeMap<_, _>, (room_id, invite_state)| { let invite_count = services .state_cache @@ -317,6 +320,7 @@ async fn build_sync_events( let knocked_rooms = services .state_cache .rooms_knocked(sender_user) + .ready_filter(|(room_id, _)| filter.room.matches(room_id)) .fold_default(async |mut knocked_rooms: BTreeMap<_, _>, (room_id, knock_state)| { let knock_count = services .state_cache @@ -340,7 +344,7 @@ async fn build_sync_events( let presence_updates: OptionFuture<_> = services .config .allow_local_presence - .then(|| process_presence_updates(services, since, next_batch, sender_user)) + .then(|| process_presence_updates(services, since, next_batch, sender_user, &filter)) .into(); let account_data = services @@ -443,10 +447,12 @@ async fn process_presence_updates( since: u64, next_batch: u64, syncing_user: &UserId, + filter: &FilterDefinition, ) -> PresenceUpdates { services .presence .presence_since(since, Some(next_batch)) + .ready_filter(|(user_id, ..)| filter.presence.matches(user_id)) .filter(|(user_id, ..)| { services .state_cache @@ -461,6 +467,7 @@ async fn process_presence_updates( }) .map(|(user_id, event)| (user_id.to_owned(), event.content)) .collect() + .boxed() .await } @@ -797,7 +804,6 @@ async fn load_joined_room( join(encrypted_room, associate_token), join(last_privateread_update, last_notification_read), ) - .boxed() .await; let joined_since_last_sync = @@ -1127,7 +1133,6 @@ async fn calculate_state_changes<'a>( services.timeline.get_pdu(&event_id).ok().await }) .collect::>() - .boxed() .await; let send_member_counts = state_events diff --git a/src/core/matrix/event/filter.rs b/src/core/matrix/event/filter.rs index ef4660b6..caee4efb 100644 --- a/src/core/matrix/event/filter.rs +++ b/src/core/matrix/event/filter.rs @@ -1,14 +1,17 @@ -use ruma::api::client::filter::{RoomEventFilter, UrlFilter}; +use ruma::{ + RoomId, UserId, + api::client::filter::{Filter, RoomEventFilter, RoomFilter, UrlFilter}, +}; use serde_json::Value; use super::Event; use crate::is_equal_to; -pub trait Matches { - fn matches(&self, event: &E) -> bool; +pub trait Matches { + fn matches(&self, t: T) -> bool; } -impl Matches for &RoomEventFilter { +impl Matches<&E> for RoomEventFilter { #[inline] fn matches(&self, event: &E) -> bool { if !matches_sender(event, self) { @@ -31,6 +34,60 @@ impl Matches for &RoomEventFilter { } } +impl Matches<&RoomId> for RoomFilter { + #[inline] + fn matches(&self, room_id: &RoomId) -> bool { + if !matches_room_id(room_id, self) { + return false; + } + + true + } +} + +impl Matches<&UserId> for Filter { + #[inline] + fn matches(&self, user_id: &UserId) -> bool { + if !matches_user_id(user_id, self) { + return false; + } + + true + } +} + +fn matches_user_id(user_id: &UserId, filter: &Filter) -> bool { + if filter + .not_senders + .iter() + .any(is_equal_to!(user_id)) + { + return false; + } + + if let Some(senders) = filter.senders.as_ref() { + if !senders.iter().any(is_equal_to!(user_id)) { + return false; + } + } + + true +} + +fn matches_room_id(room_id: &RoomId, filter: &RoomFilter) -> bool { + if filter.not_rooms.iter().any(is_equal_to!(room_id)) { + return false; + } + + if let Some(rooms) = filter.rooms.as_ref() { + if !rooms.iter().any(is_equal_to!(room_id)) { + return false; + } + } + + true +} + fn matches_room(event: &E, filter: &RoomEventFilter) -> bool { if filter .not_rooms