matrix_sdk_base/
latest_event.rs

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