use std::collections::HashMap; use std::sync::Arc; use tokio::sync::Mutex; #[derive(Clone, Debug)] pub struct RoomInfo { pub room_id: String, pub name: String, pub is_encrypted: bool, } impl RoomInfo { pub fn new(room_id: String, name: String, is_encrypted: bool) -> Self { Self { room_id, name, is_encrypted, } } } #[derive(Default)] pub struct RoomManager { pub rooms: HashMap, } impl RoomManager { pub fn new() -> Self { Self { rooms: HashMap::new(), } } pub fn add_room(&mut self, room: RoomInfo) { self.rooms.insert(room.room_id.clone(), room); } pub fn remove_room(&mut self, room_id: &str) { self.rooms.remove(room_id); } pub fn get_room(&self, room_id: &str) -> Option<&RoomInfo> { self.rooms.get(room_id) } pub fn list_rooms(&self) -> Vec<&RoomInfo> { self.rooms.values().collect() } pub fn room_count(&self) -> usize { self.rooms.len() } } pub type SharedRoomManager = Arc>; #[cfg(test)] mod tests { use super::*; #[test] fn new_creates_empty_manager() { let mgr = RoomManager::new(); assert_eq!(mgr.room_count(), 0); } #[test] fn default_creates_empty_manager() { let mgr = RoomManager::default(); assert_eq!(mgr.room_count(), 0); } #[test] fn add_room_inserts_room() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new( "!room1:server".into(), "Room One".into(), false, )); assert_eq!(mgr.room_count(), 1); } #[test] fn add_multiple_rooms() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new("!r1:server".into(), "A".into(), false)); mgr.add_room(RoomInfo::new("!r2:server".into(), "B".into(), true)); assert_eq!(mgr.room_count(), 2); } #[test] fn get_room_returns_correct_room() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new( "!room1:server".into(), "Room One".into(), false, )); let room = mgr.get_room("!room1:server").unwrap(); assert_eq!(room.name, "Room One"); assert!(!room.is_encrypted); } #[test] fn get_room_returns_none_for_missing() { let mgr = RoomManager::new(); assert!(mgr.get_room("!nonexistent:server").is_none()); } #[test] fn remove_room_deletes_room() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new( "!room1:server".into(), "Room One".into(), false, )); assert_eq!(mgr.room_count(), 1); mgr.remove_room("!room1:server"); assert_eq!(mgr.room_count(), 0); } #[test] fn remove_nonexistent_room_is_noop() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new( "!room1:server".into(), "Room One".into(), false, )); mgr.remove_room("!nonexistent:server"); assert_eq!(mgr.room_count(), 1); } #[test] fn add_room_overwrites_existing() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new( "!room1:server".into(), "Old Name".into(), false, )); mgr.add_room(RoomInfo::new( "!room1:server".into(), "New Name".into(), true, )); assert_eq!(mgr.room_count(), 1); assert_eq!(mgr.get_room("!room1:server").unwrap().name, "New Name"); assert!(mgr.get_room("!room1:server").unwrap().is_encrypted); } #[test] fn list_rooms_returns_all() { let mut mgr = RoomManager::new(); mgr.add_room(RoomInfo::new("!r1:server".into(), "A".into(), false)); mgr.add_room(RoomInfo::new("!r2:server".into(), "B".into(), true)); assert_eq!(mgr.list_rooms().len(), 2); } }