1// Copyright 2025 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
1415use std::collections::BTreeMap;
1617use ruma::{
18 push::{Action, PushConditionRoomCtx, Ruleset},
19 serde::Raw,
20 OwnedRoomId, RoomId,
21};
2223use crate::{
24 deserialized_responses::RawAnySyncOrStrippedTimelineEvent, store::BaseStateStore, sync,
25};
2627/// A classical set of data used by some processors dealing with notifications
28/// and push rules.
29pub struct Notification<'a> {
30pub push_rules: &'a Ruleset,
31pub notifications: &'a mut BTreeMap<OwnedRoomId, Vec<sync::Notification>>,
32pub state_store: &'a BaseStateStore,
33}
3435impl<'a> Notification<'a> {
36pub fn new(
37 push_rules: &'a Ruleset,
38 notifications: &'a mut BTreeMap<OwnedRoomId, Vec<sync::Notification>>,
39 state_store: &'a BaseStateStore,
40 ) -> Self {
41Self { push_rules, notifications, state_store }
42 }
4344fn push_notification(
45&mut self,
46 room_id: &RoomId,
47 actions: Vec<Action>,
48 event: RawAnySyncOrStrippedTimelineEvent,
49 ) {
50self.notifications
51 .entry(room_id.to_owned())
52 .or_default()
53 .push(sync::Notification { actions, event });
54 }
5556/// Push a new [`sync::Notification`] in [`Self::notifications`] from
57 /// `event` if and only if `predicate` returns `true` for at least one of
58 /// the [`Action`]s associated to this event and this
59 /// `push_condition_room_ctx`. (based on `Self::push_rules`).
60 ///
61 /// This method returns the fetched [`Action`]s.
62pub fn push_notification_from_event_if<E, P>(
63&mut self,
64 room_id: &RoomId,
65 push_condition_room_ctx: &PushConditionRoomCtx,
66 event: &Raw<E>,
67 predicate: P,
68 ) -> &[Action]
69where
70Raw<E>: Into<RawAnySyncOrStrippedTimelineEvent>,
71 P: Fn(&Action) -> bool,
72 {
73let actions = self.push_rules.get_actions(event, push_condition_room_ctx);
7475if actions.iter().any(predicate) {
76self.push_notification(room_id, actions.to_owned(), event.clone().into());
77 }
7879 actions
80 }
81}