From a3f3aefc94b68d74d775dccef805a1f13cd47c03 Mon Sep 17 00:00:00 2001 From: Alexander Baranov Date: Thu, 18 Dec 2025 16:37:37 +0300 Subject: [PATCH] add Room struct --- smart-house/README.md | 10 ++--- smart-house/src/lib.rs | 1 + smart-house/src/room.rs | 85 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 smart-house/src/room.rs diff --git a/smart-house/README.md b/smart-house/README.md index c3e3f7e..6412abc 100644 --- a/smart-house/README.md +++ b/smart-house/README.md @@ -30,11 +30,11 @@ - [x] Возвращать текущую мощность: если выключено — ноль, иначе произвольное число. - [x] Опишите тип: умное устройство. Тип должен содержать одно из устройств (умный термометр или розетку) и предоставлять следующий функционал: - [x] Выводить в стандартный вывод сообщение о состоянии устройства. -- [ ] Опишите тип: комната, содержащая массив умных устройств. Тип должен предоставлять следующий функционал: - - [ ] Конструктор, принимающий массив устройств. - - [ ] Можно получить ссылку на устройство по указанному индексу. - - [ ] Можно получить мутабельную ссылку на устройство по указанному индексу. - - [ ] Выводить в стандартный вывод отчёт о всех устройствах в комнате. +- [x] Опишите тип: комната, содержащая массив умных устройств. Тип должен предоставлять следующий функционал: + - [x] Конструктор, принимающий массив устройств. + - [x] Можно получить ссылку на устройство по указанному индексу. + - [x] Можно получить мутабельную ссылку на устройство по указанному индексу. + - [x] Выводить в стандартный вывод отчёт о всех устройствах в комнате. - [ ] Опишите тип: умный дом, содержащий массив комнат. Тип должен предоставлять следующий функционал: - [ ] Конструктор, принимающий массив комнат. - [ ] Можно получить ссылку на комнату по указанному индексу. diff --git a/smart-house/src/lib.rs b/smart-house/src/lib.rs index 882418f..0001a49 100644 --- a/smart-house/src/lib.rs +++ b/smart-house/src/lib.rs @@ -1,5 +1,6 @@ mod device; mod power_socket; +mod room; mod thermometer; pub use device::Device; diff --git a/smart-house/src/room.rs b/smart-house/src/room.rs new file mode 100644 index 0000000..2b0828a --- /dev/null +++ b/smart-house/src/room.rs @@ -0,0 +1,85 @@ +#![allow(unused)] + +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 check_bounds(&self, idx: usize) { + if idx >= self.devices.len() { + panic!("Index is out of bounds") + } + } + + 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 print_status(&self) { + println!("{}", "=".repeat(16)); + println!("{}:", self.name); + println!("{}", "-".repeat(16)); + for d in self.devices.iter() { + d.print_status(); + } + println!("{}", "=".repeat(16)); + } +} + +#[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).display()), "DEV:PowerSocket[ OFF : 0.0 ]"); + assert_eq!(format!("{}", room.get_device(1).display()), "DEV:Thermometer[ 21.6 ]"); + + let power_socket = match room.get_device_mut(0) { + Device::PowerSocket(ps) => ps, + _ => 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 ]"); + } + + #[test] + #[should_panic(expected = "Index is out of bounds")] + fn panic_test() { + let room = Room::new( + "test_room", + Box::new([ + Device::PowerSocket(PowerSocket::new(12.34, false)), + Device::Thermometer(Thermometer::new(21.56)), + ]), + ); + room.check_bounds(2); + } +}