matrix_sdk_base/response_processors/
notification.rs

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.
14
15use std::collections::BTreeMap;
16
17use ruma::{
18    push::{Action, PushConditionRoomCtx, Ruleset},
19    serde::Raw,
20    OwnedRoomId, RoomId,
21};
22
23use crate::{
24    deserialized_responses::RawAnySyncOrStrippedTimelineEvent, store::BaseStateStore, sync,
25};
26
27/// A classical set of data used by some processors dealing with notifications
28/// and push rules.
29pub struct Notification<'a> {
30    pub push_rules: &'a Ruleset,
31    pub notifications: &'a mut BTreeMap<OwnedRoomId, Vec<sync::Notification>>,
32    pub state_store: &'a BaseStateStore,
33}
34
35impl<'a> Notification<'a> {
36    pub fn new(
37        push_rules: &'a Ruleset,
38        notifications: &'a mut BTreeMap<OwnedRoomId, Vec<sync::Notification>>,
39        state_store: &'a BaseStateStore,
40    ) -> Self {
41        Self { push_rules, notifications, state_store }
42    }
43
44    fn push_notification(
45        &mut self,
46        room_id: &RoomId,
47        actions: Vec<Action>,
48        event: RawAnySyncOrStrippedTimelineEvent,
49    ) {
50        self.notifications
51            .entry(room_id.to_owned())
52            .or_default()
53            .push(sync::Notification { actions, event });
54    }
55
56    /// 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.
62    pub 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]
69    where
70        Raw<E>: Into<RawAnySyncOrStrippedTimelineEvent>,
71        P: Fn(&Action) -> bool,
72    {
73        let actions = self.push_rules.get_actions(event, push_condition_room_ctx);
74
75        if actions.iter().any(predicate) {
76            self.push_notification(room_id, actions.to_owned(), event.clone().into());
77        }
78
79        actions
80    }
81}