Skip to main content

ruma_events/
enums.rs

1use ruma_common::{
2    EventId, MilliSecondsSinceUnixEpoch, OwnedRoomId, RoomId, TransactionId, UserId,
3    serde::{JsonCastable, from_raw_json_value},
4};
5#[cfg(feature = "unstable-msc3381")]
6use ruma_events::{
7    poll::{start::PollStartEventContent, unstable_start::UnstablePollStartEventContent},
8    room::encrypted::Replacement,
9};
10use ruma_macros::{EventEnumFromEvent, event_enum};
11use serde::{Deserialize, Serialize, de};
12use serde_json::value::RawValue as RawJsonValue;
13
14use super::room::encrypted;
15
16/// Event types that servers should send as [stripped state] to help clients identify a room when
17/// they can't access the full room state.
18///
19/// [stripped state]: https://spec.matrix.org/v1.19/client-server-api/#stripped-state
20pub const RECOMMENDED_STRIPPED_STATE_EVENT_TYPES: &[StateEventType] = &[
21    StateEventType::RoomCreate,
22    StateEventType::RoomName,
23    StateEventType::RoomAvatar,
24    StateEventType::RoomTopic,
25    StateEventType::RoomJoinRules,
26    StateEventType::RoomCanonicalAlias,
27    StateEventType::RoomEncryption,
28];
29
30/// Event types that servers should transfer upon [room upgrade]. The exact details for what is
31/// transferred is left as an implementation detail.
32///
33/// [room upgrade]: https://spec.matrix.org/v1.19/client-server-api/#server-behaviour-21
34pub const RECOMMENDED_TRANSFERABLE_STATE_EVENT_TYPES: &[StateEventType] = &[
35    StateEventType::RoomServerAcl,
36    StateEventType::RoomEncryption,
37    StateEventType::RoomName,
38    StateEventType::RoomAvatar,
39    StateEventType::RoomTopic,
40    StateEventType::RoomGuestAccess,
41    StateEventType::RoomHistoryVisibility,
42    StateEventType::RoomJoinRules,
43    StateEventType::RoomPowerLevels,
44    #[cfg(feature = "unstable-msc4495")]
45    StateEventType::RoomPresenceSharing,
46];
47
48event_enum! {
49    /// Any global account data event.
50    enum GlobalAccountData {
51        "m.direct" => super::direct,
52        #[cfg(feature = "unstable-msc4359")]
53        #[ruma_enum(ident = DoNotDisturb, alias = "m.do_not_disturb")]
54        "dm.filament.do_not_disturb" => super::do_not_disturb,
55        "m.identity_server" => super::identity_server,
56        "m.invite_permission_config" => super::invite_permission_config,
57        #[cfg(feature = "unstable-msc4380")]
58        #[ruma_enum(ident = UnstableInvitePermissionConfig)]
59        "org.matrix.msc4380.invite_permission_config" => super::invite_permission_config,
60        "m.ignored_user_list" => super::ignored_user_list,
61        "m.image_pack.rooms" => super::image_pack::rooms,
62        "m.push_rules" => super::push_rules,
63        "m.secret_storage.default_key" => super::secret_storage::default_key,
64        "m.secret_storage.key.*" => super::secret_storage::key,
65        #[cfg(feature = "unstable-msc4278")]
66        "m.media_preview_config" => super::media_preview_config,
67        #[cfg(feature = "unstable-msc4278")]
68        #[ruma_enum(ident = UnstableMediaPreviewConfig)]
69        "io.element.msc4278.media_preview_config" => super::media_preview_config,
70        "m.recent_emoji" => super::recent_emoji,
71        "m.key_backup" => super::key_backup,
72        #[cfg(feature = "unstable-msc4495")]
73        #[ruma_enum(ident = PresenceSharing)]
74        "org.continuwuity.presence_v2.msc4495.presence.sharing" => super::presence::sharing,
75        #[cfg(feature = "unstable-msc4495")]
76        #[ruma_enum(ident = PresencePrompted)]
77        "org.continuwuity.presence_v2.msc4495.presence.prompted" => super::presence::prompted,
78    }
79
80    /// Any room account data event.
81    enum RoomAccountData {
82        "m.fully_read" => super::fully_read,
83        "m.tag" => super::tag,
84        "m.marked_unread" => super::marked_unread,
85        #[cfg(feature = "unstable-msc2867")]
86        #[ruma_enum(ident = UnstableMarkedUnread)]
87        "com.famedly.marked_unread" => super::marked_unread,
88        #[cfg(feature = "unstable-msc4278")]
89        "m.media_preview_config" => super::media_preview_config,
90        #[cfg(feature = "unstable-msc4278")]
91        #[ruma_enum(ident = UnstableMediaPreviewConfig)]
92        "io.element.msc4278.media_preview_config" => super::media_preview_config,
93        #[cfg(feature = "unstable-msc3230")]
94        #[ruma_enum(alias = "m.space_order")]
95        "org.matrix.msc3230.space_order" => super::space_order,
96    }
97
98    /// Any ephemeral room event.
99    enum EphemeralRoom {
100        "m.receipt" => super::receipt,
101        "m.typing" => super::typing,
102    }
103
104    /// Any message-like event.
105    enum MessageLike {
106        #[cfg(feature = "unstable-msc3927")]
107        #[ruma_enum(alias = "m.audio")]
108        "org.matrix.msc1767.audio" => super::audio,
109        "m.call.answer" => super::call::answer,
110        "m.call.invite" => super::call::invite,
111        "m.call.hangup" => super::call::hangup,
112        "m.call.candidates" => super::call::candidates,
113        "m.call.negotiate" => super::call::negotiate,
114        "m.call.reject" => super::call::reject,
115        #[ruma_enum(alias = "org.matrix.call.sdp_stream_metadata_changed")]
116        "m.call.sdp_stream_metadata_changed" => super::call::sdp_stream_metadata_changed,
117        "m.call.select_answer" => super::call::select_answer,
118        #[cfg(feature = "unstable-msc3954")]
119        #[ruma_enum(alias = "m.emote")]
120        "org.matrix.msc1767.emote" => super::emote,
121        #[cfg(feature = "unstable-msc3956")]
122        #[ruma_enum(alias = "m.encrypted")]
123        "org.matrix.msc1767.encrypted" => super::encrypted,
124        #[cfg(feature = "unstable-msc3551")]
125        #[ruma_enum(alias = "m.file")]
126        "org.matrix.msc1767.file" => super::file,
127        #[cfg(feature = "unstable-msc3552")]
128        #[ruma_enum(alias = "m.image")]
129        "org.matrix.msc1767.image" => super::image,
130        "m.key.verification.ready" => super::key::verification::ready,
131        "m.key.verification.start" => super::key::verification::start,
132        "m.key.verification.cancel" => super::key::verification::cancel,
133        "m.key.verification.accept" => super::key::verification::accept,
134        "m.key.verification.key" => super::key::verification::key,
135        "m.key.verification.mac" => super::key::verification::mac,
136        "m.key.verification.done" => super::key::verification::done,
137        #[cfg(feature = "unstable-msc3488")]
138        "m.location" => super::location,
139        #[cfg(feature = "unstable-msc1767")]
140        #[ruma_enum(alias = "m.message")]
141        "org.matrix.msc1767.message" => super::message,
142        #[cfg(feature = "unstable-msc3381")]
143        "m.poll.start" => super::poll::start,
144        #[cfg(feature = "unstable-msc3381")]
145        #[ruma_enum(ident = UnstablePollStart)]
146        "org.matrix.msc3381.poll.start" => super::poll::unstable_start,
147        #[cfg(feature = "unstable-msc3381")]
148        "m.poll.response" => super::poll::response,
149        #[cfg(feature = "unstable-msc3381")]
150        #[ruma_enum(ident = UnstablePollResponse)]
151        "org.matrix.msc3381.poll.response" => super::poll::unstable_response,
152        #[cfg(feature = "unstable-msc3381")]
153        "m.poll.end" => super::poll::end,
154        #[cfg(feature = "unstable-msc3381")]
155        #[ruma_enum(ident = UnstablePollEnd)]
156        "org.matrix.msc3381.poll.end" => super::poll::unstable_end,
157        #[cfg(feature = "unstable-msc3489")]
158        #[ruma_enum(alias = "m.beacon")]
159        "org.matrix.msc3672.beacon" => super::beacon,
160        "m.reaction" => super::reaction,
161        "m.room.encrypted" => super::room::encrypted,
162        "m.room.message" => super::room::message,
163        "m.room.redaction" => super::room::redaction,
164        "m.sticker" => super::sticker,
165        #[cfg(feature = "unstable-msc3553")]
166        #[ruma_enum(alias = "m.video")]
167        "org.matrix.msc1767.video" => super::video,
168        #[cfg(feature = "unstable-msc3245")]
169        #[ruma_enum(alias = "m.voice")]
170        "org.matrix.msc3245.voice.v2" => super::voice,
171        #[cfg(feature = "unstable-msc4075")]
172        #[ruma_enum(alias = "m.call.notify")]
173        #[allow(deprecated)]
174        "org.matrix.msc4075.call.notify" => super::call::notify,
175        #[cfg(feature = "unstable-msc4075")]
176        #[ruma_enum(alias = "m.rtc.notification")]
177        "org.matrix.msc4075.rtc.notification" => super::rtc::notification,
178        #[cfg(feature = "unstable-msc4310")]
179        #[ruma_enum(alias = "m.rtc.decline")]
180        "org.matrix.msc4310.rtc.decline" => super::rtc::decline,
181    }
182
183    /// Any state event.
184    enum State {
185        "m.policy.rule.room" => super::policy::rule::room,
186        "m.policy.rule.server" => super::policy::rule::server,
187        "m.policy.rule.user" => super::policy::rule::user,
188        "m.room.avatar" => super::room::avatar,
189        "m.room.canonical_alias" => super::room::canonical_alias,
190        "m.room.create" => super::room::create,
191        "m.room.encryption" => super::room::encryption,
192        #[cfg(feature = "unstable-msc4362")]
193        "m.room.encrypted" => super::room::encrypted::unstable_state,
194        "m.room.guest_access" => super::room::guest_access,
195        "m.room.history_visibility" => super::room::history_visibility,
196        "m.room.image_pack" => super::room::image_pack,
197        "m.room.join_rules" => super::room::join_rules,
198        #[cfg(feature = "unstable-msc4334")]
199        #[ruma_enum(alias = "m.room.language")]
200        "org.matrix.msc4334.room.language" => super::room::language,
201        "m.room.member" => super::room::member,
202        "m.room.name" => super::room::name,
203        "m.room.pinned_events" => super::room::pinned_events,
204        "m.room.policy" => super::room::policy,
205        "m.room.power_levels" => super::room::power_levels,
206        #[cfg(feature = "unstable-msc1763")]
207        #[ruma_enum(alias = "m.room.retention")]
208        "org.matrix.msc1763.retention" => super::room::retention,
209        "m.room.server_acl" => super::room::server_acl,
210        "m.room.third_party_invite" => super::room::third_party_invite,
211        "m.room.tombstone" => super::room::tombstone,
212        "m.room.topic" => super::room::topic,
213        #[cfg(feature = "unstable-msc4495")]
214        #[ruma_enum(alias = "m.room.presence_sharing")]
215        "org.continuwuity.presence_v2.msc4495.room.presence_sharing" => super::room::presence_sharing,
216        "m.space.child" => super::space::child,
217        "m.space.parent" => super::space::parent,
218        #[cfg(feature = "unstable-msc3489")]
219        #[ruma_enum(alias = "m.beacon_info")]
220        "org.matrix.msc3672.beacon_info" => super::beacon_info,
221        #[cfg(feature = "unstable-msc3401")]
222        #[ruma_enum(alias = "m.call.member")]
223        "org.matrix.msc3401.call.member" => super::call::member,
224        #[cfg(feature = "unstable-msc4171")]
225        #[ruma_enum(alias = "m.member_hints")]
226        "io.element.functional_members" => super::member_hints,
227    }
228
229    /// Any to-device event.
230    enum ToDevice {
231        "m.dummy" => super::dummy,
232        "m.room_key" => super::room_key,
233        "m.room_key_bundle" => super::room_key_bundle,
234        "m.room_key_request" => super::room_key_request,
235        "m.room_key.withheld" => super::room_key::withheld,
236        "m.forwarded_room_key" => super::forwarded_room_key,
237        "m.key.verification.request" => super::key::verification::request,
238        "m.key.verification.ready" => super::key::verification::ready,
239        "m.key.verification.start" => super::key::verification::start,
240        "m.key.verification.cancel" => super::key::verification::cancel,
241        "m.key.verification.accept" => super::key::verification::accept,
242        "m.key.verification.key" => super::key::verification::key,
243        "m.key.verification.mac" => super::key::verification::mac,
244        "m.key.verification.done" => super::key::verification::done,
245        "m.room.encrypted" => super::room::encrypted,
246        "m.secret.request"=> super::secret::request,
247        "m.secret.send" => super::secret::send,
248        #[cfg(feature = "unstable-msc4385")]
249        #[ruma_enum(alias = "m.secret.push")]
250        "io.element.msc4385.secret.push" => super::secret::push,
251        #[cfg(feature = "unstable-msc4471")]
252        #[ruma_enum(alias = "m.stream.subscribe")]
253        "org.matrix.msc4471.stream.subscribe" => super::stream::subscribe,
254        #[cfg(feature = "unstable-msc4471")]
255        #[ruma_enum(alias = "m.stream.cancel")]
256        "org.matrix.msc4471.stream.cancel" => super::stream::cancel,
257        #[cfg(feature = "unstable-msc4471")]
258        #[ruma_enum(alias = "m.stream.update")]
259        "org.matrix.msc4471.stream.update" => super::stream::update,
260    }
261}
262
263macro_rules! timeline_event_accessors {
264    (
265        $(
266            #[doc = $docs:literal]
267            pub fn $field:ident(&self) -> $ty:ty;
268        )*
269    ) => {
270        $(
271            #[doc = $docs]
272            pub fn $field(&self) -> $ty {
273                match self {
274                    Self::MessageLike(ev) => ev.$field(),
275                    Self::State(ev) => ev.$field(),
276                }
277            }
278        )*
279    };
280}
281
282/// Any room event.
283#[allow(clippy::large_enum_variant, clippy::exhaustive_enums)]
284#[derive(Clone, Debug, EventEnumFromEvent)]
285pub enum AnyTimelineEvent {
286    /// Any message-like event.
287    MessageLike(AnyMessageLikeEvent),
288
289    /// Any state event.
290    State(AnyStateEvent),
291}
292
293impl AnyTimelineEvent {
294    timeline_event_accessors! {
295        /// Returns this event's `origin_server_ts` field.
296        pub fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch;
297
298        /// Returns this event's `room_id` field.
299        pub fn room_id(&self) -> &RoomId;
300
301        /// Returns this event's `event_id` field.
302        pub fn event_id(&self) -> &EventId;
303
304        /// Returns this event's `sender` field.
305        pub fn sender(&self) -> &UserId;
306
307        /// Returns this event's `transaction_id` from inside `unsigned`, if there is one.
308        pub fn transaction_id(&self) -> Option<&TransactionId>;
309
310        /// Returns whether this event is in its redacted form or not.
311        pub fn is_redacted(&self) -> bool;
312    }
313
314    /// Returns this event's `type`.
315    pub fn event_type(&self) -> TimelineEventType {
316        match self {
317            Self::MessageLike(e) => e.event_type().into(),
318            Self::State(e) => e.event_type().into(),
319        }
320    }
321}
322
323/// Any sync room event.
324///
325/// Sync room events are room event without a `room_id`, as returned in `/sync` responses.
326#[allow(clippy::large_enum_variant, clippy::exhaustive_enums)]
327#[derive(Clone, Debug, EventEnumFromEvent)]
328pub enum AnySyncTimelineEvent {
329    /// Any sync message-like event.
330    MessageLike(AnySyncMessageLikeEvent),
331
332    /// Any sync state event.
333    State(AnySyncStateEvent),
334}
335
336impl AnySyncTimelineEvent {
337    timeline_event_accessors! {
338        /// Returns this event's `origin_server_ts` field.
339        pub fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch;
340
341        /// Returns this event's `event_id` field.
342        pub fn event_id(&self) -> &EventId;
343
344        /// Returns this event's `sender` field.
345        pub fn sender(&self) -> &UserId;
346
347        /// Returns this event's `transaction_id` from inside `unsigned`, if there is one.
348        pub fn transaction_id(&self) -> Option<&TransactionId>;
349
350        /// Returns whether this event is in its redacted form or not.
351        pub fn is_redacted(&self) -> bool;
352    }
353
354    /// Returns this event's `type`.
355    pub fn event_type(&self) -> TimelineEventType {
356        match self {
357            Self::MessageLike(e) => e.event_type().into(),
358            Self::State(e) => e.event_type().into(),
359        }
360    }
361
362    /// Converts `self` to an `AnyTimelineEvent` by adding the given a room ID.
363    pub fn into_full_event(self, room_id: OwnedRoomId) -> AnyTimelineEvent {
364        match self {
365            Self::MessageLike(ev) => AnyTimelineEvent::MessageLike(ev.into_full_event(room_id)),
366            Self::State(ev) => AnyTimelineEvent::State(ev.into_full_event(room_id)),
367        }
368    }
369}
370
371impl From<AnyTimelineEvent> for AnySyncTimelineEvent {
372    fn from(ev: AnyTimelineEvent) -> Self {
373        match ev {
374            AnyTimelineEvent::MessageLike(ev) => Self::MessageLike(ev.into()),
375            AnyTimelineEvent::State(ev) => Self::State(ev.into()),
376        }
377    }
378}
379
380/// Any room event content.
381#[allow(clippy::large_enum_variant, clippy::exhaustive_enums)]
382#[derive(Clone, Debug, EventEnumFromEvent, Serialize)]
383#[serde(untagged)]
384pub enum AnyTimelineEventContent {
385    /// Any message-like event content.
386    MessageLike(AnyMessageLikeEventContent),
387
388    /// Any state event content.
389    State(AnyStateEventContent),
390}
391
392impl AnyTimelineEventContent {
393    /// Get the event's type
394    pub fn event_type(&self) -> TimelineEventType {
395        match self {
396            Self::MessageLike(content) => {
397                <AnyMessageLikeEventContent as crate::MessageLikeEventContent>::event_type(content)
398                    .into()
399            }
400            Self::State(content) => {
401                <AnyStateEventContent as crate::StateEventContent>::event_type(content).into()
402            }
403        }
404    }
405}
406
407impl JsonCastable<AnyTimelineEventContent> for AnyMessageLikeEventContent {}
408impl JsonCastable<AnyTimelineEventContent> for AnyStateEventContent {}
409
410#[derive(Deserialize)]
411#[allow(clippy::exhaustive_structs)]
412struct EventDeHelper {
413    state_key: Option<de::IgnoredAny>,
414}
415
416impl<'de> Deserialize<'de> for AnyTimelineEvent {
417    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
418    where
419        D: de::Deserializer<'de>,
420    {
421        let json = Box::<RawJsonValue>::deserialize(deserializer)?;
422        let EventDeHelper { state_key } = from_raw_json_value(&json)?;
423
424        if state_key.is_some() {
425            Ok(AnyTimelineEvent::State(from_raw_json_value(&json)?))
426        } else {
427            Ok(AnyTimelineEvent::MessageLike(from_raw_json_value(&json)?))
428        }
429    }
430}
431
432impl<'de> Deserialize<'de> for AnySyncTimelineEvent {
433    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
434    where
435        D: de::Deserializer<'de>,
436    {
437        let json = Box::<RawJsonValue>::deserialize(deserializer)?;
438        let EventDeHelper { state_key } = from_raw_json_value(&json)?;
439
440        if state_key.is_some() {
441            Ok(AnySyncTimelineEvent::State(from_raw_json_value(&json)?))
442        } else {
443            Ok(AnySyncTimelineEvent::MessageLike(from_raw_json_value(&json)?))
444        }
445    }
446}
447
448impl AnyMessageLikeEventContent {
449    /// Get a copy of the event's `m.relates_to` field, if any.
450    ///
451    /// This is a helper function intended for encryption. There should not be a reason to access
452    /// `m.relates_to` without first destructuring an `AnyMessageLikeEventContent` otherwise.
453    pub fn relation(&self) -> Option<encrypted::Relation> {
454        #[cfg(feature = "unstable-msc3489")]
455        use super::beacon::BeaconEventContent;
456        use super::key::verification::{
457            accept::KeyVerificationAcceptEventContent, cancel::KeyVerificationCancelEventContent,
458            done::KeyVerificationDoneEventContent, key::KeyVerificationKeyEventContent,
459            mac::KeyVerificationMacEventContent, ready::KeyVerificationReadyEventContent,
460            start::KeyVerificationStartEventContent,
461        };
462        #[cfg(feature = "unstable-msc3381")]
463        use super::poll::{
464            end::PollEndEventContent, response::PollResponseEventContent,
465            unstable_end::UnstablePollEndEventContent,
466            unstable_response::UnstablePollResponseEventContent,
467        };
468
469        match self {
470            #[rustfmt::skip]
471            Self::KeyVerificationReady(KeyVerificationReadyEventContent { relates_to, .. })
472            | Self::KeyVerificationStart(KeyVerificationStartEventContent { relates_to, .. })
473            | Self::KeyVerificationCancel(KeyVerificationCancelEventContent { relates_to, .. })
474            | Self::KeyVerificationAccept(KeyVerificationAcceptEventContent { relates_to, .. })
475            | Self::KeyVerificationKey(KeyVerificationKeyEventContent { relates_to, .. })
476            | Self::KeyVerificationMac(KeyVerificationMacEventContent { relates_to, .. })
477            | Self::KeyVerificationDone(KeyVerificationDoneEventContent { relates_to, .. }) => {
478                Some(encrypted::Relation::Reference(relates_to.clone()))
479            },
480            Self::Reaction(ev) => Some(encrypted::Relation::Annotation(ev.relates_to.clone())),
481            Self::RoomEncrypted(ev) => ev.relates_to.clone(),
482            Self::RoomMessage(ev) => ev.relates_to.clone().map(Into::into),
483            #[cfg(feature = "unstable-msc1767")]
484            Self::Message(ev) => ev.relates_to.clone().map(Into::into),
485            #[cfg(feature = "unstable-msc3954")]
486            Self::Emote(ev) => ev.relates_to.clone().map(Into::into),
487            #[cfg(feature = "unstable-msc3956")]
488            Self::Encrypted(ev) => ev.relates_to.clone(),
489            #[cfg(feature = "unstable-msc3245")]
490            Self::Voice(ev) => ev.relates_to.clone().map(Into::into),
491            #[cfg(feature = "unstable-msc3927")]
492            Self::Audio(ev) => ev.relates_to.clone().map(Into::into),
493            #[cfg(feature = "unstable-msc3488")]
494            Self::Location(ev) => ev.relates_to.clone().map(Into::into),
495            #[cfg(feature = "unstable-msc3551")]
496            Self::File(ev) => ev.relates_to.clone().map(Into::into),
497            #[cfg(feature = "unstable-msc3552")]
498            Self::Image(ev) => ev.relates_to.clone().map(Into::into),
499            #[cfg(feature = "unstable-msc3553")]
500            Self::Video(ev) => ev.relates_to.clone().map(Into::into),
501            #[cfg(feature = "unstable-msc3381")]
502            Self::PollResponse(PollResponseEventContent { relates_to, .. })
503            | Self::UnstablePollResponse(UnstablePollResponseEventContent { relates_to, .. })
504            | Self::PollEnd(PollEndEventContent { relates_to, .. })
505            | Self::UnstablePollEnd(UnstablePollEndEventContent { relates_to, .. }) => {
506                Some(encrypted::Relation::Reference(relates_to.clone()))
507            }
508            #[cfg(feature = "unstable-msc3489")]
509            Self::Beacon(BeaconEventContent { relates_to, .. }) => {
510                Some(encrypted::Relation::Reference(relates_to.clone()))
511            }
512            #[cfg(feature = "unstable-msc3381")]
513            Self::UnstablePollStart(UnstablePollStartEventContent::New(content)) => {
514                content.relates_to.clone().map(Into::into)
515            }
516            #[cfg(feature = "unstable-msc3381")]
517            Self::UnstablePollStart(UnstablePollStartEventContent::Replacement(content)) => {
518                Some(encrypted::Relation::Replacement(Replacement::new(
519                    content.relates_to.event_id.clone(),
520                )))
521            }
522            #[cfg(feature = "unstable-msc3381")]
523            Self::PollStart(PollStartEventContent { relates_to, .. }) => {
524                relates_to.clone().map(Into::into)
525            }
526            #[cfg(feature = "unstable-msc4075")]
527            Self::CallNotify(_) => None,
528            #[cfg(feature = "unstable-msc4075")]
529            Self::RtcNotification(ev) => ev.relates_to.clone().map(encrypted::Relation::Reference),
530            #[cfg(feature = "unstable-msc4310")]
531            Self::RtcDecline(ev) => Some(encrypted::Relation::Reference(ev.relates_to.clone())),
532            Self::CallSdpStreamMetadataChanged(_)
533            | Self::CallNegotiate(_)
534            | Self::CallReject(_)
535            | Self::CallSelectAnswer(_)
536            | Self::CallAnswer(_)
537            | Self::CallInvite(_)
538            | Self::CallHangup(_)
539            | Self::CallCandidates(_)
540            | Self::RoomRedaction(_)
541            | Self::Sticker(_)
542            | Self::_Custom { .. } => None,
543        }
544    }
545}