1use matrix_sdk_common::deserialized_responses::TimelineEvent;
4use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId};
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 LocalIsSending(LocalLatestEventValue),
21
22 LocalHasBeenSent {
25 event_id: OwnedEventId,
27
28 value: LocalLatestEventValue,
30 },
31
32 LocalCannotBeSent(LocalLatestEventValue),
35}
36
37impl LatestEventValue {
38 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 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 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 pub fn is_none(&self) -> bool {
90 matches!(self, Self::None)
91 }
92
93 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
104pub type RemoteLatestEventValue = TimelineEvent;
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
110pub struct LocalLatestEventValue {
111 pub timestamp: MilliSecondsSinceUnixEpoch,
113
114 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}