Skip to content

Commit 29233b0

Browse files
committed
WidgetDriver: Introduce to-device filter.
A new widget filter is required to add support for to-device events. This allows to let the widget only send and receive to-device events it has negotiated capabilities for.
1 parent 9504745 commit 29233b0

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

crates/matrix-sdk/src/widget/capabilities.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub struct Capabilities {
6060
impl Capabilities {
6161
/// Checks if a givent event is allowed to be forwarded to the widget.
6262
///
63-
/// - `event_filter_input` is a minimized event respresntation that contains
63+
/// - `event_filter_input` is a minimized event representation that contains
6464
/// only the information needed to check if the widget is allowed to
6565
/// receive the event. (See [`FilterInput`])
6666
pub(super) fn allow_reading(&self, event_filter_input: &FilterInput) -> bool {
@@ -69,7 +69,7 @@ impl Capabilities {
6969

7070
/// Checks if a givent event is allowed to be sent by the widget.
7171
///
72-
/// - `event_filter_input` is a minimized event respresntation that contains
72+
/// - `event_filter_input` is a minimized event representation that contains
7373
/// only the information needed to check if the widget is allowed to send
7474
/// the event to a matrix room. (See [`FilterInput`])
7575
pub(super) fn allow_sending(&self, event_filter_input: &FilterInput) -> bool {
@@ -103,6 +103,7 @@ impl Serialize for Capabilities {
103103
match self.0 {
104104
Filter::MessageLike(filter) => PrintMessageLikeEventFilter(filter).fmt(f),
105105
Filter::State(filter) => PrintStateEventFilter(filter).fmt(f),
106+
Filter::ToDevice(filter) => filter.fmt(f),
106107
}
107108
}
108109
}

crates/matrix-sdk/src/widget/filter.rs

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::fmt;
16+
1517
use ruma::{
1618
events::{
17-
AnyMessageLikeEventContent, AnyTimelineEvent, MessageLikeEventType, StateEventType,
18-
TimelineEventType,
19+
AnyMessageLikeEventContent, AnyTimelineEvent, AnyToDeviceEvent, MessageLikeEventType,
20+
StateEventType, TimelineEventType, ToDeviceEventType,
1921
},
2022
serde::Raw,
2123
};
@@ -34,6 +36,8 @@ pub enum Filter {
3436
MessageLike(MessageLikeEventFilter),
3537
/// Filter for state events.
3638
State(StateEventFilter),
39+
/// Filter for to device events.
40+
ToDevice(ToDeviceEventFilter),
3741
}
3842

3943
impl Filter {
@@ -44,6 +48,7 @@ impl Filter {
4448
match self {
4549
Self::MessageLike(filter) => filter.matches(filter_input),
4650
Self::State(filter) => filter.matches(filter_input),
51+
Self::ToDevice(filter) => filter.matches(filter_input),
4752
}
4853
}
4954
/// Returns the event type that this filter is configured to match.
@@ -54,6 +59,7 @@ impl Filter {
5459
match self {
5560
Self::MessageLike(filter) => filter.filter_event_type(),
5661
Self::State(filter) => filter.filter_event_type(),
62+
Self::ToDevice(filter) => filter.event_type.to_string(),
5763
}
5864
}
5965
}
@@ -126,14 +132,43 @@ impl StateEventFilter {
126132
}
127133
}
128134

135+
/// Filter for to-device events.
136+
#[derive(Clone, Debug)]
137+
#[cfg_attr(test, derive(PartialEq))]
138+
pub struct ToDeviceEventFilter {
139+
/// The event type this to-device-filter filters for.
140+
pub event_type: ToDeviceEventType,
141+
}
142+
143+
impl ToDeviceEventFilter {
144+
/// Create a new `ToDeviceEventFilter` with the given event type.
145+
pub fn new(event_type: ToDeviceEventType) -> Self {
146+
Self { event_type }
147+
}
148+
}
149+
150+
impl ToDeviceEventFilter {
151+
fn matches(&self, filter_input: &FilterInput) -> bool {
152+
matches!(filter_input,FilterInput::ToDevice(f_in) if f_in.event_type == self.event_type)
153+
}
154+
}
155+
156+
impl fmt::Display for ToDeviceEventFilter {
157+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158+
write!(f, "{}", self.event_type)
159+
}
160+
}
161+
129162
// Filter input:
130163

131-
/// The input data for the filter. This can either be constructed from a
132-
/// [`Raw<AnyTimelineEvent>`] or a [`SendEventRequest`].
164+
/// The input data for the filter. This can be constructed from a
165+
/// [`Raw<AnyTimelineEvent>`], a [`SendEventRequest`] or a [`Raw<AnyToDeviceEvent>`]
166+
/// or using the FilterInput constructors.
133167
#[derive(Debug)]
134168
pub enum FilterInput {
135169
State(FilterInputState),
136170
MessageLike(FilterInputMessageLike),
171+
ToDevice(FilterInputToDevice),
137172
}
138173

139174
impl FilterInput {
@@ -207,6 +242,20 @@ impl TryFrom<Raw<AnyTimelineEvent>> for FilterInput {
207242
}
208243
}
209244

245+
#[derive(Debug, Deserialize)]
246+
pub struct FilterInputToDevice {
247+
#[serde(rename = "type")]
248+
pub(super) event_type: ToDeviceEventType,
249+
}
250+
251+
/// Create a filter input of type [`FilterInput::ToDevice`]`.
252+
impl TryFrom<Raw<AnyToDeviceEvent>> for FilterInput {
253+
type Error = serde_json::Error;
254+
fn try_from(raw_event: Raw<AnyToDeviceEvent>) -> Result<Self, Self::Error> {
255+
raw_event.deserialize_as::<FilterInputToDevice>().map(FilterInput::ToDevice)
256+
}
257+
}
258+
210259
impl From<&SendEventRequest> for FilterInput {
211260
fn from(request: &SendEventRequest) -> Self {
212261
match &request.state_key {
@@ -243,7 +292,9 @@ mod tests {
243292
use super::{
244293
Filter, FilterInput, FilterInputMessageLike, MessageLikeEventFilter, StateEventFilter,
245294
};
246-
use crate::widget::filter::MessageLikeFilterEventContent;
295+
use crate::widget::filter::{
296+
FilterInputToDevice, MessageLikeFilterEventContent, ToDeviceEventFilter,
297+
};
247298

248299
fn message_event(event_type: MessageLikeEventType) -> FilterInput {
249300
FilterInput::MessageLike(FilterInputMessageLike { event_type, content: Default::default() })
@@ -424,4 +475,12 @@ mod tests {
424475
assert!(!room_message_filter()
425476
.matches(&FilterInput::message_like(MessageLikeEventType::Reaction.to_string())));
426477
}
478+
479+
#[test]
480+
fn test_to_device_filter_does_match() {
481+
let f = Filter::ToDevice(ToDeviceEventFilter::new("my.custom.to.device".into()));
482+
assert!(f.matches(&FilterInput::ToDevice(FilterInputToDevice {
483+
event_type: "my.custom.to.device".into(),
484+
})));
485+
}
427486
}

0 commit comments

Comments
 (0)