diff --git a/smart-house/README.md b/smart-house/README.md index 8c9ff59..ccc3d67 100644 --- a/smart-house/README.md +++ b/smart-house/README.md @@ -189,8 +189,8 @@ Реализовать компоновщик для построения отчёта об объектах умного дома в [таком стиле](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c07dfc726e8ccbccdcc2d88a79d3f190). -- [ ] Использовать статический полиморфизм (дженерики). -- [ ] Вызов метода report() должен выводить в терминал отчёт обо всех добавленных объектах. +- [x] Использовать статический полиморфизм (дженерики). +- [x] Вызов метода report() должен выводить в терминал отчёт обо всех добавленных объектах. Добавить возможность добавления callback-ов в объект комнаты, которые срабатывают при добавлении новых устройств в комнату (паттерн Observer). diff --git a/smart-house/src/bin/reporter.rs b/smart-house/src/bin/reporter.rs new file mode 100644 index 0000000..8cb544f --- /dev/null +++ b/smart-house/src/bin/reporter.rs @@ -0,0 +1,17 @@ +use smart_house::{HouseBuilder, PowerSocket, Reporter, Thermometer}; + +fn main() { + let house = HouseBuilder::new() + .add_room("Main") + .add_device("PSockB", PowerSocket::stub(12.0, false)) + .add_room("Hall") + .add_device("ThermB", Thermometer::stub(18.5)) + .build(); + + Reporter::new() + .add_reportable(house.get_room("Main").unwrap()) + .add_reportable(house.get_device("Main", "PSockB").unwrap()) + .add_reportable(house.get_room("Hall").unwrap()) + .add_reportable(house.get_device("Hall", "ThermB").unwrap()) + .report(); +} diff --git a/smart-house/src/device.rs b/smart-house/src/device.rs index 16835b5..88681ff 100644 --- a/smart-house/src/device.rs +++ b/smart-house/src/device.rs @@ -34,7 +34,7 @@ impl From for Device { } impl PrintStatus for Device { - fn print_status_into(&self, out: &mut impl Write) -> Result<(), std::io::Error> { + fn print_status_into(&self, out: &mut dyn Write) -> Result<(), std::io::Error> { out.write_fmt(format_args!("{}", self.display())) } } diff --git a/smart-house/src/house.rs b/smart-house/src/house.rs index 9741ad4..ede8ec6 100644 --- a/smart-house/src/house.rs +++ b/smart-house/src/house.rs @@ -40,7 +40,7 @@ impl House { } impl PrintStatus for House { - fn print_status_into(&self, out: &mut impl Write) -> Result<(), std::io::Error> { + fn print_status_into(&self, out: &mut dyn Write) -> Result<(), std::io::Error> { for (room_name, room) in self.rooms.iter() { out.write_fmt(format_args!("{}:", room_name))?; out.write_fmt(format_args!("{}", "-".repeat(32)))?; diff --git a/smart-house/src/lib.rs b/smart-house/src/lib.rs index 35c3fd0..162173b 100644 --- a/smart-house/src/lib.rs +++ b/smart-house/src/lib.rs @@ -6,6 +6,7 @@ mod power_socket; mod room; mod builders; mod print_status; +mod reporter; mod thermometer; pub use builders::{HouseBuilder, RoomBuilder}; @@ -14,5 +15,6 @@ pub use error::Error; pub use house::House; pub use power_socket::PowerSocket; pub use print_status::PrintStatus; +pub use reporter::Reporter; pub use room::Room; pub use thermometer::Thermometer; diff --git a/smart-house/src/print_status.rs b/smart-house/src/print_status.rs index 92308dc..9a0c4f3 100644 --- a/smart-house/src/print_status.rs +++ b/smart-house/src/print_status.rs @@ -1,5 +1,5 @@ pub trait PrintStatus { - fn print_status_into(&self, out: &mut impl std::io::Write) -> Result<(), std::io::Error>; + fn print_status_into(&self, out: &mut dyn std::io::Write) -> Result<(), std::io::Error>; fn print_status(&self) { if let Err(e) = self.print_status_into(&mut std::io::stdout()) { diff --git a/smart-house/src/reporter.rs b/smart-house/src/reporter.rs new file mode 100644 index 0000000..42541fc --- /dev/null +++ b/smart-house/src/reporter.rs @@ -0,0 +1,30 @@ +use crate::PrintStatus; + +pub struct Reporter<'a> { + reportables: Vec<&'a dyn PrintStatus>, +} + +impl<'a> Reporter<'a> { + pub fn new() -> Self { + Self { reportables: Vec::new() } + } + + pub fn add_reportable(mut self, reportable: &'a T) -> Self { + self.reportables.push(reportable); + self + } + + pub fn report(&self) { + println!("{}", "=".repeat(16)); + for reportable in &self.reportables { + reportable.print_status(); + println!("\n{}", "=".repeat(16)); + } + } +} + +impl<'a> Default for Reporter<'a> { + fn default() -> Self { + Self::new() + } +} diff --git a/smart-house/src/room.rs b/smart-house/src/room.rs index f54c5a9..5078307 100644 --- a/smart-house/src/room.rs +++ b/smart-house/src/room.rs @@ -30,7 +30,7 @@ impl Room { } impl PrintStatus for Room { - fn print_status_into(&self, out: &mut impl Write) -> Result<(), std::io::Error> { + fn print_status_into(&self, out: &mut dyn Write) -> Result<(), std::io::Error> { for (name, device) in self.devices.iter() { out.write_fmt(format_args!("{} => ", name))?; device.print_status_into(out)?;