@@ -22,7 +22,7 @@ use serde::{ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer}
2222use tracing:: { debug, warn} ;
2323
2424use super :: {
25- filter:: { Filter , FilterInput } ,
25+ filter:: { Filter , FilterInput , ToDeviceEventFilter } ,
2626 MessageLikeEventFilter , StateEventFilter ,
2727} ;
2828
@@ -60,7 +60,7 @@ pub struct Capabilities {
6060impl Capabilities {
6161 /// Checks if a given 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 < ' a > (
@@ -78,7 +78,7 @@ impl Capabilities {
7878
7979 /// Checks if a given event is allowed to be sent by the widget.
8080 ///
81- /// - `event_filter_input` is a minimized event respresntation that contains
81+ /// - `event_filter_input` is a minimized event representation that contains
8282 /// only the information needed to check if the widget is allowed to send
8383 /// the event to a matrix room. (See [`FilterInput`])
8484 pub ( super ) fn allow_sending < ' a > (
@@ -102,11 +102,13 @@ impl Capabilities {
102102 }
103103}
104104
105- const SEND_EVENT : & str = "org.matrix.msc2762.send.event" ;
106- const READ_EVENT : & str = "org.matrix.msc2762.receive.event" ;
107- const SEND_STATE : & str = "org.matrix.msc2762.send.state_event" ;
108- const READ_STATE : & str = "org.matrix.msc2762.receive.state_event" ;
109- const REQUIRES_CLIENT : & str = "io.element.requires_client" ;
105+ pub ( super ) const SEND_EVENT : & str = "org.matrix.msc2762.send.event" ;
106+ pub ( super ) const READ_EVENT : & str = "org.matrix.msc2762.receive.event" ;
107+ pub ( super ) const SEND_STATE : & str = "org.matrix.msc2762.send.state_event" ;
108+ pub ( super ) const READ_STATE : & str = "org.matrix.msc2762.receive.state_event" ;
109+ pub ( super ) const SEND_TODEVICE : & str = "org.matrix.msc3819.send.to_device" ;
110+ pub ( super ) const READ_TODEVICE : & str = "org.matrix.msc3819.receive.to_device" ;
111+ pub ( super ) const REQUIRES_CLIENT : & str = "io.element.requires_client" ;
110112pub ( super ) const SEND_DELAYED_EVENT : & str = "org.matrix.msc4157.send.delayed_event" ;
111113pub ( super ) const UPDATE_DELAYED_EVENT : & str = "org.matrix.msc4157.update_delayed_event" ;
112114
@@ -121,6 +123,12 @@ impl Serialize for Capabilities {
121123 match self . 0 {
122124 Filter :: MessageLike ( filter) => PrintMessageLikeEventFilter ( filter) . fmt ( f) ,
123125 Filter :: State ( filter) => PrintStateEventFilter ( filter) . fmt ( f) ,
126+ Filter :: ToDevice ( filter) => {
127+ // As per MSC 3819 https://github.com/matrix-org/matrix-spec-proposals/pull/3819
128+ // ToDevice capabilities is in the form of `m.send.to_device:<event type>`
129+ // or `m.receive.to_device:<event type>`
130+ write ! ( f, "{}" , filter. event_type)
131+ }
124132 }
125133 }
126134 }
@@ -168,13 +176,15 @@ impl Serialize for Capabilities {
168176 let name = match filter {
169177 Filter :: MessageLike ( _) => READ_EVENT ,
170178 Filter :: State ( _) => READ_STATE ,
179+ Filter :: ToDevice ( _) => READ_TODEVICE ,
171180 } ;
172181 seq. serialize_element ( & format ! ( "{name}:{}" , PrintEventFilter ( filter) ) ) ?;
173182 }
174183 for filter in & self . send {
175184 let name = match filter {
176185 Filter :: MessageLike ( _) => SEND_EVENT ,
177186 Filter :: State ( _) => SEND_STATE ,
187+ Filter :: ToDevice ( _) => SEND_TODEVICE ,
178188 } ;
179189 seq. serialize_element ( & format ! ( "{name}:{}" , PrintEventFilter ( filter) ) ) ?;
180190 }
@@ -226,6 +236,12 @@ impl<'de> Deserialize<'de> for Capabilities {
226236 Some ( ( SEND_STATE , filter_s) ) => {
227237 Ok ( Permission :: Send ( Filter :: State ( parse_state_event_filter ( filter_s) ) ) )
228238 }
239+ Some ( ( READ_TODEVICE , filter_s) ) => Ok ( Permission :: Read ( Filter :: ToDevice (
240+ parse_to_device_event_filter ( filter_s) ,
241+ ) ) ) ,
242+ Some ( ( SEND_TODEVICE , filter_s) ) => Ok ( Permission :: Send ( Filter :: ToDevice (
243+ parse_to_device_event_filter ( filter_s) ,
244+ ) ) ) ,
229245 _ => {
230246 debug ! ( "Unknown capability `{s}`" ) ;
231247 Ok ( Self :: Unknown )
@@ -252,6 +268,10 @@ impl<'de> Deserialize<'de> for Capabilities {
252268 }
253269 }
254270
271+ fn parse_to_device_event_filter ( s : & str ) -> ToDeviceEventFilter {
272+ ToDeviceEventFilter :: new ( s. into ( ) )
273+ }
274+
255275 let mut capabilities = Capabilities :: default ( ) ;
256276 for capability in Vec :: < Permission > :: deserialize ( deserializer) ? {
257277 match capability {
@@ -274,6 +294,7 @@ mod tests {
274294 use ruma:: events:: StateEventType ;
275295
276296 use super :: * ;
297+ use crate :: widget:: filter:: ToDeviceEventFilter ;
277298
278299 #[ test]
279300 fn deserialization_of_no_capabilities ( ) {
@@ -293,8 +314,10 @@ mod tests {
293314 "org.matrix.msc2762.receive.event:org.matrix.rageshake_request",
294315 "org.matrix.msc2762.receive.state_event:m.room.member",
295316 "org.matrix.msc2762.receive.state_event:org.matrix.msc3401.call.member",
317+ "org.matrix.msc3819.receive.to_device:io.element.call.encryption_keys",
296318 "org.matrix.msc2762.send.event:org.matrix.rageshake_request",
297319 "org.matrix.msc2762.send.state_event:org.matrix.msc3401.call.member#@user:matrix.server",
320+ "org.matrix.msc3819.send.to_device:io.element.call.encryption_keys",
298321 "org.matrix.msc4157.send.delayed_event",
299322 "org.matrix.msc4157.update_delayed_event"
300323 ]"# ;
@@ -307,6 +330,9 @@ mod tests {
307330 ) ) ,
308331 Filter :: State ( StateEventFilter :: WithType ( StateEventType :: RoomMember ) ) ,
309332 Filter :: State ( StateEventFilter :: WithType ( "org.matrix.msc3401.call.member" . into( ) ) ) ,
333+ Filter :: ToDevice ( ToDeviceEventFilter :: new(
334+ "io.element.call.encryption_keys" . into( ) ,
335+ ) ) ,
310336 ] ,
311337 send : vec ! [
312338 Filter :: MessageLike ( MessageLikeEventFilter :: WithType (
@@ -316,6 +342,9 @@ mod tests {
316342 "org.matrix.msc3401.call.member" . into( ) ,
317343 "@user:matrix.server" . into( ) ,
318344 ) ) ,
345+ Filter :: ToDevice ( ToDeviceEventFilter :: new(
346+ "io.element.call.encryption_keys" . into( ) ,
347+ ) ) ,
319348 ] ,
320349 requires_client : true ,
321350 update_delayed_event : true ,
@@ -335,13 +364,17 @@ mod tests {
335364 "org.matrix.msc3401.call.member" . into( ) ,
336365 "@user:matrix.server" . into( ) ,
337366 ) ) ,
367+ Filter :: ToDevice ( ToDeviceEventFilter :: new(
368+ "io.element.call.encryption_keys" . into( ) ,
369+ ) ) ,
338370 ] ,
339371 send : vec ! [
340372 Filter :: MessageLike ( MessageLikeEventFilter :: WithType ( "io.element.custom" . into( ) ) ) ,
341373 Filter :: State ( StateEventFilter :: WithTypeAndStateKey (
342374 "org.matrix.msc3401.call.member" . into( ) ,
343375 "@user:matrix.server" . into( ) ,
344376 ) ) ,
377+ Filter :: ToDevice ( ToDeviceEventFilter :: new( "my.org.other.to_device_event" . into( ) ) ) ,
345378 ] ,
346379 requires_client : true ,
347380 update_delayed_event : false ,
0 commit comments