use crate::Room; use std::collections::HashMap; #[derive(Debug)] pub struct House { address: String, rooms: HashMap, } impl House { pub fn new(address: impl AsRef, rooms: Box<[Room]>) -> Self { let rooms = rooms.into_iter().map(|r| (r.get_name().to_string(), r)).collect(); Self { address: address.as_ref().to_string(), rooms, } } pub fn get_address(&self) -> &str { &self.address } pub fn get_room(&self, key: &str) -> Option<&Room> { self.rooms.get(key) } pub fn get_room_mut(&mut self, key: &str) -> Option<&mut Room> { self.rooms.get_mut(key) } pub fn insert_room(&mut self, room: Room) -> Option { self.rooms.insert(room.get_name().to_string(), room) } pub fn remove_room(&mut self, key: &str) -> Option { self.rooms.remove(key) } pub fn print_status(&self) { println!("HOUSE '{}':", self.address); println!("{}", "=".repeat(32)); for (_, room) in self.rooms.iter() { room.print_status(); println!(); } } } #[cfg(test)] mod tests { use super::*; use crate::{Device, PowerSocket, Thermometer}; fn create_test_house() -> House { House::new( "Best street, 777", Box::new([ Room::new( "main", Box::new([ Device::Thermometer(Thermometer::new("ThermA", 20.0)), Device::PowerSocket(PowerSocket::new("PSocA", 12.34, false)), Device::PowerSocket(PowerSocket::new("PSocB", 10.01, true)), ]), ), Room::new( "bedroom", Box::new([ Device::PowerSocket(PowerSocket::new("PSocC", 11.11, true)), Device::Thermometer(Thermometer::new("ThermB", 17.99)), ]), ), ]), ) } #[test] fn smoke_test() { let mut house = create_test_house(); house.print_status(); assert_eq!(house.address, "Best street, 777"); assert_eq!(house.get_address(), "Best street, 777"); assert_eq!( format!("{}", house.get_room("main").unwrap().get_device("ThermA").unwrap().display()), "DEV:ThermA[ 20.0 ]" ); assert_eq!( format!("{}", house.get_room("main").unwrap().get_device("PSocA").unwrap().display()), "DEV:PSocA[ OFF : 0.0 ]" ); assert_eq!( format!("{}", house.get_room("bedroom").unwrap().get_device("PSocC").unwrap().display()), "DEV:PSocC[ ON : 11.1 ]" ); let Device::PowerSocket(powers_socket) = house.get_room_mut("main").unwrap().get_device_mut("PSocA").unwrap() else { unreachable!() }; powers_socket.set_on(true); assert_eq!( format!("{}", house.get_room("main").unwrap().get_device("PSocA").unwrap().display()), "DEV:PSocA[ ON : 12.3 ]" ); } #[test] fn check_out_of_bounds() { let house = create_test_house(); assert!(house.get_room("absent").is_none()); } #[test] fn test_add_remove() { let mut house = create_test_house(); let room = Room::new("empty", Box::new([])); let result = house.insert_room(room); assert!(result.is_none()); assert_eq!(house.rooms.len(), 3); let Some(result) = house.remove_room("bedroom") else { unreachable!() }; assert_eq!(result.get_name(), "bedroom"); assert_eq!(house.rooms.len(), 2); } }