use crate::Device; pub struct Room { name: String, devices: Box<[Device]>, } impl Room { pub fn new(name: impl AsRef, devices: Box<[Device]>) -> Self { Self { name: name.as_ref().to_string(), devices, } } fn is_valid_idx(&self, idx: usize) -> bool { idx < self.devices.len() } pub fn get_device(&self, idx: usize) -> Option<&Device> { if self.is_valid_idx(idx) { Some(&self.devices[idx]) } else { None } } pub fn get_device_mut(&mut self, idx: usize) -> Option<&mut Device> { self.is_valid_idx(idx); Some(&mut self.devices[idx]) } pub fn print_status(&self) { println!("ROOM '{}':", self.name); println!("{}", "-".repeat(24)); for d in self.devices.iter() { d.print_status(); } } } #[cfg(test)] mod tests { use super::*; use crate::{PowerSocket, Thermometer}; #[test] fn smoke_test() { let devices = Box::new([ Device::PowerSocket(PowerSocket::new(12.34, false)), Device::Thermometer(Thermometer::new(21.56)), ]); let mut room = Room::new("test_room", devices); assert_eq!(room.name, "test_room"); room.print_status(); assert_eq!(format!("{}", room.get_device(0).unwrap().display()), "DEV:PowerSocket[ OFF : 0.0 ]"); assert_eq!(format!("{}", room.get_device(1).unwrap().display()), "DEV:Thermometer[ 21.6 ]"); let Device::PowerSocket(power_socket) = room.get_device_mut(0).unwrap() else { unreachable!() }; power_socket.set_on(true); assert_eq!(format!("{}", room.get_device(0).unwrap().display()), "DEV:PowerSocket[ ON : 12.3 ]"); assert_eq!(format!("{}", room.get_device(1).unwrap().display()), "DEV:Thermometer[ 21.6 ]"); } #[test] fn check_out_of_bounds() { let room = Room::new( "test_room", Box::new([ Device::PowerSocket(PowerSocket::new(12.34, false)), Device::Thermometer(Thermometer::new(21.56)), ]), ); assert!(room.get_device(2).is_none()); } }