1use matrix_sdk_common::deserialized_responses::TimelineEvent;
4use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId};
5use serde::{Deserialize, Serialize};
6
7use crate::store::SerializableEventContent;
8
9#[derive(Debug, Default, Clone, Serialize, Deserialize)]
11pub enum LatestEventValue {
12 #[default]
14 None,
15
16 Remote(RemoteLatestEventValue),
18
19 RemoteInvite {
22 event_id: Option<OwnedEventId>,
24
25 timestamp: MilliSecondsSinceUnixEpoch,
27
28 inviter: Option<OwnedUserId>,
30 },
31
32 LocalIsSending(LocalLatestEventValue),
34
35 LocalHasBeenSent {
38 event_id: OwnedEventId,
40
41 value: LocalLatestEventValue,
43 },
44
45 LocalCannotBeSent(LocalLatestEventValue),
48}
49
50impl LatestEventValue {
51 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 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 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 pub fn is_none(&self) -> bool {
112 matches!(self, Self::None)
113 }
114
115 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
127pub type RemoteLatestEventValue = TimelineEvent;
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct LocalLatestEventValue {
134 pub timestamp: MilliSecondsSinceUnixEpoch,
136
137 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}