@@ -28,14 +28,14 @@ use ruma::{
2828 assign,
2929 events:: {
3030 AnyMessageLikeEventContent , AnyStateEventContent , AnySyncMessageLikeEvent ,
31- AnySyncStateEvent , AnySyncTimelineEvent , AnyTimelineEvent , AnyToDeviceEvent ,
32- AnyToDeviceEventContent , MessageLikeEventType , StateEventType , TimelineEventType ,
33- ToDeviceEventType ,
31+ AnySyncStateEvent , AnyTimelineEvent , AnyToDeviceEvent , AnyToDeviceEventContent ,
32+ MessageLikeEventType , StateEventType , TimelineEventType , ToDeviceEventType ,
3433 } ,
3534 serde:: { from_raw_json_value, Raw } ,
3635 to_device:: DeviceIdOrAllDevices ,
37- EventId , OwnedUserId , RoomId , TransactionId ,
36+ EventId , OwnedRoomId , OwnedUserId , TransactionId ,
3837} ;
38+ use serde:: { Deserialize , Serialize } ;
3939use serde_json:: { value:: RawValue as RawJsonValue , Value } ;
4040use tokio:: sync:: mpsc:: { unbounded_channel, UnboundedReceiver } ;
4141use tracing:: error;
@@ -89,11 +89,14 @@ impl MatrixDriver {
8989 ) -> Result < Vec < Raw < AnyTimelineEvent > > > {
9090 let room_id = self . room . room_id ( ) ;
9191 let convert = |sync_or_stripped_state| match sync_or_stripped_state {
92- RawAnySyncOrStrippedState :: Sync ( ev) => with_attached_room_id ( ev. cast_ref ( ) , room_id)
93- . map_err ( |e| {
94- error ! ( "failed to convert event from `get_state_event` response:{}" , e)
95- } )
96- . ok ( ) ,
92+ RawAnySyncOrStrippedState :: Sync ( ev) => {
93+ add_props_to_raw ( & ev, Some ( room_id. to_owned ( ) ) , None )
94+ . map ( Raw :: cast)
95+ . map_err ( |e| {
96+ error ! ( "failed to convert event from `get_state_event` response:{}" , e)
97+ } )
98+ . ok ( )
99+ }
97100 RawAnySyncOrStrippedState :: Stripped ( _) => {
98101 error ! ( "MatrixDriver can't operate in invited rooms" ) ;
99102 None
@@ -197,9 +200,9 @@ impl MatrixDriver {
197200 let _room_id = room_id. clone ( ) ;
198201 let handle_msg_like =
199202 self . room . add_event_handler ( move |raw : Raw < AnySyncMessageLikeEvent > | {
200- match with_attached_room_id ( raw. cast_ref ( ) , & _room_id ) {
203+ match add_props_to_raw ( & raw , Some ( _room_id ) , None ) {
201204 Ok ( event_with_room_id) => {
202- let _ = _tx. send ( event_with_room_id) ;
205+ let _ = _tx. send ( event_with_room_id. cast ( ) ) ;
203206 }
204207 Err ( e) => {
205208 error ! ( "Failed to attach room id to message like event: {}" , e) ;
@@ -212,9 +215,9 @@ impl MatrixDriver {
212215 let _tx = tx;
213216 // Get only all state events from the state section of the sync.
214217 let handle_state = self . room . add_event_handler ( move |raw : Raw < AnySyncStateEvent > | {
215- match with_attached_room_id ( raw. cast_ref ( ) , & _room_id ) {
218+ match add_props_to_raw ( & raw , Some ( _room_id . to_owned ( ) ) , None ) {
216219 Ok ( event_with_room_id) => {
217- let _ = _tx. send ( event_with_room_id) ;
220+ let _ = _tx. send ( event_with_room_id. cast ( ) ) ;
218221 }
219222 Err ( e) => {
220223 error ! ( "Failed to attach room id to state event: {}" , e) ;
@@ -240,7 +243,7 @@ impl MatrixDriver {
240243
241244 let to_device_handle = self . room . client ( ) . add_event_handler (
242245 move |raw : Raw < AnyToDeviceEvent > , encryption_info : Option < EncryptionInfo > | {
243- match with_attached_encryption_flag ( raw, & encryption_info) {
246+ match add_props_to_raw ( & raw , None , encryption_info. as_ref ( ) ) {
244247 Ok ( ev) => {
245248 let _ = tx. send ( ev) ;
246249 }
@@ -296,35 +299,40 @@ impl<T> EventReceiver<T> {
296299 }
297300}
298301
299- /// Attach a room id to the event. This is needed because the widget API
300- /// requires the room id to be present in the event.
301-
302- fn with_attached_room_id (
303- raw : & Raw < AnySyncTimelineEvent > ,
304- room_id : & RoomId ,
305- ) -> Result < Raw < AnyTimelineEvent > > {
306- // This is the only modification we need to do to the events otherwise they are
307- // just forwarded raw to the widget.
308- // This is why we do the serialization dance here to allow the optimization of
309- // using `BTreeMap<String, Box<RawJsonValue>` instead of serializing the full event.
310- match raw. deserialize_as :: < BTreeMap < String , Box < RawJsonValue > > > ( ) {
311- Ok ( mut ev_mut) => {
312- ev_mut. insert ( "room_id" . to_owned ( ) , serde_json:: value:: to_raw_value ( room_id) ?) ;
313- Ok ( Raw :: new ( & ev_mut) ?. cast ( ) )
314- }
315- Err ( e) => Err ( Error :: from ( e) ) ,
316- }
302+ // `room_id` and `encryption` is the only modification we need to do to the
303+ // events otherwise they are just forwarded raw to the widget.
304+ // This is why we do not serialization the whole event but pass it as a raw
305+ // value through the widget driver and only serialize here to allow potimizing
306+ // with `serde(borrow)`.
307+ #[ derive( Deserialize , Serialize ) ]
308+ struct RoomIdEncryptionSerializer < ' a > {
309+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
310+ room_id : Option < OwnedRoomId > ,
311+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
312+ encrypted : Option < bool > ,
313+ #[ serde( flatten, borrow) ]
314+ rest : & ' a RawJsonValue ,
317315}
318316
319- fn with_attached_encryption_flag (
320- raw : Raw < AnyToDeviceEvent > ,
321- encryption_info : & Option < EncryptionInfo > ,
322- ) -> Result < Raw < AnyToDeviceEvent > > {
323- match raw. deserialize_as :: < BTreeMap < String , Box < RawJsonValue > > > ( ) {
324- Ok ( mut ev_mut) => {
325- let encrypted = encryption_info. is_some ( ) ;
326- ev_mut. insert ( "encrypted" . to_owned ( ) , serde_json:: value:: to_raw_value ( & encrypted) ?) ;
327- Ok ( Raw :: new ( & ev_mut) ?. cast ( ) )
317+ /// Attach additional properties to the event.
318+ ///
319+ /// Attach a room id to the event. This is needed because the widget API
320+ /// requires the room id to be present in the event.
321+ ///
322+ /// Attach the `ecryption` flag to the event. This is needed so the widget gets
323+ /// informed if an event is encrypted or not. Since the client is responsible
324+ /// for decrypting the event, there otherwise is no way for the widget to know
325+ /// if its an encrypted (signed/trusted) event or not.
326+ fn add_props_to_raw < T > (
327+ raw : & Raw < T > ,
328+ room_id : Option < OwnedRoomId > ,
329+ encryption_info : Option < & EncryptionInfo > ,
330+ ) -> Result < Raw < T > > {
331+ match raw. deserialize_as :: < RoomIdEncryptionSerializer < ' _ > > ( ) {
332+ Ok ( mut event) => {
333+ event. room_id = room_id. or ( event. room_id ) ;
334+ event. encrypted = encryption_info. map ( |_| true ) . or ( event. encrypted ) ;
335+ Ok ( Raw :: new ( & event) ?. cast ( ) )
328336 }
329337 Err ( e) => Err ( Error :: from ( e) ) ,
330338 }
0 commit comments