ruma_events/
unsigned.rs

1use js_int::Int;
2use ruma_common::{
3    serde::{CanBeEmpty, Raw},
4    MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, OwnedUserId,
5};
6use serde::{de::DeserializeOwned, Deserialize};
7
8use super::{
9    relation::{BundledMessageLikeRelations, BundledStateRelations},
10    room::redaction::RoomRedactionEventContent,
11    MessageLikeEventContent, OriginalSyncMessageLikeEvent, PossiblyRedactedStateEventContent,
12};
13
14/// Extra information about a message event that is not incorporated into the event's hash.
15#[derive(Clone, Debug, Deserialize)]
16#[serde(bound = "OriginalSyncMessageLikeEvent<C>: DeserializeOwned")]
17#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
18pub struct MessageLikeUnsigned<C: MessageLikeEventContent> {
19    /// The time in milliseconds that has elapsed since the event was sent.
20    ///
21    /// This field is generated by the local homeserver, and may be incorrect if the local time on
22    /// at least one of the two servers is out of sync, which can cause the age to either be
23    /// negative or greater than it actually is.
24    pub age: Option<Int>,
25
26    /// The client-supplied transaction ID, if the client being given the event is the same one
27    /// which sent it.
28    pub transaction_id: Option<OwnedTransactionId>,
29
30    /// [Bundled aggregations] of related child events.
31    ///
32    /// [Bundled aggregations]: https://spec.matrix.org/latest/client-server-api/#aggregations-of-child-events
33    #[serde(rename = "m.relations", default)]
34    pub relations: BundledMessageLikeRelations<OriginalSyncMessageLikeEvent<C>>,
35}
36
37impl<C: MessageLikeEventContent> MessageLikeUnsigned<C> {
38    /// Create a new `Unsigned` with fields set to `None`.
39    pub fn new() -> Self {
40        Self { age: None, transaction_id: None, relations: BundledMessageLikeRelations::default() }
41    }
42}
43
44impl<C: MessageLikeEventContent> Default for MessageLikeUnsigned<C> {
45    fn default() -> Self {
46        Self::new()
47    }
48}
49
50impl<C: MessageLikeEventContent> CanBeEmpty for MessageLikeUnsigned<C> {
51    /// Whether this unsigned data is empty (all fields are `None`).
52    ///
53    /// This method is used to determine whether to skip serializing the `unsigned` field in room
54    /// events. Do not use it to determine whether an incoming `unsigned` field was present - it
55    /// could still have been present but contained none of the known fields.
56    fn is_empty(&self) -> bool {
57        self.age.is_none() && self.transaction_id.is_none() && self.relations.is_empty()
58    }
59}
60
61/// Extra information about a state event that is not incorporated into the event's hash.
62#[derive(Clone, Debug, Deserialize)]
63#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
64pub struct StateUnsigned<C: PossiblyRedactedStateEventContent> {
65    /// The time in milliseconds that has elapsed since the event was sent.
66    ///
67    /// This field is generated by the local homeserver, and may be incorrect if the local time on
68    /// at least one of the two servers is out of sync, which can cause the age to either be
69    /// negative or greater than it actually is.
70    pub age: Option<Int>,
71
72    /// The client-supplied transaction ID, if the client being given the event is the same one
73    /// which sent it.
74    pub transaction_id: Option<OwnedTransactionId>,
75
76    /// Optional previous content of the event.
77    pub prev_content: Option<C>,
78
79    /// [Bundled aggregations] of related child events.
80    ///
81    /// [Bundled aggregations]: https://spec.matrix.org/latest/client-server-api/#aggregations-of-child-events
82    #[serde(rename = "m.relations", default)]
83    pub relations: BundledStateRelations,
84}
85
86impl<C: PossiblyRedactedStateEventContent> StateUnsigned<C> {
87    /// Create a new `Unsigned` with fields set to `None`.
88    pub fn new() -> Self {
89        Self { age: None, transaction_id: None, prev_content: None, relations: Default::default() }
90    }
91}
92
93impl<C: PossiblyRedactedStateEventContent> CanBeEmpty for StateUnsigned<C> {
94    /// Whether this unsigned data is empty (all fields are `None`).
95    ///
96    /// This method is used to determine whether to skip serializing the `unsigned` field in room
97    /// events. Do not use it to determine whether an incoming `unsigned` field was present - it
98    /// could still have been present but contained none of the known fields.
99    fn is_empty(&self) -> bool {
100        self.age.is_none()
101            && self.transaction_id.is_none()
102            && self.prev_content.is_none()
103            && self.relations.is_empty()
104    }
105}
106
107impl<C: PossiblyRedactedStateEventContent> Default for StateUnsigned<C> {
108    fn default() -> Self {
109        Self::new()
110    }
111}
112
113/// Extra information about a redacted event that is not incorporated into the event's hash.
114#[derive(Clone, Debug, Deserialize)]
115#[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
116pub struct RedactedUnsigned {
117    /// The event that redacted this event, if any.
118    pub redacted_because: Raw<UnsignedRoomRedactionEvent>,
119}
120
121impl RedactedUnsigned {
122    /// Create a new `RedactedUnsigned` with the given redaction event.
123    pub fn new(redacted_because: Raw<UnsignedRoomRedactionEvent>) -> Self {
124        Self { redacted_because }
125    }
126}
127
128/// A redaction event as found in `unsigned.redacted_because`.
129///
130/// While servers usually send this with the `redacts` field (unless nested), the ID of the event
131/// being redacted is known from context wherever this type is used, so it's not reflected as a
132/// field here.
133///
134/// It is intentionally not possible to create an instance of this type other than through `Clone`
135/// or `Deserialize`.
136#[derive(Clone, Debug, Deserialize)]
137#[non_exhaustive]
138pub struct UnsignedRoomRedactionEvent {
139    /// Data specific to the event type.
140    pub content: RoomRedactionEventContent,
141
142    /// The globally unique event identifier for the user who sent the event.
143    pub event_id: OwnedEventId,
144
145    /// The fully-qualified ID of the user who sent this event.
146    pub sender: OwnedUserId,
147
148    /// Timestamp in milliseconds on originating homeserver when this event was sent.
149    pub origin_server_ts: MilliSecondsSinceUnixEpoch,
150
151    /// Additional key-value pairs not signed by the homeserver.
152    #[serde(default)]
153    pub unsigned: MessageLikeUnsigned<RoomRedactionEventContent>,
154}