use serde::{Deserialize, Serialize};
use serde_json::Value;
use super::{
conversation::{Conversation, SyncConversationListData},
friend::{FriendRequest, Friendship, SyncFriendListData, SyncFriendRequestsData},
message::{NewMessageData, SyncMessageHistoryData},
user::User,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "event_type")]
pub enum ServerEvent {
#[serde(rename = "new_message")]
NewMessage { data: NewMessageData },
#[serde(rename = "sync_message_history")]
SyncMessageHistory { data: SyncMessageHistoryData },
#[serde(rename = "message_status_updated")]
MessageStatusUpdated { data: MessageStatusUpdatedData },
#[serde(rename = "message_deleted")]
MessageDeleted { data: MessageDeletedData },
#[serde(rename = "sync_conversation_list")]
SyncConversationList { data: SyncConversationListData },
#[serde(rename = "conversation_updated")]
ConversationUpdated { data: Conversation },
#[serde(rename = "conversation_members_updated")]
ConversationMembersUpdated { data: ConversationMembersUpdatedData },
#[serde(rename = "added_to_conversation")]
AddedToConversation { data: Conversation },
#[serde(rename = "removed_from_conversation")]
RemovedFromConversation { data: RemovedFromConversationData },
#[serde(rename = "sync_friend_list")]
SyncFriendList { data: SyncFriendListData },
#[serde(rename = "friendship_updated")]
FriendshipUpdated { data: Friendship },
#[serde(rename = "friend_deleted")]
FriendDeleted { data: FriendDeletedData },
#[serde(rename = "friend_request_received")]
FriendRequestReceived { data: FriendRequest },
#[serde(rename = "friend_request_responded")]
FriendRequestResponded { data: FriendRequest },
#[serde(rename = "sync_friend_requests")]
SyncFriendRequests { data: SyncFriendRequestsData },
#[serde(rename = "user_presence_updated")]
UserPresenceUpdated { data: UserPresenceData },
#[serde(rename = "user_info_updated")]
UserInfoUpdated { data: User },
#[serde(rename = "added_to_blacklist")]
AddedToBlacklist { data: BlacklistEventData },
#[serde(rename = "removed_from_blacklist")]
RemovedFromBlacklist { data: BlacklistEventData },
#[serde(rename = "notification")]
Notification { data: NotificationData },
#[serde(rename = "system_message")]
SystemMessage { data: SystemMessageData },
#[serde(rename = "sync_completed")]
SyncCompleted { data: SyncCompletedData },
#[serde(rename = "data_updated")]
DataUpdated { data: DataUpdatedData },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageStatusUpdatedData {
pub conversation_id: String,
pub message_id: String,
pub status: String,
pub updated_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MessageDeletedData {
pub conversation_id: String,
pub message_id: String,
pub deleted_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationMembersUpdatedData {
pub conversation_id: String,
pub members: Vec<ConversationMemberInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationMemberInfo {
pub user_id: String,
pub role: String,
pub joined_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RemovedFromConversationData {
pub conversation_id: String,
pub removed_by: String,
pub removed_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FriendDeletedData {
pub friend_id: String,
pub deleted_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UserPresenceData {
pub user_id: String,
pub online: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub device_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub last_seen_at: Option<String>,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BlacklistEventData {
pub user_id: String,
pub blocked_user_id: String,
pub timestamp: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NotificationData {
pub id: String,
#[serde(rename = "type")]
pub notification_type: String,
pub title: String,
pub content: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
pub created_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemMessageData {
pub id: String,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
pub created_at: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SyncCompletedData {
pub sync_type: String,
pub timestamp: String,
#[serde(default)]
pub item_count: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataUpdatedData {
pub data_type: String,
pub operation: String, #[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
pub timestamp: String,
}
#[derive(Debug, Clone)]
pub struct RawMqttMessage {
pub topic: String,
pub payload: Vec<u8>,
pub qos: u8,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EventMeta {
pub seq_id: i64,
pub timestamp: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub source: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerEventEnvelope {
#[serde(flatten)]
pub event: ServerEvent,
#[serde(flatten)]
pub meta: EventMeta,
}
impl ServerEvent {
pub fn event_type(&self) -> &'static str {
match self {
ServerEvent::NewMessage { .. } => "new_message",
ServerEvent::SyncMessageHistory { .. } => "sync_message_history",
ServerEvent::MessageStatusUpdated { .. } => "message_status_updated",
ServerEvent::MessageDeleted { .. } => "message_deleted",
ServerEvent::SyncConversationList { .. } => "sync_conversation_list",
ServerEvent::ConversationUpdated { .. } => "conversation_updated",
ServerEvent::ConversationMembersUpdated { .. } => "conversation_members_updated",
ServerEvent::AddedToConversation { .. } => "added_to_conversation",
ServerEvent::RemovedFromConversation { .. } => "removed_from_conversation",
ServerEvent::SyncFriendList { .. } => "sync_friend_list",
ServerEvent::FriendshipUpdated { .. } => "friendship_updated",
ServerEvent::FriendDeleted { .. } => "friend_deleted",
ServerEvent::FriendRequestReceived { .. } => "friend_request_received",
ServerEvent::FriendRequestResponded { .. } => "friend_request_responded",
ServerEvent::SyncFriendRequests { .. } => "sync_friend_requests",
ServerEvent::UserPresenceUpdated { .. } => "user_presence_updated",
ServerEvent::UserInfoUpdated { .. } => "user_info_updated",
ServerEvent::AddedToBlacklist { .. } => "added_to_blacklist",
ServerEvent::RemovedFromBlacklist { .. } => "removed_from_blacklist",
ServerEvent::Notification { .. } => "notification",
ServerEvent::SystemMessage { .. } => "system_message",
ServerEvent::SyncCompleted { .. } => "sync_completed",
ServerEvent::DataUpdated { .. } => "data_updated",
}
}
pub fn is_sync_event(&self) -> bool {
matches!(
self,
ServerEvent::SyncMessageHistory { .. }
| ServerEvent::SyncConversationList { .. }
| ServerEvent::SyncFriendList { .. }
| ServerEvent::SyncFriendRequests { .. }
| ServerEvent::SyncCompleted { .. }
)
}
pub fn conversation_id(&self) -> Option<String> {
match self {
ServerEvent::NewMessage { data } => Some(data.conversation_id.clone()),
ServerEvent::SyncMessageHistory { data } => Some(data.conversation_id.clone()),
ServerEvent::MessageStatusUpdated { data } => Some(data.conversation_id.clone()),
ServerEvent::MessageDeleted { data } => Some(data.conversation_id.clone()),
ServerEvent::ConversationUpdated { data } => Some(data.id.clone()),
ServerEvent::ConversationMembersUpdated { data } => Some(data.conversation_id.clone()),
ServerEvent::AddedToConversation { data } => Some(data.id.clone()),
ServerEvent::RemovedFromConversation { data } => Some(data.conversation_id.clone()),
_ => None,
}
}
pub fn user_id(&self) -> Option<String> {
match self {
ServerEvent::UserPresenceUpdated { data } => Some(data.user_id.clone()),
ServerEvent::UserInfoUpdated { data } => Some(data.id.clone()),
ServerEvent::FriendshipUpdated { data } => Some(data.friend_id.clone()),
ServerEvent::FriendDeleted { data } => Some(data.friend_id.clone()),
_ => None,
}
}
}