diff --git a/smart-house/README.md b/smart-house/README.md index 8c73f3b..d803d9e 100644 --- a/smart-house/README.md +++ b/smart-house/README.md @@ -71,8 +71,8 @@ ### Описание/Пошаговая инструкция выполнения домашнего задания: Добавить обработку ошибок: -- [ ] Заменить паники на возврат Option в методах получения комнаты по ключу. -- [ ] Заменить паники на возврат Option в методах получения устройства по ключу. +- [x] Заменить паники на возврат Option в методах получения комнаты по ключу. +- [x] Заменить паники на возврат Option в методах получения устройства по ключу. Доработать хранение объектов: - [ ] Заменить массивы устройств и комнат на ассоциативные коллекции из std. В качестве ключей использовать строки. diff --git a/smart-house/src/house.rs b/smart-house/src/house.rs index f94f241..6c20934 100644 --- a/smart-house/src/house.rs +++ b/smart-house/src/house.rs @@ -13,20 +13,24 @@ impl House { } } - fn check_bounds(&self, idx: usize) { - if idx >= self.rooms.len() { - panic!("Index is out of bounds") + fn is_valid_idx(&self, idx: usize) -> bool { + idx < self.rooms.len() + } + + pub fn get_room(&self, idx: usize) -> Option<&Room> { + if self.is_valid_idx(idx) { + Some(&self.rooms[idx]) + } else { + None } } - pub fn get_room(&self, idx: usize) -> &Room { - self.check_bounds(idx); - &self.rooms[idx] - } - - pub fn get_room_mut(&mut self, idx: usize) -> &mut Room { - self.check_bounds(idx); - &mut self.rooms[idx] + pub fn get_room_mut(&mut self, idx: usize) -> Option<&mut Room> { + if self.is_valid_idx(idx) { + Some(&mut self.rooms[idx]) + } else { + None + } } pub fn print_status(&self) { @@ -70,22 +74,21 @@ mod tests { house.print_status(); assert_eq!(house.address, "Best street, 777"); - assert_eq!(format!("{}", house.get_room(0).get_device(0).display()), "DEV:Thermometer[ 20.0 ]"); - assert_eq!(format!("{}", house.get_room(0).get_device(1).display()), "DEV:PowerSocket[ OFF : 0.0 ]"); - assert_eq!(format!("{}", house.get_room(1).get_device(0).display()), "DEV:PowerSocket[ ON : 11.1 ]"); + assert_eq!(format!("{}", house.get_room(0).unwrap().get_device(0).unwrap().display()), "DEV:Thermometer[ 20.0 ]"); + assert_eq!(format!("{}", house.get_room(0).unwrap().get_device(1).unwrap().display()), "DEV:PowerSocket[ OFF : 0.0 ]"); + assert_eq!(format!("{}", house.get_room(1).unwrap().get_device(0).unwrap().display()), "DEV:PowerSocket[ ON : 11.1 ]"); - let Device::PowerSocket(powers_socket) = house.get_room_mut(0).get_device_mut(1) else { + let Device::PowerSocket(powers_socket) = house.get_room_mut(0).unwrap().get_device_mut(1).unwrap() else { unreachable!() }; powers_socket.set_on(true); - assert_eq!(format!("{}", house.get_room(0).get_device(1).display()), "DEV:PowerSocket[ ON : 12.3 ]"); + assert_eq!(format!("{}", house.get_room(0).unwrap().get_device(1).unwrap().display()), "DEV:PowerSocket[ ON : 12.3 ]"); } #[test] - #[should_panic(expected = "Index is out of bounds")] - fn panic_test() { + fn check_out_of_bounds() { let house = create_test_house(); - house.check_bounds(2); + assert!(house.get_room(2).is_none()); } } diff --git a/smart-house/src/room.rs b/smart-house/src/room.rs index 3718b37..75c0491 100644 --- a/smart-house/src/room.rs +++ b/smart-house/src/room.rs @@ -13,20 +13,21 @@ impl Room { } } - fn check_bounds(&self, idx: usize) { - if idx >= self.devices.len() { - panic!("Index is out of bounds") + 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(&self, idx: usize) -> &Device { - self.check_bounds(idx); - &self.devices[idx] - } - - pub fn get_device_mut(&mut self, idx: usize) -> &mut Device { - self.check_bounds(idx); - &mut self.devices[idx] + 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) { @@ -53,21 +54,20 @@ mod tests { assert_eq!(room.name, "test_room"); room.print_status(); - assert_eq!(format!("{}", room.get_device(0).display()), "DEV:PowerSocket[ OFF : 0.0 ]"); - assert_eq!(format!("{}", room.get_device(1).display()), "DEV:Thermometer[ 21.6 ]"); + 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) else { + 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).display()), "DEV:PowerSocket[ ON : 12.3 ]"); - assert_eq!(format!("{}", room.get_device(1).display()), "DEV:Thermometer[ 21.6 ]"); + 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] - #[should_panic(expected = "Index is out of bounds")] - fn panic_test() { + fn check_out_of_bounds() { let room = Room::new( "test_room", Box::new([ @@ -75,6 +75,6 @@ mod tests { Device::Thermometer(Thermometer::new(21.56)), ]), ); - room.check_bounds(2); + assert!(room.get_device(2).is_none()); } }