// --------------- // Module overview // --------------- // // DiscordInfo: describes a Discord user's information // // ClientInfo: describes a client's identifying information, // both for websocket and Discord connections. // Webscoket connections have the option to store // DiscordInfo as well for verified connections. // // Client: describes a client, holding ClientInfo and Rc use crate::room::Room; use simple_websockets::{Message, Responder}; use std::cell::RefCell; use std::cmp::{Eq, PartialEq}; use std::hash::{Hash, Hasher}; use std::rc::Rc; pub struct DiscordInfo { pub username: String, pub discriminator: u16, pub id: u64, } impl PartialEq for DiscordInfo { fn eq(&self, other: &Self) -> bool { self.id == other.id } } impl Eq for DiscordInfo {} pub enum ClientInfo { Ws { id: u64, responder: Responder, discord_info: Option, }, Discord { discord_info: DiscordInfo, }, } impl ClientInfo { fn id(&self) -> u64 { match self { Self::Ws { id, discord_info, .. } => match discord_info { // Discord-verified websocket connection Some(discord_info) => discord_info.id, // Anonymous websocket connection None => *id, }, // Discord connection Self::Discord { discord_info } => discord_info.id, } } } impl PartialEq for ClientInfo { fn eq(&self, other: &Self) -> bool { self.id() == other.id() } } impl Eq for ClientInfo {} impl Hash for ClientInfo { fn hash(&self, state: &mut H) { self.id().hash(state) } } pub struct Client { info: ClientInfo, pub room: Rc>, } impl Client { pub fn new(info: ClientInfo, room: Rc>) -> Self { Self { info, room } } pub fn id(&self) -> u64 { match self.info { ClientInfo::Ws { id, .. } => id, ClientInfo::Discord { .. } => unimplemented!("no id for Discord connections"), } } pub fn send(&self, message: Message) -> bool { match &self.info { ClientInfo::Ws { responder, .. } => responder.send(message), ClientInfo::Discord { .. } => { unimplemented!("no networking implementation for Discord connections") } } } // Returns (old_room, &new_room) pub fn switch_rooms(&mut self, new_room: Rc>) -> (Rc>, Rc>) { (std::mem::replace(&mut self.room, new_room), self.room.clone()) } } impl PartialEq for Client { fn eq(&self, other: &Self) -> bool { self.info.eq(&other.info) } } impl Eq for Client {} impl Hash for Client { fn hash(&self, state: &mut H) { self.info.hash(state) } }