use crate::Device; use std::collections::HashMap; #[derive(Debug)] pub struct Room { name: String, devices: HashMap, } impl Room { pub fn new(name: impl AsRef, devices: Box<[Device]>) -> Self { let devices = devices.into_iter().map(|d| (d.get_name().to_string(), d)).collect(); Self { name: name.as_ref().to_string(), devices, } } pub fn get_name(&self) -> &str { &self.name } pub fn get_device(&self, key: &str) -> Option<&Device> { self.devices.get(key) } pub fn get_device_mut(&mut self, key: &str) -> Option<&mut Device> { self.devices.get_mut(key) } pub fn insert_device(&mut self, device: Device) -> Option { self.devices.insert(device.get_name().to_string(), device) } pub fn remove_device(&mut self, key: &str) -> Option { self.devices.remove(key) } pub fn print_status(&self) { println!("ROOM '{}':", self.name); println!("{}", "-".repeat(24)); for (_, device) in self.devices.iter() { device.print_status(); } } } #[cfg(test)] mod tests { use super::*; use crate::{PowerSocket, Thermometer}; #[test] fn smoke_test() { let devices = Box::new([ Device::PowerSocket(PowerSocket::new("PSoc", 12.34, false)), Device::Thermometer(Thermometer::new("Therm", 21.56)), ]); let mut room = Room::new("test_room", devices); assert_eq!(room.name, "test_room"); assert_eq!(room.get_name(), "test_room"); room.print_status(); assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PSoc[ OFF : 0.0 ]"); assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Therm[ 21.6 ]"); let Device::PowerSocket(power_socket) = room.get_device_mut("PSoc").unwrap() else { unreachable!() }; power_socket.set_on(true); assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PSoc[ ON : 12.3 ]"); assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Therm[ 21.6 ]"); } #[test] fn check_out_of_bounds() { let room = Room::new( "test_room", Box::new([ Device::PowerSocket(PowerSocket::new("PSoc", 12.34, false)), Device::Thermometer(Thermometer::new("Therm", 21.56)), ]), ); assert!(room.get_device("dummy").is_none()); } #[test] fn test_add_remove() { let mut room = Room::new( "test_room", Box::new([ Device::PowerSocket(PowerSocket::new("PSoc", 12.34, false)), Device::Thermometer(Thermometer::new("Therm", 21.56)), ]), ); let result = room.insert_device(Device::Thermometer(Thermometer::new("NewTerm", 20.0))); assert!(result.is_none()); assert_eq!(room.devices.len(), 3); let Some(Device::Thermometer(removed)) = room.remove_device("Therm") else { unreachable!() }; assert_eq!(removed.get_name(), "Therm"); assert_eq!(removed.get_temperature(), 21.56); assert_eq!(room.devices.len(), 2); } }