matrix_sdk_base/
latest_event.rs

1//! The Latest Event basic types.
2
3use matrix_sdk_common::deserialized_responses::TimelineEvent;
4use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId};
5use serde::{Deserialize, Serialize};
6
7use crate::store::SerializableEventContent;
8
9/// A latest event value!
10#[derive(Debug, Default, Clone, Serialize, Deserialize)]
11pub enum LatestEventValue {
12    /// No value has been computed yet, or no candidate value was found.
13    #[default]
14    None,
15
16    /// The latest event represents a remote event.
17    Remote(RemoteLatestEventValue),
18
19    /// The latest event represents an invite, i.e. the current user has been
20    /// invited to join a room.
21    RemoteInvite {
22        /// The ID of the invite event.
23        event_id: Option<OwnedEventId>,
24
25        /// The timestamp of the invite event.
26        timestamp: MilliSecondsSinceUnixEpoch,
27
28        /// The user ID of the inviter.
29        inviter: Option<OwnedUserId>,
30    },
31
32    /// The latest event represents a local event that is sending.
33    LocalIsSending(LocalLatestEventValue),
34
35    /// The latest event represents a local event that has been sent
36    /// successfully. It should come quickly as a [`Self::Remote`].
37    LocalHasBeenSent {
38        /// ID of the sent event.
39        event_id: OwnedEventId,
40
41        /// Value, as for other `Self::Local*` variants.
42        value: LocalLatestEventValue,
43    },
44
45    /// The latest event represents a local event that cannot be sent, either
46    /// because a previous local event, or this local event cannot be sent.
47    LocalCannotBeSent(LocalLatestEventValue),
48}
49
50impl LatestEventValue {
51    /// Get the timestamp of the [`LatestEventValue`].
52    ///
53    /// - If it's [`None`], it returns `None`.
54    /// - If it's [`Remote`], it returns the [`TimelineEvent::timestamp`].
55    /// - If it's [`RemoteInvite`], it returns the
56    ///   [`SyncOrStrippedState::timestamp`].
57    /// - If it's [`LocalIsSending`],[`LocalHasBeenSent`] or
58    ///   [`LocalCannotBeSent`], it returns the
59    ///   [`LocalLatestEventValue::timestamp`] value.
60    ///
61    /// [`None`]: LatestEventValue::None
62    /// [`Remote`]: LatestEventValue::Remote
63    /// [`RemoteInvite`]: LatestEventValue::RemoteInvite
64    /// [`LocalIsSending`]: LatestEventValue::LocalIsSending
65    /// [`LocalHasBeenSent`]: LatestEventValue::LocalHasBeenSent
66    /// [`LocalCannotBeSent`]: LatestEventValue::LocalCannotBeSent
67    /// [`SyncOrStrippedState::timestamp`]: crate::deserialized_responses::SyncOrStrippedState::timestamp
68    pub fn timestamp(&self) -> Option<MilliSecondsSinceUnixEpoch> {
69        match self {
70            Self::None => None,
71            Self::Remote(remote_latest_event_value) => remote_latest_event_value.timestamp(),
72            Self::RemoteInvite { timestamp, .. } => Some(*timestamp),
73            Self::LocalIsSending(LocalLatestEventValue { timestamp, .. })
74            | Self::LocalHasBeenSent { value: LocalLatestEventValue { timestamp, .. }, .. }
75            | Self::LocalCannotBeSent(LocalLatestEventValue { timestamp, .. }) => Some(*timestamp),
76        }
77    }
78
79    /// Check whether the [`LatestEventValue`] represents a local value or not,
80    /// i.e. it is [`LocalIsSending`] or [`LocalCannotBeSent`].
81    ///
82    /// [`LocalIsSending`]: LatestEventValue::LocalIsSending
83    /// [`LocalCannotBeSent`]: LatestEventValue::LocalCannotBeSent
84    pub fn is_local(&self) -> bool {
85        match self {
86            Self::LocalIsSending(_)
87            | Self::LocalHasBeenSent { .. }
88            | Self::LocalCannotBeSent(_) => true,
89            Self::None | Self::Remote(_) | Self::RemoteInvite { .. } => false,
90        }
91    }
92
93    /// Check whether the [`LatestEventValue`] represents an unsent event, i.e.
94    /// is [`LocalIsSending`] nor [`LocalCannotBeSent`].
95    ///
96    /// [`LocalIsSending`]: LatestEventValue::LocalIsSending
97    /// [`LocalCannotBeSent`]: LatestEventValue::LocalCannotBeSent
98    pub fn is_unsent(&self) -> bool {
99        match self {
100            Self::LocalIsSending(_) | Self::LocalCannotBeSent(_) => true,
101            Self::LocalHasBeenSent { .. }
102            | Self::Remote(_)
103            | Self::RemoteInvite { .. }
104            | Self::None => false,
105        }
106    }
107
108    /// Check whether the [`LatestEventValue`] is not set, i.e. [`None`].
109    ///
110    /// [`None`]: LatestEventValue::None
111    pub fn is_none(&self) -> bool {
112        matches!(self, Self::None)
113    }
114
115    /// Get the event ID (if it exists) of the event representing the
116    /// [`LatestEventValue`].
117    pub fn event_id(&self) -> Option<OwnedEventId> {
118        match self {
119            Self::Remote(event) => event.event_id(),
120            Self::RemoteInvite { event_id, .. } => event_id.clone(),
121            Self::LocalHasBeenSent { event_id, .. } => Some(event_id.clone()),
122            Self::LocalIsSending(_) | Self::LocalCannotBeSent(_) | Self::None => None,
123        }
124    }
125}
126
127/// Represents the value for [`LatestEventValue::Remote`].
128pub type RemoteLatestEventValue = TimelineEvent;
129
130/// Represents the value for [`LatestEventValue::LocalIsSending`] and
131/// [`LatestEventValue::LocalCannotBeSent`].
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct LocalLatestEventValue {
134    /// The time where the event has been created (by this module).
135    pub timestamp: MilliSecondsSinceUnixEpoch,
136
137    /// The content of the local event.
138    pub content: SerializableEventContent,
139}
140
141#[cfg(test)]
142mod tests_latest_event_value {
143    use ruma::{
144        MilliSecondsSinceUnixEpoch,
145        events::{AnyMessageLikeEventContent, room::message::RoomMessageEventContent},
146        owned_event_id,
147        serde::Raw,
148        uint,
149    };
150    use serde_json::json;
151
152    use super::{LatestEventValue, LocalLatestEventValue, RemoteLatestEventValue};
153    use crate::store::SerializableEventContent;
154
155    #[test]
156    fn test_timestamp_with_none() {
157        let value = LatestEventValue::None;
158
159        assert_eq!(value.timestamp(), None);
160    }
161
162    #[test]
163    fn test_timestamp_with_remote() {
164        let value = LatestEventValue::Remote(RemoteLatestEventValue::from_plaintext(
165            Raw::from_json_string(
166                json!({
167                    "content": RoomMessageEventContent::text_plain("raclette"),
168                    "type": "m.room.message",
169                    "event_id": "$ev0",
170                    "room_id": "!r0",
171                    "origin_server_ts": 42,
172                    "sender": "@mnt_io:matrix.org",
173                })
174                .to_string(),
175            )
176            .unwrap(),
177        ));
178
179        assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
180    }
181
182    #[test]
183    fn test_timestamp_with_local_is_sending() {
184        let value = LatestEventValue::LocalIsSending(LocalLatestEventValue {
185            timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
186            content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
187                RoomMessageEventContent::text_plain("raclette"),
188            ))
189            .unwrap(),
190        });
191
192        assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
193    }
194
195    #[test]
196    fn test_timestamp_with_local_has_been_sent() {
197        let value = LatestEventValue::LocalHasBeenSent {
198            event_id: owned_event_id!("$ev0"),
199            value: LocalLatestEventValue {
200                timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
201                content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
202                    RoomMessageEventContent::text_plain("raclette"),
203                ))
204                .unwrap(),
205            },
206        };
207
208        assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
209    }
210
211    #[test]
212    fn test_timestamp_with_local_cannot_be_sent() {
213        let value = LatestEventValue::LocalCannotBeSent(LocalLatestEventValue {
214            timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
215            content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
216                RoomMessageEventContent::text_plain("raclette"),
217            ))
218            .unwrap(),
219        });
220
221        assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
222    }
223
224    #[test]
225    fn test_event_id_with_none() {
226        let value = LatestEventValue::None;
227
228        assert!(value.event_id().is_none());
229    }
230
231    #[test]
232    fn test_event_id_with_remote() {
233        let event_id = owned_event_id!("$ev0");
234        let value = LatestEventValue::Remote(RemoteLatestEventValue::from_plaintext(
235            Raw::from_json_string(
236                json!({
237                    "content": RoomMessageEventContent::text_plain("raclette"),
238                    "type": "m.room.message",
239                    "event_id": event_id,
240                    "room_id": "!r0",
241                    "origin_server_ts": 42,
242                    "sender": "@mnt_io:matrix.org",
243                })
244                .to_string(),
245            )
246            .unwrap(),
247        ));
248
249        assert_eq!(value.event_id(), Some(event_id));
250    }
251
252    #[test]
253    fn test_event_id_with_local_is_sending() {
254        let value = LatestEventValue::LocalIsSending(LocalLatestEventValue {
255            timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
256            content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
257                RoomMessageEventContent::text_plain("raclette"),
258            ))
259            .unwrap(),
260        });
261
262        assert!(value.event_id().is_none());
263    }
264
265    #[test]
266    fn test_event_id_with_local_has_been_sent() {
267        let event_id = owned_event_id!("$ev0");
268        let value = LatestEventValue::LocalHasBeenSent {
269            event_id: event_id.clone(),
270            value: LocalLatestEventValue {
271                timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
272                content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
273                    RoomMessageEventContent::text_plain("raclette"),
274                ))
275                .unwrap(),
276            },
277        };
278
279        assert_eq!(value.event_id(), Some(event_id));
280    }
281
282    #[test]
283    fn test_event_id_with_local_cannot_be_sent() {
284        let value = LatestEventValue::LocalCannotBeSent(LocalLatestEventValue {
285            timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
286            content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
287                RoomMessageEventContent::text_plain("raclette"),
288            ))
289            .unwrap(),
290        });
291
292        assert!(value.event_id().is_none());
293    }
294}