add House struct

This commit is contained in:
4 changed files with 103 additions and 12 deletions

View File

@@ -35,11 +35,11 @@
- [x] Можно получить ссылку на устройство по указанному индексу. - [x] Можно получить ссылку на устройство по указанному индексу.
- [x] Можно получить мутабельную ссылку на устройство по указанному индексу. - [x] Можно получить мутабельную ссылку на устройство по указанному индексу.
- [x] Выводить в стандартный вывод отчёт о всех устройствах в комнате. - [x] Выводить в стандартный вывод отчёт о всех устройствах в комнате.
- [ ] Опишите тип: умный дом, содержащий массив комнат. Тип должен предоставлять следующий функционал: - [x] Опишите тип: умный дом, содержащий массив комнат. Тип должен предоставлять следующий функционал:
- [ ] Конструктор, принимающий массив комнат. - [x] Конструктор, принимающий массив комнат.
- [ ] Можно получить ссылку на комнату по указанному индексу. - [x] Можно получить ссылку на комнату по указанному индексу.
- [ ] Можно получить мутабельную ссылку на комнату по указанному индексу. - [x] Можно получить мутабельную ссылку на комнату по указанному индексу.
- [ ] Выводить в стандартный вывод отчёт о всех комнатах. - [x] Выводить в стандартный вывод отчёт о всех комнатах.
- Размеры массивов можно выбрать произвольно. - Размеры массивов можно выбрать произвольно.
- В случае, если указан индекс, выходящий за пределы массива, приложение должно аварийно завершаться (макрос `panic!()`). - В случае, если указан индекс, выходящий за пределы массива, приложение должно аварийно завершаться (макрос `panic!()`).

91
smart-house/src/house.rs Normal file
View File

@@ -0,0 +1,91 @@
use crate::Room;
pub struct House {
address: String,
rooms: Box<[Room]>,
}
impl House {
pub fn new(address: impl AsRef<str>, rooms: Box<[Room]>) -> Self {
Self {
address: address.as_ref().to_string(),
rooms,
}
}
fn check_bounds(&self, idx: usize) {
if idx >= self.rooms.len() {
panic!("Index is out of bounds")
}
}
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 print_status(&self) {
println!("HOUSE '{}':", self.address);
println!("{}", "=".repeat(32));
for d in self.rooms.iter() {
d.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(20.0)),
Device::PowerSocket(PowerSocket::new(12.34, false)),
Device::PowerSocket(PowerSocket::new(10.01, true)),
]),
),
Room::new(
"bedroom",
Box::new([Device::PowerSocket(PowerSocket::new(11.11, true)), Device::Thermometer(Thermometer::new(17.99))]),
),
]),
)
}
#[test]
fn smoke_test() {
let mut house = create_test_house();
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 ]");
let Device::PowerSocket(powers_socket) = house.get_room_mut(0).get_device_mut(1) else {
unreachable!()
};
powers_socket.set_on(true);
assert_eq!(format!("{}", house.get_room(0).get_device(1).display()), "DEV:PowerSocket[ ON : 12.3 ]");
}
#[test]
#[should_panic(expected = "Index is out of bounds")]
fn panic_test() {
let house = create_test_house();
house.check_bounds(2);
}
}

View File

@@ -1,8 +1,11 @@
mod device; mod device;
mod house;
mod power_socket; mod power_socket;
mod room; mod room;
mod thermometer; mod thermometer;
pub use device::Device; pub use device::Device;
pub use house::House;
pub use power_socket::PowerSocket; pub use power_socket::PowerSocket;
pub use room::Room;
pub use thermometer::Thermometer; pub use thermometer::Thermometer;

View File

@@ -32,13 +32,11 @@ impl Room {
} }
pub fn print_status(&self) { pub fn print_status(&self) {
println!("{}", "=".repeat(16)); println!("ROOM '{}':", self.name);
println!("{}:", self.name); println!("{}", "-".repeat(24));
println!("{}", "-".repeat(16));
for d in self.devices.iter() { for d in self.devices.iter() {
d.print_status(); d.print_status();
} }
println!("{}", "=".repeat(16));
} }
} }
@@ -60,9 +58,8 @@ mod tests {
assert_eq!(format!("{}", room.get_device(0).display()), "DEV:PowerSocket[ OFF : 0.0 ]"); 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(1).display()), "DEV:Thermometer[ 21.6 ]");
let power_socket = match room.get_device_mut(0) { let Device::PowerSocket(power_socket) = room.get_device_mut(0) else {
Device::PowerSocket(ps) => ps, unreachable!()
_ => unreachable!(),
}; };
power_socket.set_on(true); power_socket.set_on(true);