1#![allow(clippy::exhaustive_structs)]
2
3use as_variant::as_variant;
4use ruma_common::{
5 serde::{from_raw_json_value, Raw},
6 EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId,
7 RoomVersionId, UserId,
8};
9use ruma_macros::Event;
10use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize};
11use serde_json::value::RawValue as RawJsonValue;
12
13use super::{
14 AnyInitialStateEvent, EmptyStateKey, EphemeralRoomEventContent, EventContent,
15 EventContentFromType, GlobalAccountDataEventContent, MessageLikeEventContent,
16 MessageLikeEventType, MessageLikeUnsigned, PossiblyRedactedStateEventContent, RedactContent,
17 RedactedMessageLikeEventContent, RedactedStateEventContent, RedactedUnsigned,
18 RedactionDeHelper, RoomAccountDataEventContent, StateEventType, StaticStateEventContent,
19 ToDeviceEventContent,
20};
21
22#[derive(Clone, Debug, Event)]
24pub struct GlobalAccountDataEvent<C: GlobalAccountDataEventContent> {
25 pub content: C,
27}
28
29impl<C: GlobalAccountDataEventContent> Serialize for GlobalAccountDataEvent<C> {
30 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
31 where
32 S: serde::Serializer,
33 {
34 let mut state = serializer.serialize_struct("GlobalAccountDataEvent", 2)?;
35 state.serialize_field("type", &self.content.event_type())?;
36 state.serialize_field("content", &self.content)?;
37 state.end()
38 }
39}
40
41#[derive(Clone, Debug, Event)]
43pub struct RoomAccountDataEvent<C: RoomAccountDataEventContent> {
44 pub content: C,
46}
47
48impl<C: RoomAccountDataEventContent> Serialize for RoomAccountDataEvent<C> {
49 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
50 where
51 S: serde::Serializer,
52 {
53 let mut state = serializer.serialize_struct("RoomAccountDataEvent", 2)?;
54 state.serialize_field("type", &self.content.event_type())?;
55 state.serialize_field("content", &self.content)?;
56 state.end()
57 }
58}
59
60#[derive(Clone, Debug, Event)]
62pub struct EphemeralRoomEvent<C: EphemeralRoomEventContent> {
63 pub content: C,
65
66 pub room_id: OwnedRoomId,
68}
69
70impl<C: EphemeralRoomEventContent> Serialize for EphemeralRoomEvent<C> {
71 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
72 where
73 S: serde::Serializer,
74 {
75 let mut state = serializer.serialize_struct("EphemeralRoomEvent", 2)?;
76 state.serialize_field("type", &self.content.event_type())?;
77 state.serialize_field("content", &self.content)?;
78 state.serialize_field("room_id", &self.room_id)?;
79 state.end()
80 }
81}
82
83#[derive(Clone, Debug, Event)]
85pub struct SyncEphemeralRoomEvent<C: EphemeralRoomEventContent> {
86 pub content: C,
88}
89
90impl<C: EphemeralRoomEventContent> Serialize for SyncEphemeralRoomEvent<C> {
91 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92 where
93 S: serde::Serializer,
94 {
95 let mut state = serializer.serialize_struct("SyncEphemeralRoomEvent", 2)?;
96 state.serialize_field("type", &self.content.event_type())?;
97 state.serialize_field("content", &self.content)?;
98 state.end()
99 }
100}
101
102#[derive(Clone, Debug, Event)]
107pub struct OriginalMessageLikeEvent<C: MessageLikeEventContent> {
108 pub content: C,
110
111 pub event_id: OwnedEventId,
113
114 pub sender: OwnedUserId,
116
117 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
119
120 pub room_id: OwnedRoomId,
122
123 pub unsigned: MessageLikeUnsigned<C>,
125}
126
127#[derive(Clone, Debug, Event)]
132pub struct OriginalSyncMessageLikeEvent<C: MessageLikeEventContent> {
133 pub content: C,
135
136 pub event_id: OwnedEventId,
138
139 pub sender: OwnedUserId,
141
142 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
144
145 pub unsigned: MessageLikeUnsigned<C>,
147}
148
149impl<C: MessageLikeEventContent + RedactContent> OriginalSyncMessageLikeEvent<C>
150where
151 C::Redacted: RedactedMessageLikeEventContent,
152{
153 pub(crate) fn into_maybe_redacted(self) -> SyncMessageLikeEvent<C> {
154 SyncMessageLikeEvent::Original(self)
155 }
156}
157
158#[derive(Clone, Debug, Event)]
163pub struct RedactedMessageLikeEvent<C: RedactedMessageLikeEventContent> {
164 pub content: C,
166
167 pub event_id: OwnedEventId,
169
170 pub sender: OwnedUserId,
172
173 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
175
176 pub room_id: OwnedRoomId,
178
179 pub unsigned: RedactedUnsigned,
181}
182
183#[derive(Clone, Debug, Event)]
188pub struct RedactedSyncMessageLikeEvent<C: RedactedMessageLikeEventContent> {
189 pub content: C,
191
192 pub event_id: OwnedEventId,
194
195 pub sender: OwnedUserId,
197
198 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
200
201 pub unsigned: RedactedUnsigned,
203}
204
205#[allow(clippy::exhaustive_enums)]
210#[derive(Clone, Debug)]
211pub enum MessageLikeEvent<C: MessageLikeEventContent + RedactContent>
212where
213 C::Redacted: RedactedMessageLikeEventContent,
214{
215 Original(OriginalMessageLikeEvent<C>),
217
218 Redacted(RedactedMessageLikeEvent<C::Redacted>),
220}
221
222#[allow(clippy::exhaustive_enums)]
227#[derive(Clone, Debug)]
228pub enum SyncMessageLikeEvent<C: MessageLikeEventContent + RedactContent>
229where
230 C::Redacted: RedactedMessageLikeEventContent,
231{
232 Original(OriginalSyncMessageLikeEvent<C>),
234
235 Redacted(RedactedSyncMessageLikeEvent<C::Redacted>),
237}
238
239#[derive(Clone, Debug, Event)]
244pub struct OriginalStateEvent<C: StaticStateEventContent> {
245 pub content: C,
247
248 pub event_id: OwnedEventId,
250
251 pub sender: OwnedUserId,
253
254 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
256
257 pub room_id: OwnedRoomId,
259
260 pub state_key: C::StateKey,
265
266 pub unsigned: C::Unsigned,
268}
269
270#[derive(Clone, Debug, Event)]
275pub struct OriginalSyncStateEvent<C: StaticStateEventContent> {
276 pub content: C,
278
279 pub event_id: OwnedEventId,
281
282 pub sender: OwnedUserId,
284
285 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
287
288 pub state_key: C::StateKey,
293
294 pub unsigned: C::Unsigned,
296}
297
298#[derive(Clone, Debug, Event)]
300pub struct StrippedStateEvent<C: PossiblyRedactedStateEventContent> {
301 pub content: C,
303
304 pub sender: OwnedUserId,
306
307 pub state_key: C::StateKey,
312}
313
314#[derive(Clone, Debug, Event)]
316pub struct InitialStateEvent<C: StaticStateEventContent> {
317 pub content: C,
319
320 pub state_key: C::StateKey,
327}
328
329impl<C: StaticStateEventContent> InitialStateEvent<C> {
330 pub fn new(content: C) -> Self
334 where
335 C: StaticStateEventContent<StateKey = EmptyStateKey>,
336 {
337 Self { content, state_key: EmptyStateKey }
338 }
339
340 pub fn to_raw(&self) -> Raw<Self> {
348 Raw::new(self).unwrap()
349 }
350
351 pub fn to_raw_any(&self) -> Raw<AnyInitialStateEvent> {
359 self.to_raw().cast()
360 }
361}
362
363impl<C> Default for InitialStateEvent<C>
364where
365 C: StaticStateEventContent<StateKey = EmptyStateKey> + Default,
366{
367 fn default() -> Self {
368 Self { content: Default::default(), state_key: EmptyStateKey }
369 }
370}
371
372impl<C: StaticStateEventContent> Serialize for InitialStateEvent<C> {
373 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
374 where
375 S: serde::Serializer,
376 {
377 let mut state = serializer.serialize_struct("InitialStateEvent", 3)?;
378 state.serialize_field("type", &self.content.event_type())?;
379 state.serialize_field("content", &self.content)?;
380 state.serialize_field("state_key", &self.state_key)?;
381 state.end()
382 }
383}
384
385#[derive(Clone, Debug, Event)]
390pub struct RedactedStateEvent<C: RedactedStateEventContent> {
391 pub content: C,
393
394 pub event_id: OwnedEventId,
396
397 pub sender: OwnedUserId,
399
400 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
402
403 pub room_id: OwnedRoomId,
405
406 pub state_key: C::StateKey,
411
412 pub unsigned: RedactedUnsigned,
414}
415
416#[derive(Clone, Debug, Event)]
421pub struct RedactedSyncStateEvent<C: RedactedStateEventContent> {
422 pub content: C,
424
425 pub event_id: OwnedEventId,
427
428 pub sender: OwnedUserId,
430
431 pub origin_server_ts: MilliSecondsSinceUnixEpoch,
433
434 pub state_key: C::StateKey,
439
440 pub unsigned: RedactedUnsigned,
442}
443
444#[allow(clippy::exhaustive_enums)]
449#[derive(Clone, Debug)]
450pub enum StateEvent<C: StaticStateEventContent + RedactContent>
451where
452 C::Redacted: RedactedStateEventContent,
453{
454 Original(OriginalStateEvent<C>),
456
457 Redacted(RedactedStateEvent<C::Redacted>),
459}
460
461#[allow(clippy::exhaustive_enums)]
466#[derive(Clone, Debug)]
467pub enum SyncStateEvent<C: StaticStateEventContent + RedactContent>
468where
469 C::Redacted: RedactedStateEventContent,
470{
471 Original(OriginalSyncStateEvent<C>),
473
474 Redacted(RedactedSyncStateEvent<C::Redacted>),
476}
477
478#[derive(Clone, Debug, Event)]
480pub struct ToDeviceEvent<C: ToDeviceEventContent> {
481 pub content: C,
483
484 pub sender: OwnedUserId,
486}
487
488impl<C: ToDeviceEventContent> Serialize for ToDeviceEvent<C> {
489 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
490 where
491 S: serde::Serializer,
492 {
493 let mut state = serializer.serialize_struct("ToDeviceEvent", 3)?;
494 state.serialize_field("type", &self.content.event_type())?;
495 state.serialize_field("content", &self.content)?;
496 state.serialize_field("sender", &self.sender)?;
497 state.end()
498 }
499}
500
501#[derive(Clone, Debug, Event)]
503pub struct DecryptedOlmV1Event<C: MessageLikeEventContent> {
504 pub content: C,
506
507 pub sender: OwnedUserId,
509
510 pub recipient: OwnedUserId,
512
513 pub recipient_keys: OlmV1Keys,
515
516 pub keys: OlmV1Keys,
518}
519
520#[derive(Clone, Debug, Deserialize, Serialize)]
522pub struct OlmV1Keys {
523 pub ed25519: String,
525}
526
527#[derive(Clone, Debug, Event)]
529pub struct DecryptedMegolmV1Event<C: MessageLikeEventContent> {
530 pub content: C,
532
533 pub room_id: OwnedRoomId,
535}
536
537#[allow(clippy::exhaustive_enums)]
541#[derive(Clone, Debug)]
542pub enum FullStateEventContent<C: StaticStateEventContent + RedactContent> {
543 Original {
545 content: C,
547
548 prev_content: Option<C::PossiblyRedacted>,
550 },
551
552 Redacted(C::Redacted),
554}
555
556impl<C: StaticStateEventContent + RedactContent> FullStateEventContent<C>
557where
558 C::Redacted: RedactedStateEventContent,
559{
560 pub fn event_type(&self) -> StateEventType {
562 match self {
563 Self::Original { content, .. } => content.event_type(),
564 Self::Redacted(content) => content.event_type(),
565 }
566 }
567
568 pub fn redact(self, version: &RoomVersionId) -> C::Redacted {
575 match self {
576 FullStateEventContent::Original { content, .. } => content.redact(version),
577 FullStateEventContent::Redacted(content) => content,
578 }
579 }
580}
581
582macro_rules! impl_possibly_redacted_event {
583 (
584 $ty:ident ( $content_trait:ident, $redacted_content_trait:ident, $event_type:ident )
585 $( where C::Redacted: $trait:ident<StateKey = C::StateKey>, )?
586 { $($extra:tt)* }
587 ) => {
588 impl<C> $ty<C>
589 where
590 C: $content_trait + RedactContent,
591 C::Redacted: $redacted_content_trait,
592 $( C::Redacted: $trait<StateKey = C::StateKey>, )?
593 {
594 pub fn event_type(&self) -> $event_type {
596 match self {
597 Self::Original(ev) => ev.content.event_type(),
598 Self::Redacted(ev) => ev.content.event_type(),
599 }
600 }
601
602 pub fn event_id(&self) -> &EventId {
604 match self {
605 Self::Original(ev) => &ev.event_id,
606 Self::Redacted(ev) => &ev.event_id,
607 }
608 }
609
610 pub fn sender(&self) -> &UserId {
612 match self {
613 Self::Original(ev) => &ev.sender,
614 Self::Redacted(ev) => &ev.sender,
615 }
616 }
617
618 pub fn origin_server_ts(&self) -> MilliSecondsSinceUnixEpoch {
620 match self {
621 Self::Original(ev) => ev.origin_server_ts,
622 Self::Redacted(ev) => ev.origin_server_ts,
623 }
624 }
625
626 $($extra)*
628 }
629
630 impl<'de, C> Deserialize<'de> for $ty<C>
631 where
632 C: $content_trait + EventContentFromType + RedactContent,
633 C::Redacted: $redacted_content_trait + EventContentFromType,
634 $( C::Redacted: $trait<StateKey = C::StateKey>, )?
635 {
636 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
637 where
638 D: Deserializer<'de>,
639 {
640 let json = Box::<RawJsonValue>::deserialize(deserializer)?;
641 let RedactionDeHelper { unsigned } = from_raw_json_value(&json)?;
642
643 if unsigned.and_then(|u| u.redacted_because).is_some() {
644 Ok(Self::Redacted(from_raw_json_value(&json)?))
645 } else {
646 Ok(Self::Original(from_raw_json_value(&json)?))
647 }
648 }
649 }
650 }
651}
652
653impl_possibly_redacted_event!(
654 MessageLikeEvent(
655 MessageLikeEventContent, RedactedMessageLikeEventContent, MessageLikeEventType
656 ) {
657 pub fn room_id(&self) -> &RoomId {
659 match self {
660 Self::Original(ev) => &ev.room_id,
661 Self::Redacted(ev) => &ev.room_id,
662 }
663 }
664
665 pub fn as_original(&self) -> Option<&OriginalMessageLikeEvent<C>> {
667 as_variant!(self, Self::Original)
668 }
669 }
670);
671
672impl_possibly_redacted_event!(
673 SyncMessageLikeEvent(
674 MessageLikeEventContent, RedactedMessageLikeEventContent, MessageLikeEventType
675 ) {
676 pub fn as_original(&self) -> Option<&OriginalSyncMessageLikeEvent<C>> {
678 as_variant!(self, Self::Original)
679 }
680
681 pub fn into_full_event(self, room_id: OwnedRoomId) -> MessageLikeEvent<C> {
683 match self {
684 Self::Original(ev) => MessageLikeEvent::Original(ev.into_full_event(room_id)),
685 Self::Redacted(ev) => MessageLikeEvent::Redacted(ev.into_full_event(room_id)),
686 }
687 }
688 }
689);
690
691impl_possibly_redacted_event!(
692 StateEvent(StaticStateEventContent, RedactedStateEventContent, StateEventType)
693 where
694 C::Redacted: RedactedStateEventContent<StateKey = C::StateKey>,
695 {
696 pub fn room_id(&self) -> &RoomId {
698 match self {
699 Self::Original(ev) => &ev.room_id,
700 Self::Redacted(ev) => &ev.room_id,
701 }
702 }
703
704 pub fn state_key(&self) -> &C::StateKey {
706 match self {
707 Self::Original(ev) => &ev.state_key,
708 Self::Redacted(ev) => &ev.state_key,
709 }
710 }
711
712 pub fn as_original(&self) -> Option<&OriginalStateEvent<C>> {
714 as_variant!(self, Self::Original)
715 }
716 }
717);
718
719impl_possibly_redacted_event!(
720 SyncStateEvent(StaticStateEventContent, RedactedStateEventContent, StateEventType)
721 where
722 C::Redacted: RedactedStateEventContent<StateKey = C::StateKey>,
723 {
724 pub fn state_key(&self) -> &C::StateKey {
726 match self {
727 Self::Original(ev) => &ev.state_key,
728 Self::Redacted(ev) => &ev.state_key,
729 }
730 }
731
732 pub fn as_original(&self) -> Option<&OriginalSyncStateEvent<C>> {
734 as_variant!(self, Self::Original)
735 }
736
737 pub fn into_full_event(self, room_id: OwnedRoomId) -> StateEvent<C> {
739 match self {
740 Self::Original(ev) => StateEvent::Original(ev.into_full_event(room_id)),
741 Self::Redacted(ev) => StateEvent::Redacted(ev.into_full_event(room_id)),
742 }
743 }
744 }
745);
746
747macro_rules! impl_sync_from_full {
748 ($ty:ident, $full:ident, $content_trait:ident, $redacted_content_trait: ident) => {
749 impl<C> From<$full<C>> for $ty<C>
750 where
751 C: $content_trait + RedactContent,
752 C::Redacted: $redacted_content_trait,
753 {
754 fn from(full: $full<C>) -> Self {
755 match full {
756 $full::Original(ev) => Self::Original(ev.into()),
757 $full::Redacted(ev) => Self::Redacted(ev.into()),
758 }
759 }
760 }
761 };
762}
763
764impl_sync_from_full!(
765 SyncMessageLikeEvent,
766 MessageLikeEvent,
767 MessageLikeEventContent,
768 RedactedMessageLikeEventContent
769);
770impl_sync_from_full!(
771 SyncStateEvent,
772 StateEvent,
773 StaticStateEventContent,
774 RedactedStateEventContent
775);