homework: use hash map and implement Debug trait
This commit is contained in:
@@ -75,8 +75,8 @@
|
|||||||
- [x] Заменить паники на возврат Option в методах получения устройства по ключу.
|
- [x] Заменить паники на возврат Option в методах получения устройства по ключу.
|
||||||
|
|
||||||
Доработать хранение объектов:
|
Доработать хранение объектов:
|
||||||
- [ ] Заменить массивы устройств и комнат на ассоциативные коллекции из std. В качестве ключей использовать строки.
|
- [x] Заменить массивы устройств и комнат на ассоциативные коллекции из std. В качестве ключей использовать строки.
|
||||||
- [ ] Реализовать трейт Debug на всех типах.
|
- [x] Реализовать трейт Debug на всех типах.
|
||||||
- [ ] Добавить возможность динамически добавлять/удалять устройства в комнату.
|
- [ ] Добавить возможность динамически добавлять/удалять устройства в комнату.
|
||||||
- [ ] Добавить возможность динамически добавлять/удалять комнату в дом.
|
- [ ] Добавить возможность динамически добавлять/удалять комнату в дом.
|
||||||
- [ ] Добавить в тип умного дома метод, позволяющий сразу получить ссылку на умное устройство. Метод принимает имя комнаты
|
- [ ] Добавить в тип умного дома метод, позволяющий сразу получить ссылку на умное устройство. Метод принимает имя комнаты
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum Device {
|
pub enum Device {
|
||||||
Thermometer(super::Thermometer),
|
Thermometer(super::Thermometer),
|
||||||
PowerSocket(super::PowerSocket),
|
PowerSocket(super::PowerSocket),
|
||||||
@@ -20,6 +21,13 @@ impl Device {
|
|||||||
pub fn print_status(&self) {
|
pub fn print_status(&self) {
|
||||||
println!("{}", self.display());
|
println!("{}", self.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_name(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Device::Thermometer(thermometer) => thermometer.get_name(),
|
||||||
|
Device::PowerSocket(power_socket) => power_socket.get_name(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -1,35 +1,38 @@
|
|||||||
use crate::Room;
|
use crate::Room;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct House {
|
pub struct House {
|
||||||
address: String,
|
address: String,
|
||||||
rooms: Box<[Room]>,
|
rooms: HashMap<String, Room>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl House {
|
impl House {
|
||||||
pub fn new(address: impl AsRef<str>, rooms: Box<[Room]>) -> Self {
|
pub fn new(address: impl AsRef<str>, rooms: Box<[Room]>) -> Self {
|
||||||
|
let rooms = rooms.into_iter().map(|r| (r.get_name().to_string(), r)).collect();
|
||||||
Self {
|
Self {
|
||||||
address: address.as_ref().to_string(),
|
address: address.as_ref().to_string(),
|
||||||
rooms,
|
rooms,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_idx(&self, idx: usize) -> bool {
|
pub fn get_address(&self) -> &str {
|
||||||
idx < self.rooms.len()
|
&self.address
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_room(&self, idx: usize) -> Option<&Room> {
|
pub fn get_room(&self, key: &str) -> Option<&Room> {
|
||||||
if self.is_valid_idx(idx) { Some(&self.rooms[idx]) } else { None }
|
self.rooms.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_room_mut(&mut self, idx: usize) -> Option<&mut Room> {
|
pub fn get_room_mut(&mut self, key: &str) -> Option<&mut Room> {
|
||||||
if self.is_valid_idx(idx) { Some(&mut self.rooms[idx]) } else { None }
|
self.rooms.get_mut(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_status(&self) {
|
pub fn print_status(&self) {
|
||||||
println!("HOUSE '{}':", self.address);
|
println!("HOUSE '{}':", self.address);
|
||||||
println!("{}", "=".repeat(32));
|
println!("{}", "=".repeat(32));
|
||||||
for d in self.rooms.iter() {
|
for (_, room) in self.rooms.iter() {
|
||||||
d.print_status();
|
room.print_status();
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,24 +71,28 @@ mod tests {
|
|||||||
let mut house = create_test_house();
|
let mut house = create_test_house();
|
||||||
house.print_status();
|
house.print_status();
|
||||||
assert_eq!(house.address, "Best street, 777");
|
assert_eq!(house.address, "Best street, 777");
|
||||||
|
assert_eq!(house.get_address(), "Best street, 777");
|
||||||
|
|
||||||
assert_eq!(format!("{}", house.get_room(0).unwrap().get_device(0).unwrap().display()), "DEV:ThermA[ 20.0 ]");
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{}", house.get_room(0).unwrap().get_device(1).unwrap().display()),
|
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 ]"
|
"DEV:PSocA[ OFF : 0.0 ]"
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{}", house.get_room(1).unwrap().get_device(0).unwrap().display()),
|
format!("{}", house.get_room("bedroom").unwrap().get_device("PSocC").unwrap().display()),
|
||||||
"DEV:PSocC[ ON : 11.1 ]"
|
"DEV:PSocC[ ON : 11.1 ]"
|
||||||
);
|
);
|
||||||
|
|
||||||
let Device::PowerSocket(powers_socket) = house.get_room_mut(0).unwrap().get_device_mut(1).unwrap() else {
|
let Device::PowerSocket(powers_socket) = house.get_room_mut("main").unwrap().get_device_mut("PSocA").unwrap() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
powers_socket.set_on(true);
|
powers_socket.set_on(true);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
format!("{}", house.get_room(0).unwrap().get_device(1).unwrap().display()),
|
format!("{}", house.get_room("main").unwrap().get_device("PSocA").unwrap().display()),
|
||||||
"DEV:PSocA[ ON : 12.3 ]"
|
"DEV:PSocA[ ON : 12.3 ]"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -93,6 +100,6 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn check_out_of_bounds() {
|
fn check_out_of_bounds() {
|
||||||
let house = create_test_house();
|
let house = create_test_house();
|
||||||
assert!(house.get_room(2).is_none());
|
assert!(house.get_room("absent").is_none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ fn main() {
|
|||||||
house.print_status();
|
house.print_status();
|
||||||
|
|
||||||
print!("# Switching off a power socket in Hall... ");
|
print!("# Switching off a power socket in Hall... ");
|
||||||
let Device::PowerSocket(power_socket) = house.get_room_mut(0).unwrap().get_device_mut(0).unwrap() else {
|
let Device::PowerSocket(power_socket) = house.get_room_mut("Hall").unwrap().get_device_mut("PSocA").unwrap() else {
|
||||||
println!("FAILED!");
|
println!("FAILED!");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct PowerSocket {
|
pub struct PowerSocket {
|
||||||
name: String,
|
name: String,
|
||||||
power_rate: f32,
|
power_rate: f32,
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
use crate::Device;
|
use crate::Device;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Room {
|
pub struct Room {
|
||||||
name: String,
|
name: String,
|
||||||
devices: Box<[Device]>,
|
devices: HashMap<String, Device>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Room {
|
impl Room {
|
||||||
pub fn new(name: impl AsRef<str>, devices: Box<[Device]>) -> Self {
|
pub fn new(name: impl AsRef<str>, devices: Box<[Device]>) -> Self {
|
||||||
|
let devices = devices.into_iter().map(|d| (d.get_name().to_string(), d)).collect();
|
||||||
Self {
|
Self {
|
||||||
name: name.as_ref().to_string(),
|
name: name.as_ref().to_string(),
|
||||||
devices,
|
devices,
|
||||||
@@ -17,24 +20,19 @@ impl Room {
|
|||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_valid_idx(&self, idx: usize) -> bool {
|
pub fn get_device(&self, key: &str) -> Option<&Device> {
|
||||||
idx < self.devices.len()
|
self.devices.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_device(&self, idx: usize) -> Option<&Device> {
|
pub fn get_device_mut(&mut self, key: &str) -> Option<&mut Device> {
|
||||||
if self.is_valid_idx(idx) { Some(&self.devices[idx]) } else { None }
|
self.devices.get_mut(key)
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
pub fn print_status(&self) {
|
||||||
println!("ROOM '{}':", self.name);
|
println!("ROOM '{}':", self.name);
|
||||||
println!("{}", "-".repeat(24));
|
println!("{}", "-".repeat(24));
|
||||||
for d in self.devices.iter() {
|
for (_, device) in self.devices.iter() {
|
||||||
d.print_status();
|
device.print_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,16 +53,16 @@ mod tests {
|
|||||||
assert_eq!(room.get_name(), "test_room");
|
assert_eq!(room.get_name(), "test_room");
|
||||||
room.print_status();
|
room.print_status();
|
||||||
|
|
||||||
assert_eq!(format!("{}", room.get_device(0).unwrap().display()), "DEV:PSoc[ OFF : 0.0 ]");
|
assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PSoc[ OFF : 0.0 ]");
|
||||||
assert_eq!(format!("{}", room.get_device(1).unwrap().display()), "DEV:Therm[ 21.6 ]");
|
assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Therm[ 21.6 ]");
|
||||||
|
|
||||||
let Device::PowerSocket(power_socket) = room.get_device_mut(0).unwrap() else {
|
let Device::PowerSocket(power_socket) = room.get_device_mut("PSoc").unwrap() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
power_socket.set_on(true);
|
power_socket.set_on(true);
|
||||||
|
|
||||||
assert_eq!(format!("{}", room.get_device(0).unwrap().display()), "DEV:PSoc[ ON : 12.3 ]");
|
assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PSoc[ ON : 12.3 ]");
|
||||||
assert_eq!(format!("{}", room.get_device(1).unwrap().display()), "DEV:Therm[ 21.6 ]");
|
assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Therm[ 21.6 ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -76,6 +74,6 @@ mod tests {
|
|||||||
Device::Thermometer(Thermometer::new("Therm", 21.56)),
|
Device::Thermometer(Thermometer::new("Therm", 21.56)),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
assert!(room.get_device(2).is_none());
|
assert!(room.get_device("dummy").is_none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Thermometer {
|
pub struct Thermometer {
|
||||||
name: String,
|
name: String,
|
||||||
temperature: f32,
|
temperature: f32,
|
||||||
|
|||||||
Reference in New Issue
Block a user