use crate::error::{Result, TidewayError};
use super::message::Message;
use std::collections::{HashMap, HashSet};
use tokio::sync::mpsc;
use serde::Serialize;
pub struct Connection {
id: String,
user_id: Option<String>,
metadata: HashMap<String, String>,
rooms: HashSet<String>,
sender: mpsc::Sender<Message>,
}
impl Connection {
pub(crate) fn new(id: String, sender: mpsc::Sender<Message>) -> Self {
Self {
id,
user_id: None,
metadata: HashMap::new(),
rooms: HashSet::new(),
sender,
}
}
pub fn id(&self) -> &str {
&self.id
}
pub fn user_id(&self) -> Option<&str> {
self.user_id.as_deref()
}
pub fn set_user_id(&mut self, user_id: String) {
self.user_id = Some(user_id);
}
pub fn metadata(&self) -> &HashMap<String, String> {
&self.metadata
}
pub fn set_metadata(&mut self, key: String, value: String) {
self.metadata.insert(key, value);
}
pub fn rooms(&self) -> &HashSet<String> {
&self.rooms
}
pub async fn send(&self, msg: Message) -> Result<()> {
self.sender.send(msg).await.map_err(|_| {
TidewayError::internal("Failed to send message: channel full or connection closed")
})
}
pub async fn send_text(&self, text: impl Into<String>) -> Result<()> {
self.send(Message::Text(text.into())).await
}
pub async fn send_json<T: Serialize>(&self, data: &T) -> Result<()> {
let json = serde_json::to_string(data)
.map_err(|e| TidewayError::internal(format!("Failed to serialize JSON: {}", e)))?;
self.send_text(json).await
}
pub async fn send_binary(&self, data: Vec<u8>) -> Result<()> {
self.send(Message::Binary(data)).await
}
pub async fn close(&self) -> Result<()> {
self.send(Message::Close(None)).await
}
pub fn join_room(&mut self, room: impl Into<String>) {
self.rooms.insert(room.into());
}
pub fn leave_room(&mut self, room: &str) {
self.rooms.remove(room);
}
pub fn is_in_room(&self, room: &str) -> bool {
self.rooms.contains(room)
}
}