From 3f083fd9fd7bc3e463025bf9fe73a969f7a18037 Mon Sep 17 00:00:00 2001 From: Alexander Baranov Date: Sat, 24 Jan 2026 10:23:13 +0300 Subject: [PATCH] homework: remove names --- smart-house/src/device.rs | 23 +++------ smart-house/src/house.rs | 91 +++++++++++++++++---------------- smart-house/src/main.rs | 57 +++++++++++++-------- smart-house/src/power_socket.rs | 23 +++------ smart-house/src/room.rs | 80 +++++++++++------------------ smart-house/src/thermometer.rs | 22 +++----- 6 files changed, 133 insertions(+), 163 deletions(-) diff --git a/smart-house/src/device.rs b/smart-house/src/device.rs index 6879709..73f9910 100644 --- a/smart-house/src/device.rs +++ b/smart-house/src/device.rs @@ -21,13 +21,6 @@ impl Device { pub fn print_status(&self) { 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(), - } - } } impl From for Device { @@ -49,8 +42,8 @@ mod tests { #[test] fn smoke_test() { - let dev_thermometer = Device::Thermometer(Thermometer::new("Therm", 20.1)); - let dev_power_socket = Device::PowerSocket(PowerSocket::new("PSoc", 11.2, false)); + let dev_thermometer = Device::Thermometer(Thermometer::new(20.1)); + let dev_power_socket = Device::PowerSocket(PowerSocket::new(11.2, false)); dev_thermometer.print_status(); dev_power_socket.print_status(); @@ -60,16 +53,16 @@ mod tests { unreachable!() }; - assert_eq!(format!("{}", thermometer.display()), "Therm[ 20.1 ]"); - assert_eq!(format!("{}", power_socket.display()), "PSoc[ OFF : 0.0 ]"); + assert_eq!(format!("{}", thermometer.display()), "Thermometer[ 20.1 ]"); + assert_eq!(format!("{}", power_socket.display()), "PowerSocket[ OFF : 0.0 ]"); } #[test] fn display_test() { - let dev_thermometer = Device::Thermometer(Thermometer::new("Therm", 20.1)); - let dev_power_socket = Device::PowerSocket(PowerSocket::new("PSoc", 11.2, false)); + let dev_thermometer = Device::Thermometer(Thermometer::new(20.1)); + let dev_power_socket = Device::PowerSocket(PowerSocket::new(11.2, false)); - assert_eq!(format!("{}", dev_thermometer.display()), "DEV:Therm[ 20.1 ]"); - assert_eq!(format!("{}", dev_power_socket.display()), "DEV:PSoc[ OFF : 0.0 ]"); + assert_eq!(format!("{}", dev_thermometer.display()), "DEV:Thermometer[ 20.1 ]"); + assert_eq!(format!("{}", dev_power_socket.display()), "DEV:PowerSocket[ OFF : 0.0 ]"); } } diff --git a/smart-house/src/house.rs b/smart-house/src/house.rs index 7c80473..a2e563d 100644 --- a/smart-house/src/house.rs +++ b/smart-house/src/house.rs @@ -3,21 +3,12 @@ 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 new(rooms: HashMap) -> Self { + Self { rooms } } pub fn get_room(&self, key: &str) -> Option<&Room> { @@ -28,28 +19,28 @@ impl House { 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 insert_room(&mut self, name: &str, room: Room) -> Option { + self.rooms.insert(name.to_string(), room) } pub fn remove_room(&mut self, key: &str) -> Option { self.rooms.remove(key) } - pub fn get_device(&self, room: &str, device: &str) -> Result<&Device, Error> { - let Some(room) = self.get_room(room) else { - return Err(Error::new(format!("no room named '{}' found", room))); + pub fn get_device(&self, room_name: &str, device_name: &str) -> Result<&Device, Error> { + let Some(room) = self.get_room(room_name) else { + return Err(Error::new(format!("no room named '{}' found", room_name))); }; - let Some(device) = room.get_device(device) else { - return Err(Error::new(format!("no device named '{}' found in room '{}'", device, room.get_name()))); + let Some(device) = room.get_device(device_name) else { + return Err(Error::new(format!("no device named '{}' found in room '{}'", device_name, room_name))); }; Ok(device) } pub fn print_status(&self) { - println!("HOUSE '{}':", self.address); - println!("{}", "=".repeat(32)); - for (_, room) in self.rooms.iter() { + for (room_name, room) in self.rooms.iter() { + println!("{}:", room_name); + println!("{}", "-".repeat(32)); room.print_status(); println!(); } @@ -63,42 +54,53 @@ mod tests { fn create_test_house() -> House { House::new( - "Best street, 777", - Box::new([ - Room::new( - "main", - Box::new([ - Thermometer::new("ThermA", 20.0).into(), - PowerSocket::new("PSocA", 12.34, false).into(), - PowerSocket::new("PSocB", 10.01, true).into(), - ]), + [ + ( + "main".to_string(), + Room::new( + [ + ("ThermA".to_string(), Thermometer::new(20.0).into()), + ("PSocA".to_string(), PowerSocket::new(12.34, false).into()), + ("PSocB".to_string(), PowerSocket::new(10.01, true).into()), + ] + .into_iter() + .collect(), + ), ), - Room::new( - "bedroom", - Box::new([PowerSocket::new("PSocC", 11.11, true).into(), Thermometer::new("ThermB", 17.99).into()]), + ( + "bedroom".to_string(), + Room::new( + [ + ("PSocC".to_string(), PowerSocket::new(11.11, true).into()), + ("ThermB".to_string(), Thermometer::new(17.99).into()), + ] + .into_iter() + .collect(), + ), ), - ]), + ] + .into_iter() + .collect(), ) } #[test] fn smoke_test() { let mut house = create_test_house(); + assert_eq!(house.rooms.len(), 2); 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 ]" + "DEV:Thermometer[ 20.0 ]" ); assert_eq!( format!("{}", house.get_room("main").unwrap().get_device("PSocA").unwrap().display()), - "DEV:PSocA[ OFF : 0.0 ]" + "DEV:PowerSocket[ OFF : 0.0 ]" ); assert_eq!( format!("{}", house.get_room("bedroom").unwrap().get_device("PSocC").unwrap().display()), - "DEV:PSocC[ ON : 11.1 ]" + "DEV:PowerSocket[ ON : 11.1 ]" ); let Device::PowerSocket(powers_socket) = house.get_room_mut("main").unwrap().get_device_mut("PSocA").unwrap() else { @@ -108,7 +110,7 @@ mod tests { assert_eq!( format!("{}", house.get_room("main").unwrap().get_device("PSocA").unwrap().display()), - "DEV:PSocA[ ON : 12.3 ]" + "DEV:PowerSocket[ ON : 12.3 ]" ); } @@ -121,15 +123,14 @@ mod tests { #[test] fn test_add_remove() { let mut house = create_test_house(); - let room = Room::new("empty", Box::new([])); + let room = Room::new(HashMap::new()); - let result = house.insert_room(room); + let result = house.insert_room("empty", 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); + assert_eq!(result.get_device("ThermB").unwrap().display().to_string(), "DEV:Thermometer[ 18.0 ]"); } #[test] @@ -143,6 +144,6 @@ mod tests { assert_eq!(result.unwrap_err().to_string(), "no device named 'dummy' found in room 'main'"); let result = house.get_device("main", "ThermA"); - assert_eq!(result.unwrap().get_name(), "ThermA"); + assert_eq!(result.unwrap().display().to_string(), "DEV:Thermometer[ 20.0 ]"); } } diff --git a/smart-house/src/main.rs b/smart-house/src/main.rs index 756fefb..9181164 100644 --- a/smart-house/src/main.rs +++ b/smart-house/src/main.rs @@ -2,31 +2,44 @@ use smart_house::{Device, House, PowerSocket, Room, Thermometer}; fn main() { let mut house = House::new( - "A house of dream", - Box::new([ - Room::new( - "Hall", - Box::new([ - Device::PowerSocket(PowerSocket::new("PSocA", 9.5, true)), - Device::Thermometer(Thermometer::new("ThermA", 20.1)), - ]), + [ + ( + "Hall".to_string(), + Room::new( + [ + ("PSocA".to_string(), PowerSocket::new(9.5, true).into()), + ("ThermA".to_string(), Thermometer::new(20.1).into()), + ] + .into_iter() + .collect(), + ), ), - Room::new( - "Main", - Box::new([ - Device::PowerSocket(PowerSocket::new("PSocB", 11.2, true)), - Device::Thermometer(Thermometer::new("ThermB", 24.5)), - Device::PowerSocket(PowerSocket::new("PSocC", 10.4, true)), - ]), + ( + "Main".to_string(), + Room::new( + [ + ("PSocB".to_string(), PowerSocket::new(11.2, true).into()), + ("ThermB".to_string(), Thermometer::new(24.5).into()), + ("PSocC".to_string(), PowerSocket::new(10.4, true).into()), + ] + .into_iter() + .collect(), + ), ), - Room::new( - "Bedroom", - Box::new([ - Device::Thermometer(Thermometer::new("ThermC", 19.3)), - Device::PowerSocket(PowerSocket::new("PSocD", 12.1, true)), - ]), + ( + "Bedroom".to_string(), + Room::new( + [ + ("ThermC".to_string(), Thermometer::new(19.3).into()), + ("PSocD".to_string(), PowerSocket::new(12.1, true).into()), + ] + .into_iter() + .collect(), + ), ), - ]), + ] + .into_iter() + .collect(), ); house.print_status(); diff --git a/smart-house/src/power_socket.rs b/smart-house/src/power_socket.rs index ea0dac1..3b1be09 100644 --- a/smart-house/src/power_socket.rs +++ b/smart-house/src/power_socket.rs @@ -2,22 +2,13 @@ use std::fmt::Display; #[derive(Debug)] pub struct PowerSocket { - name: String, power_rate: f32, on: bool, } impl PowerSocket { - pub fn new(name: impl AsRef, power_rate: f32, on: bool) -> Self { - Self { - name: name.as_ref().to_string(), - power_rate, - on, - } - } - - pub fn get_name(&self) -> &str { - &self.name + pub fn new(power_rate: f32, on: bool) -> Self { + Self { power_rate, on } } pub fn is_on(&self) -> bool { @@ -34,7 +25,7 @@ impl PowerSocket { pub fn display(&self) -> impl Display { let state = if self.is_on() { "ON" } else { "OFF" }; - format!("{}[ {} : {:02.1} ]", self.get_name(), state, self.get_power()) + format!("PowerSocket[ {} : {:02.1} ]", state, self.get_power()) } } @@ -44,7 +35,7 @@ mod tests { #[test] fn smoke_test() { - let mut power_socket = PowerSocket::new("PowerSocket", 12.4, false); + let mut power_socket = PowerSocket::new(12.4, false); assert_eq!(power_socket.power_rate, 12.4); assert!(!power_socket.on); assert!(!power_socket.is_on()); @@ -57,8 +48,8 @@ mod tests { #[test] fn display_test() { - assert_eq!(format!("{}", PowerSocket::new("PS_1", 11.549, false).display()), "PS_1[ OFF : 0.0 ]"); - assert_eq!(format!("{}", PowerSocket::new("PS_2", 11.549, true).display()), "PS_2[ ON : 11.5 ]"); - assert_eq!(format!("{}", PowerSocket::new("PS_3", 11.550, true).display()), "PS_3[ ON : 11.6 ]"); + assert_eq!(format!("{}", PowerSocket::new(11.549, false).display()), "PowerSocket[ OFF : 0.0 ]"); + assert_eq!(format!("{}", PowerSocket::new(11.549, true).display()), "PowerSocket[ ON : 11.5 ]"); + assert_eq!(format!("{}", PowerSocket::new(11.550, true).display()), "PowerSocket[ ON : 11.6 ]"); } } diff --git a/smart-house/src/room.rs b/smart-house/src/room.rs index dfde819..a1a9fbb 100644 --- a/smart-house/src/room.rs +++ b/smart-house/src/room.rs @@ -3,43 +3,33 @@ use std::collections::HashMap; #[derive(Debug)] pub struct Room { - name: String, devices: HashMap, } impl Room { - pub fn new(name: impl AsRef, devices: Box<[Device]>) -> Self { - let devices = devices.into_iter().map(|d| (d.get_name().to_string(), d)).collect(); - Self { - name: name.as_ref().to_string(), - devices, - } + pub fn new(devices: HashMap) -> Self { + Self { devices } } - pub fn get_name(&self) -> &str { - &self.name + pub fn get_device(&self, name: &str) -> Option<&Device> { + self.devices.get(name) } - pub fn get_device(&self, key: &str) -> Option<&Device> { - self.devices.get(key) + pub fn get_device_mut(&mut self, name: &str) -> Option<&mut Device> { + self.devices.get_mut(name) } - pub fn get_device_mut(&mut self, key: &str) -> Option<&mut Device> { - self.devices.get_mut(key) + pub fn insert_device(&mut self, name: &str, device: Device) -> Option { + self.devices.insert(name.to_string(), device) } - pub fn insert_device(&mut self, device: Device) -> Option { - self.devices.insert(device.get_name().to_string(), device) - } - - pub fn remove_device(&mut self, key: &str) -> Option { - self.devices.remove(key) + pub fn remove_device(&mut self, name: &str) -> Option { + self.devices.remove(name) } pub fn print_status(&self) { - println!("ROOM '{}':", self.name); - println!("{}", "-".repeat(24)); - for (_, device) in self.devices.iter() { + for (name, device) in self.devices.iter() { + print!("{} => ", name); device.print_status(); } } @@ -50,58 +40,50 @@ mod tests { use super::*; use crate::{PowerSocket, Thermometer}; + fn create_test_room() -> Room { + let devices = [ + ("PSoc".to_string(), PowerSocket::new(12.34, false).into()), + ("Therm".to_string(), Thermometer::new(21.56).into()), + ] + .into_iter() + .collect::>(); + Room::new(devices) + } + #[test] fn smoke_test() { - let devices = Box::new([ - Device::PowerSocket(PowerSocket::new("PSoc", 12.34, false)), - Device::Thermometer(Thermometer::new("Therm", 21.56)), - ]); - let mut room = Room::new("test_room", devices); - assert_eq!(room.name, "test_room"); - assert_eq!(room.get_name(), "test_room"); + let mut room = create_test_room(); + assert_eq!(room.devices.len(), 2); room.print_status(); - assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PSoc[ OFF : 0.0 ]"); - assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Therm[ 21.6 ]"); + assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PowerSocket[ OFF : 0.0 ]"); + assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Thermometer[ 21.6 ]"); let Device::PowerSocket(power_socket) = room.get_device_mut("PSoc").unwrap() else { unreachable!() }; power_socket.set_on(true); - assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PSoc[ ON : 12.3 ]"); - assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Therm[ 21.6 ]"); + assert_eq!(format!("{}", room.get_device("PSoc").unwrap().display()), "DEV:PowerSocket[ ON : 12.3 ]"); + assert_eq!(format!("{}", room.get_device("Therm").unwrap().display()), "DEV:Thermometer[ 21.6 ]"); } #[test] fn check_out_of_bounds() { - let room = Room::new( - "test_room", - Box::new([ - Device::PowerSocket(PowerSocket::new("PSoc", 12.34, false)), - Device::Thermometer(Thermometer::new("Therm", 21.56)), - ]), - ); + let room = create_test_room(); assert!(room.get_device("dummy").is_none()); } #[test] fn test_add_remove() { - let mut room = Room::new( - "test_room", - Box::new([ - Device::PowerSocket(PowerSocket::new("PSoc", 12.34, false)), - Device::Thermometer(Thermometer::new("Therm", 21.56)), - ]), - ); - let result = room.insert_device(Device::Thermometer(Thermometer::new("NewTerm", 20.0))); + let mut room = create_test_room(); + let result = room.insert_device("NewTerm", Thermometer::new(20.0).into()); assert!(result.is_none()); assert_eq!(room.devices.len(), 3); let Some(Device::Thermometer(removed)) = room.remove_device("Therm") else { unreachable!() }; - assert_eq!(removed.get_name(), "Therm"); assert_eq!(removed.get_temperature(), 21.56); assert_eq!(room.devices.len(), 2); } diff --git a/smart-house/src/thermometer.rs b/smart-house/src/thermometer.rs index 05f3792..a6ca607 100644 --- a/smart-house/src/thermometer.rs +++ b/smart-house/src/thermometer.rs @@ -2,20 +2,12 @@ use std::fmt::Display; #[derive(Debug)] pub struct Thermometer { - name: String, temperature: f32, } impl Thermometer { - pub fn new(name: impl AsRef, temperature: f32) -> Self { - Self { - name: name.as_ref().to_string(), - temperature, - } - } - - pub fn get_name(&self) -> &str { - &self.name + pub fn new(temperature: f32) -> Self { + Self { temperature } } pub fn get_temperature(&self) -> f32 { @@ -23,7 +15,7 @@ impl Thermometer { } pub fn display(&self) -> impl Display { - format!("{}[ {:02.1} ]", self.get_name(), self.get_temperature()) + format!("Thermometer[ {:02.1} ]", self.get_temperature()) } } @@ -33,16 +25,14 @@ mod tests { #[test] fn smoke_test() { - let thermometer = Thermometer::new("TERM", 20.0); + let thermometer = Thermometer::new(20.0); assert_eq!(thermometer.temperature, 20.0); assert_eq!(thermometer.get_temperature(), 20.0); - assert_eq!(thermometer.name, "TERM"); - assert_eq!(thermometer.get_name(), "TERM"); } #[test] fn display_test() { - assert_eq!(format!("{}", Thermometer::new("T1", 19.550).display()), "T1[ 19.5 ]"); - assert_eq!(format!("{}", Thermometer::new("T2", 19.551).display()), "T2[ 19.6 ]"); + assert_eq!(format!("{}", Thermometer::new(19.550).display()), "Thermometer[ 19.5 ]"); + assert_eq!(format!("{}", Thermometer::new(19.551).display()), "Thermometer[ 19.6 ]"); } }