use matrix_sdk_common::deserialized_responses::TimelineEvent;
use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId};
use serde::{Deserialize, Serialize};
use crate::store::SerializableEventContent;
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub enum LatestEventValue {
#[default]
None,
Remote(RemoteLatestEventValue),
RemoteInvite {
event_id: Option<OwnedEventId>,
timestamp: MilliSecondsSinceUnixEpoch,
inviter: Option<OwnedUserId>,
},
LocalIsSending(LocalLatestEventValue),
LocalHasBeenSent {
event_id: OwnedEventId,
value: LocalLatestEventValue,
},
LocalCannotBeSent(LocalLatestEventValue),
}
impl LatestEventValue {
pub fn timestamp(&self) -> Option<MilliSecondsSinceUnixEpoch> {
match self {
Self::None => None,
Self::Remote(remote_latest_event_value) => remote_latest_event_value.timestamp(),
Self::RemoteInvite { timestamp, .. } => Some(*timestamp),
Self::LocalIsSending(LocalLatestEventValue { timestamp, .. })
| Self::LocalHasBeenSent { value: LocalLatestEventValue { timestamp, .. }, .. }
| Self::LocalCannotBeSent(LocalLatestEventValue { timestamp, .. }) => Some(*timestamp),
}
}
pub fn is_local(&self) -> bool {
match self {
Self::LocalIsSending(_)
| Self::LocalHasBeenSent { .. }
| Self::LocalCannotBeSent(_) => true,
Self::None | Self::Remote(_) | Self::RemoteInvite { .. } => false,
}
}
pub fn is_unsent(&self) -> bool {
match self {
Self::LocalIsSending(_) | Self::LocalCannotBeSent(_) => true,
Self::LocalHasBeenSent { .. }
| Self::Remote(_)
| Self::RemoteInvite { .. }
| Self::None => false,
}
}
pub fn is_none(&self) -> bool {
matches!(self, Self::None)
}
pub fn event_id(&self) -> Option<OwnedEventId> {
match self {
Self::Remote(event) => event.event_id(),
Self::RemoteInvite { event_id, .. } => event_id.clone(),
Self::LocalHasBeenSent { event_id, .. } => Some(event_id.clone()),
Self::LocalIsSending(_) | Self::LocalCannotBeSent(_) | Self::None => None,
}
}
}
pub type RemoteLatestEventValue = TimelineEvent;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LocalLatestEventValue {
pub timestamp: MilliSecondsSinceUnixEpoch,
pub content: SerializableEventContent,
}
#[cfg(test)]
mod tests_latest_event_value {
use ruma::{
MilliSecondsSinceUnixEpoch,
events::{AnyMessageLikeEventContent, room::message::RoomMessageEventContent},
owned_event_id,
serde::Raw,
uint,
};
use serde_json::json;
use super::{LatestEventValue, LocalLatestEventValue, RemoteLatestEventValue};
use crate::store::SerializableEventContent;
#[test]
fn test_timestamp_with_none() {
let value = LatestEventValue::None;
assert_eq!(value.timestamp(), None);
}
#[test]
fn test_timestamp_with_remote() {
let value = LatestEventValue::Remote(RemoteLatestEventValue::from_plaintext(
Raw::from_json_string(
json!({
"content": RoomMessageEventContent::text_plain("raclette"),
"type": "m.room.message",
"event_id": "$ev0",
"room_id": "!r0",
"origin_server_ts": 42,
"sender": "@mnt_io:matrix.org",
})
.to_string(),
)
.unwrap(),
));
assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
}
#[test]
fn test_timestamp_with_local_is_sending() {
let value = LatestEventValue::LocalIsSending(LocalLatestEventValue {
timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
RoomMessageEventContent::text_plain("raclette"),
))
.unwrap(),
});
assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
}
#[test]
fn test_timestamp_with_local_has_been_sent() {
let value = LatestEventValue::LocalHasBeenSent {
event_id: owned_event_id!("$ev0"),
value: LocalLatestEventValue {
timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
RoomMessageEventContent::text_plain("raclette"),
))
.unwrap(),
},
};
assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
}
#[test]
fn test_timestamp_with_local_cannot_be_sent() {
let value = LatestEventValue::LocalCannotBeSent(LocalLatestEventValue {
timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
RoomMessageEventContent::text_plain("raclette"),
))
.unwrap(),
});
assert_eq!(value.timestamp(), Some(MilliSecondsSinceUnixEpoch(uint!(42))));
}
#[test]
fn test_event_id_with_none() {
let value = LatestEventValue::None;
assert!(value.event_id().is_none());
}
#[test]
fn test_event_id_with_remote() {
let event_id = owned_event_id!("$ev0");
let value = LatestEventValue::Remote(RemoteLatestEventValue::from_plaintext(
Raw::from_json_string(
json!({
"content": RoomMessageEventContent::text_plain("raclette"),
"type": "m.room.message",
"event_id": event_id,
"room_id": "!r0",
"origin_server_ts": 42,
"sender": "@mnt_io:matrix.org",
})
.to_string(),
)
.unwrap(),
));
assert_eq!(value.event_id(), Some(event_id));
}
#[test]
fn test_event_id_with_local_is_sending() {
let value = LatestEventValue::LocalIsSending(LocalLatestEventValue {
timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
RoomMessageEventContent::text_plain("raclette"),
))
.unwrap(),
});
assert!(value.event_id().is_none());
}
#[test]
fn test_event_id_with_local_has_been_sent() {
let event_id = owned_event_id!("$ev0");
let value = LatestEventValue::LocalHasBeenSent {
event_id: event_id.clone(),
value: LocalLatestEventValue {
timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
RoomMessageEventContent::text_plain("raclette"),
))
.unwrap(),
},
};
assert_eq!(value.event_id(), Some(event_id));
}
#[test]
fn test_event_id_with_local_cannot_be_sent() {
let value = LatestEventValue::LocalCannotBeSent(LocalLatestEventValue {
timestamp: MilliSecondsSinceUnixEpoch(uint!(42)),
content: SerializableEventContent::new(&AnyMessageLikeEventContent::RoomMessage(
RoomMessageEventContent::text_plain("raclette"),
))
.unwrap(),
});
assert!(value.event_id().is_none());
}
}