use crate::collab_msg::CollabMessage; use bytes::Bytes; use serde::{Deserialize, Serialize}; use std::fmt::Display; use websocket::Message; #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr( feature = "actix_message", derive(actix::Message), rtype(result = "()") )] pub enum RealtimeMessage { Collab(CollabMessage), User(UserMessage), System(SystemMessage), } impl RealtimeMessage { pub fn device_id(&self) -> Option { match self { RealtimeMessage::Collab(msg) => msg.device_id(), RealtimeMessage::User(_) => None, RealtimeMessage::System(_) => None, } } } impl Display for RealtimeMessage { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { RealtimeMessage::Collab(msg) => f.write_fmt(format_args!("Collab:{}", msg)), RealtimeMessage::User(_) => f.write_fmt(format_args!("User")), RealtimeMessage::System(_) => f.write_fmt(format_args!("System")), } } } impl From for Bytes { fn from(msg: RealtimeMessage) -> Self { let bytes = bincode::serialize(&msg).unwrap_or_default(); Bytes::from(bytes) } } impl From for Vec { fn from(msg: RealtimeMessage) -> Self { bincode::serialize(&msg).unwrap_or_default() } } impl TryFrom for RealtimeMessage { type Error = bincode::Error; fn try_from(value: Bytes) -> Result { bincode::deserialize(&value) } } impl TryFrom<&[u8]> for RealtimeMessage { type Error = bincode::Error; fn try_from(value: &[u8]) -> Result { bincode::deserialize(value) } } impl TryFrom<&Vec> for RealtimeMessage { type Error = bincode::Error; fn try_from(value: &Vec) -> Result { bincode::deserialize(value) } } impl TryFrom> for RealtimeMessage { type Error = bincode::Error; fn try_from(value: Vec) -> Result { bincode::deserialize(&value) } } use crate::user::UserMessage; impl TryFrom<&Message> for RealtimeMessage { type Error = anyhow::Error; fn try_from(value: &Message) -> Result { match value { Message::Binary(bytes) => RealtimeMessage::try_from(bytes).map_err(anyhow::Error::from), _ => Err(anyhow::anyhow!("Unsupported message type")), } } } impl TryFrom for RealtimeMessage { type Error = anyhow::Error; fn try_from(value: Message) -> Result { match value { Message::Binary(bytes) => RealtimeMessage::try_from(bytes).map_err(anyhow::Error::from), _ => Err(anyhow::anyhow!("Unsupported message type")), } } } impl From for Message { fn from(msg: RealtimeMessage) -> Self { let bytes = bincode::serialize(&msg).unwrap_or_default(); Message::Binary(bytes) } } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum SystemMessage { RateLimit(u32), KickOff, }