use serde::{Serialize, Deserialize}; use tracing::instrument; use crate::{types::http::{ResponseCode, Result}, database::Database}; #[derive(Deserialize, Serialize, Clone, Debug)] pub struct ChatRoom { pub room_id: u64, pub users: Vec, pub name: String } #[derive(Serialize, Clone, Debug)] pub struct ChatMessage { pub message_id: u64, pub user_id: u64, pub room_id: u64, pub date: u64, pub content: String } #[derive(Serialize, Deserialize, Clone, Debug)] #[serde(tag = "type")] pub enum ChatEvent { #[serde(rename = "message")] Message { user_id: u64, message_id: u64, room_id: u64, content: String, date: u64 }, #[serde(rename = "add")] Add { user_id: u64, room: ChatRoom }, #[serde(rename = "leave")] Leave { user_id: u64, room_id: u64 }, #[serde(rename = "typing")] Typing { user_id: u64, room_id: u64 } } impl ChatRoom { #[instrument(skip(db))] pub fn new(db: &Database, users: Vec, name: String) -> Result { let Ok(room) = db.create_room(users, name) else { tracing::error!("Failed to create room"); return Err(ResponseCode::InternalServerError.text("Failed to create room")) }; Ok(room) } #[instrument(skip(db))] pub fn from_user_id(db: &Database, user_id: u64) -> Result> { let Ok(rooms) = db.get_rooms(user_id) else { tracing::error!("Failed to get rooms"); return Err(ResponseCode::InternalServerError.text("Failed to get rooms")) }; Ok(rooms) } #[instrument(skip(db))] pub fn from_user_and_room_id(db: &Database, user_id: u64, room_id: u64) -> Result { let Ok(rooms) = db.get_rooms(user_id) else { tracing::error!("Failed to get room"); return Err(ResponseCode::InternalServerError.text("Failed to get room")) }; for room in rooms { if room.room_id == room_id { return Ok(room); } } return Err(ResponseCode::BadRequest.text("Room doesnt exist or you are not in it")) } #[instrument(skip(db))] pub fn add_user(&self, db: &Database, user_id: u64) -> Result { let Ok(success) = db.add_user_to_room(self.room_id, user_id) else { tracing::error!("Failed to add user to room"); return Err(ResponseCode::InternalServerError.text("Failed to add user to room")) }; Ok(success) } #[instrument(skip(db))] pub fn remove_user(&self, db: &Database, user_id: u64) -> Result { let Ok(success) = db.remove_user_from_room(self.room_id, user_id) else { tracing::error!("Failed to remove user from room"); return Err(ResponseCode::InternalServerError.text("Failed to remove user from room")) }; Ok(success) } #[instrument(skip(db))] pub fn send_message(&self, db: &Database, user_id: u64, content: String) -> Result { let Ok(msg) = db.create_message(self.room_id, user_id, content) else { tracing::error!("Failed to create messgae"); return Err(ResponseCode::InternalServerError.text("Failed to create message")) }; Ok(msg) } #[instrument(skip(db))] pub fn load_old_chat_messages(&self, db: &Database, newest_message: u64, page: u64) -> Result> { let Ok(msgs) = db.load_old_chat_messages(self.room_id, newest_message, page) else { tracing::error!("Failed to load messgaes"); return Err(ResponseCode::InternalServerError.text("Failed to load messages")) }; Ok(msgs) } }