matrix_sdk/event_handler/
context.rs

1// Copyright 2021 Jonas Platte
2// Copyright 2022 Famedly GmbH
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use std::ops::Deref;
17
18use matrix_sdk_base::deserialized_responses::EncryptionInfo;
19use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm};
20use ruma::push::Action;
21use serde_json::value::RawValue as RawJsonValue;
22
23use super::{EventHandlerData, EventHandlerHandle};
24use crate::{Client, Room};
25
26/// Context for an event handler.
27///
28/// This trait defines the set of types that may be used as additional arguments
29/// in event handler functions after the event itself.
30pub trait EventHandlerContext: Sized {
31    #[doc(hidden)]
32    fn from_data(_: &EventHandlerData<'_>) -> Option<Self>;
33}
34
35impl EventHandlerContext for Client {
36    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
37        Some(data.client.clone())
38    }
39}
40
41impl EventHandlerContext for EventHandlerHandle {
42    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
43        Some(data.handle.clone())
44    }
45}
46
47/// This event handler context argument is only applicable to room-specific
48/// events.
49///
50/// Trying to use it in the event handler for another event, for example a
51/// global account data or presence event, will result in the event handler
52/// being skipped and an error getting logged.
53impl EventHandlerContext for Room {
54    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
55        data.room.clone()
56    }
57}
58
59/// The raw JSON form of an event.
60///
61/// Used as a context argument for event handlers (see
62/// [`Client::add_event_handler`]).
63#[derive(Clone, Debug)]
64pub struct RawEvent(pub Box<RawJsonValue>);
65
66impl Deref for RawEvent {
67    type Target = RawJsonValue;
68
69    fn deref(&self) -> &Self::Target {
70        &self.0
71    }
72}
73
74impl EventHandlerContext for RawEvent {
75    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
76        Some(Self(data.raw.to_owned()))
77    }
78}
79
80impl EventHandlerContext for Option<EncryptionInfo> {
81    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
82        Some(data.encryption_info.cloned())
83    }
84}
85
86impl EventHandlerContext for Vec<Action> {
87    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
88        Some(data.push_actions.to_owned())
89    }
90}
91
92/// A custom value registered with
93/// [`.add_event_handler_context`][Client::add_event_handler_context].
94#[derive(Debug)]
95pub struct Ctx<T>(pub T);
96
97impl<T: Clone + SendOutsideWasm + SyncOutsideWasm + 'static> EventHandlerContext for Ctx<T> {
98    fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
99        let map = data.client.inner.event_handlers.context.read().unwrap();
100        map.get::<T>().cloned().map(Ctx)
101    }
102}
103
104impl<T> Deref for Ctx<T> {
105    type Target = T;
106
107    fn deref(&self) -> &Self::Target {
108        &self.0
109    }
110}
111
112// `EventHandlerContext` for tuples.
113
114impl EventHandlerContext for () {
115    fn from_data(_data: &EventHandlerData<'_>) -> Option<Self> {
116        Some(())
117    }
118}
119
120macro_rules! impl_context_for_tuple {
121    ( $( $ty:ident ),* $(,)? ) => {
122        #[allow(non_snake_case)]
123        impl< $( $ty ),* > EventHandlerContext for ( $( $ty ),* , )
124        where
125            $( $ty : EventHandlerContext, )*
126        {
127            fn from_data(data: &EventHandlerData<'_>) -> Option<Self> {
128                $(
129                    let $ty = $ty ::from_data(data)?;
130                )*
131
132                Some(( $( $ty ),* , ))
133            }
134        }
135    };
136}
137
138impl_context_for_tuple!(A);
139impl_context_for_tuple!(A, B);
140impl_context_for_tuple!(A, B, C);
141impl_context_for_tuple!(A, B, C, D);
142impl_context_for_tuple!(A, B, C, D, E);
143impl_context_for_tuple!(A, B, C, D, E, F);
144impl_context_for_tuple!(A, B, C, D, E, F, G);
145impl_context_for_tuple!(A, B, C, D, E, F, G, H);