1#![allow(clippy::exhaustive_structs)]
2
3use as_variant::as_variant;
4use ruma_common::{
5 encryption::DeviceKeys,
6 room_version_rules::RedactionRules,
7 serde::{from_raw_json_value, Raw},
8 EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId,
9};
10use ruma_macros::Event;
11use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
12use serde_json::value::RawValue as RawJsonValue;
13
14use super::{
15 AnyInitialStateEvent, EmptyStateKey, EphemeralRoomEventContent, EventContentFromType,
16 GlobalAccountDataEventContent, MessageLikeEventContent, MessageLikeEventType,
17 MessageLikeUnsigned, PossiblyRedactedStateEventContent, RedactContent,
18 RedactedMessageLikeEventContent, RedactedStateEventContent, RedactedUnsigned,
19 RedactionDeHelper, RoomAccountDataEventContent, StateEventType, StaticStateEventContent,
20 ToDeviceEventContent,
21};
22
23#[derive(Clone, Debug, Event)]
25pub struct GlobalAccountDataEvent<C: GlobalAccountDataEventContent> {
26 pub content: C,
28}
29
30impl<C: GlobalAccountDataEventContent> Serialize for GlobalAccountDataEvent<C> {
31 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32 where
33 S: serde::Serializer,
34 {
35 let mut state = serializer.serialize_struct("GlobalAccountDataEvent", 2)?;
36 state.serialize_field("type", &self.content.event_type())?;
37 state.serialize_field("content", &self.content)?;
38 state.end()
39 }
40}
41
42#[derive(Clone, Debug, Event)]
44pub struct RoomAccountDataEvent<C: RoomAccountDataEventContent> {
45 pub content: C,
47}
48
49impl<C: RoomAccountDataEventContent> Serialize for RoomAccountDataEvent<C> {
50 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51 where
52 S: serde::Serializer,
53 {
54 let mut state = serializer.serialize_struct("RoomAccountDataEvent", 2)?;
55 state.serialize_field("type", &self.content.event_type())?;
56 state.serialize_field("content", &self.content)?;
57 state.end()
58 }
59}
60
61#[derive(Clone, Debug, Event)]
63pub struct EphemeralRoomEvent<C: EphemeralRoomEventContent> {
64 pub content: C,
66
67 pub room_id: OwnedRoomId,
69}
70
71impl<C: EphemeralRoomEventContent> Serialize for EphemeralRoomEvent<C> {
72 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73 where
74 S: serde::Serializer,
75 {
76 let mut state = serializer.serialize_struct("EphemeralRoomEvent", 2)?;
77 state.serialize_field("type", &self.content.event_type())?;
78 state.serialize_field("content", &self.content)?;
79 state.serialize_field("room_id", &self.room_id)?;
80 state.end()
81 }
82}
83
84#[derive(Clone, Debug, Event)]
86pub struct SyncEphemeralRoomEvent<C: EphemeralRoomEventContent> {
87 pub content: C,
89}
90
91impl<C: EphemeralRoomEventContent> Serialize for SyncEphemeralRoomEvent<C> {
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: serde::Serializer,
95 {
96 let mut state = serializer.serialize_struct("SyncEphemeralRoomEvent", 2)?;
97 state.serialize_field("type", &self.content.event_type())?;
98 state.serialize_field("content", &self.content)?;
99 state.end()
100 }
101}
102
103#[derive(Clone, Debug, Event)]
108pub struct OriginalMessageLikeEvent<C: MessageLikeEventContent> {
109 pub content: C,
111
112 pub event_id: OwnedEventId,
114
115 pub sender: OwnedUserId,
117
118 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
120
121 pub room_id: OwnedRoomId,
123
124 pub unsigned: MessageLikeUnsigned<C>,
126}
127
128#[derive(Clone, Debug, Event)]
133pub struct OriginalSyncMessageLikeEvent<C: MessageLikeEventContent> {
134 pub content: C,
136
137 pub event_id: OwnedEventId,
139
140 pub sender: OwnedUserId,
142
143 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
145
146 pub unsigned: MessageLikeUnsigned<C>,
148}
149
150impl<C: MessageLikeEventContent + RedactContent> OriginalSyncMessageLikeEvent<C>
151where
152 C::Redacted: RedactedMessageLikeEventContent,
153{
154 pub(crate) fn into_maybe_redacted(self) -> SyncMessageLikeEvent<C> {
155 SyncMessageLikeEvent::Original(self)
156 }
157}
158
159#[derive(Clone, Debug, Event)]
164pub struct RedactedMessageLikeEvent<C: RedactedMessageLikeEventContent> {
165 pub content: C,
167
168 pub event_id: OwnedEventId,
170
171 pub sender: OwnedUserId,
173
174 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
176
177 pub room_id: OwnedRoomId,
179
180 pub unsigned: RedactedUnsigned,
182}
183
184#[derive(Clone, Debug, Event)]
189pub struct RedactedSyncMessageLikeEvent<C: RedactedMessageLikeEventContent> {
190 pub content: C,
192
193 pub event_id: OwnedEventId,
195
196 pub sender: OwnedUserId,
198
199 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
201
202 pub unsigned: RedactedUnsigned,
204}
205
206#[allow(clippy::exhaustive_enums)]
211#[derive(Clone, Debug)]
212pub enum MessageLikeEvent<C: MessageLikeEventContent + RedactContent>
213where
214 C::Redacted: RedactedMessageLikeEventContent,
215{
216 Original(OriginalMessageLikeEvent<C>),
218
219 Redacted(RedactedMessageLikeEvent<C::Redacted>),
221}
222
223#[allow(clippy::exhaustive_enums)]
228#[derive(Clone, Debug)]
229pub enum SyncMessageLikeEvent<C: MessageLikeEventContent + RedactContent>
230where
231 C::Redacted: RedactedMessageLikeEventContent,
232{
233 Original(OriginalSyncMessageLikeEvent<C>),
235
236 Redacted(RedactedSyncMessageLikeEvent<C::Redacted>),
238}
239
240#[derive(Clone, Debug, Event)]
245pub struct OriginalStateEvent<C: StaticStateEventContent> {
246 pub content: C,
248
249 pub event_id: OwnedEventId,
251
252 pub sender: OwnedUserId,
254
255 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
257
258 pub room_id: OwnedRoomId,
260
261 pub state_key: C::StateKey,
266
267 pub unsigned: C::Unsigned,
269}
270
271#[derive(Clone, Debug, Event)]
276pub struct OriginalSyncStateEvent<C: StaticStateEventContent> {
277 pub content: C,
279
280 pub event_id: OwnedEventId,
282
283 pub sender: OwnedUserId,
285
286 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
288
289 pub state_key: C::StateKey,
294
295 pub unsigned: C::Unsigned,
297}
298
299#[derive(Clone, Debug, Event)]
301pub struct StrippedStateEvent<C: PossiblyRedactedStateEventContent> {
302 pub content: C,
304
305 pub sender: OwnedUserId,
307
308 pub state_key: C::StateKey,
313}
314
315#[derive(Clone, Debug, Event)]
317pub struct InitialStateEvent<C: StaticStateEventContent> {
318 pub content: C,
320
321 pub state_key: C::StateKey,
328}
329
330impl<C: StaticStateEventContent> InitialStateEvent<C> {
331 pub fn new(content: C) -> Self
335 where
336 C: StaticStateEventContent<StateKey = EmptyStateKey>,
337 {
338 Self { content, state_key: EmptyStateKey }
339 }
340
341 pub fn to_raw(&self) -> Raw<Self> {
349 Raw::new(self).unwrap()
350 }
351
352 pub fn to_raw_any(&self) -> Raw<AnyInitialStateEvent> {
360 self.to_raw().cast()
361 }
362}
363
364impl<C> Default for InitialStateEvent<C>
365where
366 C: StaticStateEventContent<StateKey = EmptyStateKey> + Default,
367{
368 fn default() -> Self {
369 Self { content: Default::default(), state_key: EmptyStateKey }
370 }
371}
372
373impl<C: StaticStateEventContent> Serialize for InitialStateEvent<C> {
374 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
375 where
376 S: serde::Serializer,
377 {
378 let mut state = serializer.serialize_struct("InitialStateEvent", 3)?;
379 state.serialize_field("type", &self.content.event_type())?;
380 state.serialize_field("content", &self.content)?;
381 state.serialize_field("state_key", &self.state_key)?;
382 state.end()
383 }
384}
385
386#[derive(Clone, Debug, Event)]
391pub struct RedactedStateEvent<C: RedactedStateEventContent> {
392 pub content: C,
394
395 pub event_id: OwnedEventId,
397
398 pub sender: OwnedUserId,
400
401 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
403
404 pub room_id: OwnedRoomId,
406
407 pub state_key: C::StateKey,
412
413 pub unsigned: RedactedUnsigned,
415}
416
417#[derive(Clone, Debug, Event)]
422pub struct RedactedSyncStateEvent<C: RedactedStateEventContent> {
423 pub content: C,
425
426 pub event_id: OwnedEventId,
428
429 pub sender: OwnedUserId,
431
432 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
434
435 pub state_key: C::StateKey,
440
441 pub unsigned: RedactedUnsigned,
443}
444
445#[allow(clippy::exhaustive_enums)]
450#[derive(Clone, Debug)]
451pub enum StateEvent<C: StaticStateEventContent + RedactContent>
452where
453 C::Redacted: RedactedStateEventContent,
454{
455 Original(OriginalStateEvent<C>),
457
458 Redacted(RedactedStateEvent<C::Redacted>),
460}
461
462#[allow(clippy::exhaustive_enums)]
467#[derive(Clone, Debug)]
468pub enum SyncStateEvent<C: StaticStateEventContent + RedactContent>
469where
470 C::Redacted: RedactedStateEventContent,
471{
472 Original(OriginalSyncStateEvent<C>),
474
475 Redacted(RedactedSyncStateEvent<C::Redacted>),
477}
478
479#[derive(Clone, Debug, Event)]
481pub struct ToDeviceEvent<C: ToDeviceEventContent> {
482 pub content: C,
484
485 pub sender: OwnedUserId,
487}
488
489impl<C: ToDeviceEventContent> Serialize for ToDeviceEvent<C> {
490 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
491 where
492 S: serde::Serializer,
493 {
494 let mut state = serializer.serialize_struct("ToDeviceEvent", 3)?;
495 state.serialize_field("type", &self.content.event_type())?;
496 state.serialize_field("content", &self.content)?;
497 state.serialize_field("sender", &self.sender)?;
498 state.end()
499 }
500}
501
502#[derive(Clone, Debug, Event)]
504pub struct DecryptedOlmV1Event<C: MessageLikeEventContent> {
505 pub content: C,
507
508 pub sender: OwnedUserId,
510
511 pub recipient: OwnedUserId,
513
514 pub recipient_keys: OlmV1Keys,
516
517 pub keys: OlmV1Keys,
519
520 pub sender_device_keys: Option<Raw<DeviceKeys>>,
522}
523
524#[derive(Clone, Debug, Deserialize, Serialize)]
526pub struct OlmV1Keys {
527 pub ed25519: String,
529}
530
531#[derive(Clone, Debug, Event)]
533pub struct DecryptedMegolmV1Event<C: MessageLikeEventContent> {
534 pub content: C,
536
537 pub room_id: OwnedRoomId,
539}
540
541#[allow(clippy::exhaustive_enums)]
545#[derive(Clone, Debug)]
546pub enum FullStateEventContent<C: StaticStateEventContent + RedactContent> {
547 Original {
549 content: C,
551
552 prev_content: Option<C::PossiblyRedacted>,
554 },
555
556 Redacted(C::Redacted),
558}
559
560impl<C: StaticStateEventContent + RedactContent> FullStateEventContent<C>
561where
562 C::Redacted: RedactedStateEventContent,
563{
564 pub fn event_type(&self) -> StateEventType {
566 match self {
567 Self::Original { content, .. } => content.event_type(),
568 Self::Redacted(content) => content.event_type(),
569 }
570 }
571
572 pub fn redact(self, rules: &RedactionRules) -> C::Redacted {
579 match self {
580 FullStateEventContent::Original { content, .. } => content.redact(rules),
581 FullStateEventContent::Redacted(content) => content,
582 }
583 }
584}
585
586macro_rules! impl_possibly_redacted_event {
587 (
588 $ty:ident ( $content_trait:ident, $redacted_content_trait:ident, $event_type:ident )
589 $( where C::Redacted: $trait:ident<StateKey = C::StateKey>, )?
590 { $($extra:tt)* }
591 ) => {
592 impl<C> $ty<C>
593 where
594 C: $content_trait + RedactContent,
595 C::Redacted: $redacted_content_trait,
596 $( C::Redacted: $trait<StateKey = C::StateKey>, )?
597 {
598 pub fn event_type(&self) -> $event_type {
600 match self {
601 Self::Original(ev) => ev.content.event_type(),
602 Self::Redacted(ev) => ev.content.event_type(),
603 }
604 }
605
606 pub fn event_id(&self) -> &EventId {
608 match self {
609 Self::Original(ev) => &ev.event_id,
610 Self::Redacted(ev) => &ev.event_id,
611 }
612 }
613
614 pub fn sender(&self) -> &UserId {
616 match self {
617 Self::Original(ev) => &ev.sender,
618 Self::Redacted(ev) => &ev.sender,
619 }
620 }
621
622 pub fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
624 match self {
625 Self::Original(ev) => ev.origin_server_ts,
626 Self::Redacted(ev) => ev.origin_server_ts,
627 }
628 }
629
630 $($extra)*
632 }
633
634 impl<'de, C> Deserialize<'de> for $ty<C>
635 where
636 C: $content_trait + EventContentFromType + RedactContent,
637 C::Redacted: $redacted_content_trait + EventContentFromType,
638 $( C::Redacted: $trait<StateKey = C::StateKey>, )?
639 {
640 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
641 where
642 D: Deserializer<'de>,
643 {
644 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
645 let RedactionDeHelper { unsigned } = from_raw_json_value(&json)?;
646
647 if unsigned.and_then(|u| u.redacted_because).is_some() {
648 Ok(Self::Redacted(from_raw_json_value(&json)?))
649 } else {
650 Ok(Self::Original(from_raw_json_value(&json)?))
651 }
652 }
653 }
654 }
655}
656
657impl_possibly_redacted_event!(
658 MessageLikeEvent(
659 MessageLikeEventContent, RedactedMessageLikeEventContent, MessageLikeEventType
660 ) {
661 pub fn room_id(&self) -> &RoomId {
663 match self {
664 Self::Original(ev) => &ev.room_id,
665 Self::Redacted(ev) => &ev.room_id,
666 }
667 }
668
669 pub fn as_original(&self) -> Option<&OriginalMessageLikeEvent<C>> {
671 as_variant!(self, Self::Original)
672 }
673 }
674);
675
676impl_possibly_redacted_event!(
677 SyncMessageLikeEvent(
678 MessageLikeEventContent, RedactedMessageLikeEventContent, MessageLikeEventType
679 ) {
680 pub fn as_original(&self) -> Option<&OriginalSyncMessageLikeEvent<C>> {
682 as_variant!(self, Self::Original)
683 }
684
685 pub fn into_full_event(self, room_id: OwnedRoomId) -> MessageLikeEvent<C> {
687 match self {
688 Self::Original(ev) => MessageLikeEvent::Original(ev.into_full_event(room_id)),
689 Self::Redacted(ev) => MessageLikeEvent::Redacted(ev.into_full_event(room_id)),
690 }
691 }
692 }
693);
694
695impl_possibly_redacted_event!(
696 StateEvent(StaticStateEventContent, RedactedStateEventContent, StateEventType)
697 where
698 C::Redacted: RedactedStateEventContent<StateKey = C::StateKey>,
699 {
700 pub fn room_id(&self) -> &RoomId {
702 match self {
703 Self::Original(ev) => &ev.room_id,
704 Self::Redacted(ev) => &ev.room_id,
705 }
706 }
707
708 pub fn state_key(&self) -> &C::StateKey {
710 match self {
711 Self::Original(ev) => &ev.state_key,
712 Self::Redacted(ev) => &ev.state_key,
713 }
714 }
715
716 pub fn as_original(&self) -> Option<&OriginalStateEvent<C>> {
718 as_variant!(self, Self::Original)
719 }
720 }
721);
722
723impl_possibly_redacted_event!(
724 SyncStateEvent(StaticStateEventContent, RedactedStateEventContent, StateEventType)
725 where
726 C::Redacted: RedactedStateEventContent<StateKey = C::StateKey>,
727 {
728 pub fn state_key(&self) -> &C::StateKey {
730 match self {
731 Self::Original(ev) => &ev.state_key,
732 Self::Redacted(ev) => &ev.state_key,
733 }
734 }
735
736 pub fn as_original(&self) -> Option<&OriginalSyncStateEvent<C>> {
738 as_variant!(self, Self::Original)
739 }
740
741 pub fn into_full_event(self, room_id: OwnedRoomId) -> StateEvent<C> {
743 match self {
744 Self::Original(ev) => StateEvent::Original(ev.into_full_event(room_id)),
745 Self::Redacted(ev) => StateEvent::Redacted(ev.into_full_event(room_id)),
746 }
747 }
748 }
749);
750
751macro_rules! impl_sync_from_full {
752 ($ty:ident, $full:ident, $content_trait:ident, $redacted_content_trait: ident) => {
753 impl<C> From<$full<C>> for $ty<C>
754 where
755 C: $content_trait + RedactContent,
756 C::Redacted: $redacted_content_trait,
757 {
758 fn from(full: $full<C>) -> Self {
759 match full {
760 $full::Original(ev) => Self::Original(ev.into()),
761 $full::Redacted(ev) => Self::Redacted(ev.into()),
762 }
763 }
764 }
765 };
766}
767
768impl_sync_from_full!(
769 SyncMessageLikeEvent,
770 MessageLikeEvent,
771 MessageLikeEventContent,
772 RedactedMessageLikeEventContent
773);
774impl_sync_from_full!(
775 SyncStateEvent,
776 StateEvent,
777 StaticStateEventContent,
778 RedactedStateEventContent
779);