You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
3.8 KiB
Rust

//! 聊天消息数据结构
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// 消息类型枚举
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum MessageType {
/// 文本消息
Text,
/// 图片消息 (base64 指针)
Image,
/// 系统事件 (上线/离线等)
Event,
/// 消息确认回执
Ack,
/// 心跳 ping
Ping,
/// 心跳 pong
Pong,
}
/// 聊天消息结构
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChatMessage {
/// 消息唯一标识符
pub id: String,
/// 消息类型
#[serde(rename = "type")]
pub message_type: MessageType,
/// 消息内容
pub content: String,
/// 发送者设备 ID
pub from: String,
/// 接收者设备 ID
pub to: String,
/// 时间戳 (Unix timestamp)
pub timestamp: i64,
/// 消息状态
#[serde(default)]
pub status: MessageStatus,
}
/// 消息状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum MessageStatus {
/// 待发送
#[default]
Pending,
/// 已发送
Sent,
/// 已送达
Delivered,
/// 已读
Read,
/// 发送失败
Failed,
}
impl ChatMessage {
/// 创建新的文本消息
pub fn new_text(from: String, to: String, content: String) -> Self {
Self {
id: Uuid::new_v4().to_string(),
message_type: MessageType::Text,
content,
from,
to,
timestamp: chrono::Utc::now().timestamp(),
status: MessageStatus::Pending,
}
}
/// 创建图片消息
pub fn new_image(from: String, to: String, image_data: String) -> Self {
Self {
id: Uuid::new_v4().to_string(),
message_type: MessageType::Image,
content: image_data,
from,
to,
timestamp: chrono::Utc::now().timestamp(),
status: MessageStatus::Pending,
}
}
/// 创建事件消息
pub fn new_event(from: String, to: String, event: &str) -> Self {
Self {
id: Uuid::new_v4().to_string(),
message_type: MessageType::Event,
content: event.to_string(),
from,
to,
timestamp: chrono::Utc::now().timestamp(),
status: MessageStatus::Sent,
}
}
/// 创建消息确认
pub fn new_ack(from: String, to: String, message_id: &str) -> Self {
Self {
id: Uuid::new_v4().to_string(),
message_type: MessageType::Ack,
content: message_id.to_string(),
from,
to,
timestamp: chrono::Utc::now().timestamp(),
status: MessageStatus::Sent,
}
}
/// 创建 ping 消息
pub fn new_ping(from: String) -> Self {
Self {
id: Uuid::new_v4().to_string(),
message_type: MessageType::Ping,
content: String::new(),
from,
to: String::new(),
timestamp: chrono::Utc::now().timestamp(),
status: MessageStatus::Sent,
}
}
/// 创建 pong 消息
pub fn new_pong(from: String, to: String) -> Self {
Self {
id: Uuid::new_v4().to_string(),
message_type: MessageType::Pong,
content: String::new(),
from,
to,
timestamp: chrono::Utc::now().timestamp(),
status: MessageStatus::Sent,
}
}
}
/// WebSocket 连接状态
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConnectionState {
/// 对端设备 ID
pub device_id: String,
/// 是否已连接
pub connected: bool,
/// 最后心跳时间
pub last_heartbeat: i64,
}