@@ -162,7 +162,10 @@ impl AnyDecryptedOlmEvent {
162162}
163163
164164/// An `m.olm.v1.curve25519-aes-sha2` decrypted to-device event.
165- #[ derive( Clone , Debug , Deserialize , Serialize ) ]
165+ ///
166+ /// **Note**: This event will reserialize events lossy, unknown fields will be
167+ /// lost during deserialization.
168+ #[ derive( Clone , Debug , Deserialize ) ]
166169pub struct DecryptedOlmV1Event < C >
167170where
168171 C : EventType + Debug + Sized + Serialize ,
@@ -182,6 +185,59 @@ where
182185 pub content : C ,
183186}
184187
188+ impl < C : EventType + Debug + Sized + Serialize > Serialize for DecryptedOlmV1Event < C > {
189+ /// A customized [`Serialize`] implementation that ensures that the
190+ /// `event_type` field is present in the serialized JSON.
191+ ///
192+ /// The `event_type` in the [`DecryptedOlmV1Event`] is omitted because the
193+ /// event type is expressed in the generic type `C`. To properly serialize
194+ /// the [`DecryptedOlmV1Event`] we'll must extract the event type from `C`
195+ /// and reintroduce it into the JSON field.
196+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
197+ where
198+ S : serde:: Serializer ,
199+ {
200+ #[ derive( Serialize ) ]
201+ struct DecryptedEventSerializationHelper < ' a , C : EventType + Debug + Sized + Serialize > {
202+ sender : & ' a UserId ,
203+ recipient : & ' a UserId ,
204+ keys : & ' a OlmV1Keys ,
205+ recipient_keys : & ' a OlmV1Keys ,
206+ #[ serde(
207+ rename = "org.matrix.msc4147.device_keys" ,
208+ skip_serializing_if = "Option::is_none"
209+ ) ]
210+ sender_device_keys : Option < & ' a DeviceKeys > ,
211+ content : & ' a C ,
212+ #[ serde( rename = "type" ) ]
213+ event_type : & ' a str ,
214+ }
215+
216+ let event_type = self . content . event_type ( ) ;
217+
218+ let DecryptedOlmV1Event {
219+ sender,
220+ recipient,
221+ keys,
222+ recipient_keys,
223+ sender_device_keys,
224+ content,
225+ } = & self ;
226+
227+ let event = DecryptedEventSerializationHelper {
228+ sender,
229+ recipient,
230+ keys,
231+ recipient_keys,
232+ sender_device_keys : sender_device_keys. as_ref ( ) ,
233+ content,
234+ event_type,
235+ } ;
236+
237+ event. serialize ( serializer)
238+ }
239+ }
240+
185241impl < C : EventType + Debug + Sized + Serialize > DecryptedOlmV1Event < C > {
186242 #[ cfg( test) ]
187243 /// Test helper to create a new [`DecryptedOlmV1Event`] with the given
@@ -269,6 +325,7 @@ mod tests {
269325 use assert_matches:: assert_matches;
270326 use ruma:: { device_id, owned_user_id, KeyId } ;
271327 use serde_json:: { json, Value } ;
328+ use similar_asserts:: assert_eq;
272329 use vodozemac:: { Curve25519PublicKey , Ed25519PublicKey , Ed25519Signature } ;
273330
274331 use super :: AnyDecryptedOlmEvent ;
@@ -298,7 +355,6 @@ mod tests {
298355 fn room_key_event ( ) -> Value {
299356 json ! ( {
300357 "sender" : "@alice:example.org" ,
301- "sender_device" : "DEVICEID" ,
302358 "keys" : {
303359 "ed25519" : ED25519_KEY ,
304360 } ,
@@ -513,4 +569,19 @@ mod tests {
513569 // Then it contains the sender_device_keys
514570 assert_eq ! ( event. sender_device_keys, Some ( sender_device_keys) ) ;
515571 }
572+
573+ #[ test]
574+ fn test_serialization_cycle ( ) {
575+ let event_json = room_key_event ( ) ;
576+ let event: DecryptedRoomKeyEvent = serde_json:: from_value ( event_json. clone ( ) )
577+ . expect ( "JSON should deserialize to the right event type" ) ;
578+
579+ let reserialized =
580+ serde_json:: to_value ( event) . expect ( "We should be able to serialize the event" ) ;
581+
582+ assert_eq ! (
583+ event_json, reserialized,
584+ "The reserialized JSON should match the original value"
585+ ) ;
586+ }
516587}
0 commit comments