use crate::ws::WSError; use realtime_entity::collab_msg::CollabMessage; use serde::{Deserialize, Serialize}; use serde_repr::{Deserialize_repr, Serialize_repr}; use tokio_tungstenite::tungstenite::Message; #[derive(Debug, Copy, Clone, Serialize_repr, Deserialize_repr, Eq, PartialEq, Hash)] #[repr(u8)] pub enum BusinessID { CollabId = 1, } /// The message sent through WebSocket. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ClientRealtimeMessage { pub business_id: BusinessID, pub object_id: String, pub payload: Vec, } impl ClientRealtimeMessage { pub fn new(business_id: BusinessID, object_id: String, payload: Vec) -> Self { Self { business_id, object_id, payload, } } } impl TryFrom<&[u8]> for ClientRealtimeMessage { type Error = WSError; fn try_from(bytes: &[u8]) -> Result { let msg = serde_json::from_slice::(bytes)?; Ok(msg) } } impl TryFrom> for ClientRealtimeMessage { type Error = WSError; fn try_from(bytes: Vec) -> Result { let msg = serde_json::from_slice::(&bytes)?; Ok(msg) } } impl TryFrom<&Message> for ClientRealtimeMessage { type Error = WSError; fn try_from(value: &Message) -> Result { match value { Message::Binary(bytes) => { let msg = serde_json::from_slice::(bytes)?; Ok(msg) }, _ => Err(WSError::UnsupportedMsgType), } } } impl From for Message { fn from(msg: ClientRealtimeMessage) -> Self { let bytes = serde_json::to_vec(&msg).unwrap_or_default(); Message::Binary(bytes) } } impl From for ClientRealtimeMessage { fn from(msg: CollabMessage) -> Self { let business_id = BusinessID::CollabId; let object_id = msg.object_id().to_string(); let payload = msg.to_vec(); Self { business_id, object_id, payload, } } } impl TryFrom for CollabMessage { type Error = WSError; fn try_from(value: ClientRealtimeMessage) -> Result { let msg = CollabMessage::from_vec(&value.payload).map_err(|e| WSError::Internal(Box::new(e)))?; Ok(msg) } } impl From for Result { fn from(msg: ClientRealtimeMessage) -> Self { CollabMessage::try_from(msg) } }