builders - done

This commit is contained in:
8 changed files with 55 additions and 29 deletions

View File

@@ -185,7 +185,7 @@
Реализовать билдер для умного дома, позволяющий инициализировать объект умного дома в [таком стиле](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5d0527e4684f726d54dc375829d983f4).
- [ ] До добавления первой комнаты, билдер запрещает добавлять устройства. Это должно контролироваться компилятором.
- [x] До добавления первой комнаты, билдер запрещает добавлять устройства. Это должно контролироваться компилятором.
Реализовать компоновщик для построения отчёта об объектах умного дома в [таком стиле](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c07dfc726e8ccbccdcc2d88a79d3f190).

View File

@@ -0,0 +1,11 @@
use smart_house::{HouseBuilder, PowerSocket, PrintStatus, Thermometer};
fn main() {
let house = HouseBuilder::new()
.add_room("Main")
.add_device("PSockA", PowerSocket::stub(12.0, false))
.add_room("Hall")
.add_device("ThermA", Thermometer::stub(18.5))
.build();
house.print_status();
}

View File

@@ -1,51 +1,53 @@
use crate::{Device, House, Room};
use std::collections::HashMap;
struct HouseBuilder {
pub struct HouseBuilder {
rooms: HashMap<String, Room>,
}
impl HouseBuilder {
fn new() -> Self {
Self {
rooms: HashMap::new()
}
pub fn new() -> Self {
Self { rooms: HashMap::new() }
}
fn build(self) -> House {
House::new(self.rooms)
}
fn add_room(self, name: &str) -> RoomBuilder {
pub fn add_room(self, name: &str) -> RoomBuilder {
RoomBuilder {
parent: self,
name: name.to_string(),
devices: HashMap::new()
}
devices: HashMap::new(),
}
}
struct RoomBuilder {
pub fn build(self) -> House {
House::new(self.rooms)
}
}
impl Default for HouseBuilder {
fn default() -> Self {
Self::new()
}
}
pub struct RoomBuilder {
parent: HouseBuilder,
name: String,
devices: HashMap<String, Device>,
}
impl RoomBuilder {
fn add_device(mut self, name: &str, device: Device) -> Self {
self.devices.insert(name.to_string(), device);
pub fn add_device(mut self, name: &str, device: impl Into<Device>) -> Self {
self.devices.insert(name.to_string(), device.into());
self
}
fn add_room(mut self, name: &str) -> RoomBuilder {
pub fn add_room(mut self, name: &str) -> RoomBuilder {
self.parent.rooms.insert(self.name, Room::new(self.devices));
self.parent.add_room(name)
}
fn build(mut self) -> House {
pub fn build(mut self) -> House {
self.parent.rooms.insert(self.name, Room::new(self.devices));
self.parent.build()
}
}

View File

@@ -1,5 +1,6 @@
use crate::PrintStatus;
use std::fmt::Display;
use std::io::Write;
#[derive(Debug)]
pub enum Device {
@@ -33,8 +34,8 @@ impl From<super::PowerSocket> for Device {
}
impl PrintStatus for Device {
fn print_status(&self) {
println!("{}", self.display());
fn print_status_into(&self, out: &mut impl Write) -> Result<(), std::io::Error> {
out.write_fmt(format_args!("{}", self.display()))
}
}

View File

@@ -1,5 +1,6 @@
use crate::{Device, Error, PrintStatus, Room};
use std::collections::HashMap;
use std::io::Write;
#[derive(Debug)]
pub struct House {
@@ -39,13 +40,15 @@ impl House {
}
impl PrintStatus for House {
fn print_status(&self) {
fn print_status_into(&self, out: &mut impl Write) -> Result<(), std::io::Error> {
for (room_name, room) in self.rooms.iter() {
println!("{}:", room_name);
println!("{}", "-".repeat(32));
room.print_status();
out.write_fmt(format_args!("{}:", room_name))?;
out.write_fmt(format_args!("{}", "-".repeat(32)))?;
room.print_status_into(out)?;
out.write_fmt(format_args!("\n"))?;
println!();
}
Ok(())
}
}

View File

@@ -8,6 +8,7 @@ mod builders;
mod print_status;
mod thermometer;
pub use builders::{HouseBuilder, RoomBuilder};
pub use device::Device;
pub use error::Error;
pub use house::House;

View File

@@ -1,3 +1,9 @@
pub trait PrintStatus {
fn print_status(&self);
fn print_status_into(&self, out: &mut impl std::io::Write) -> Result<(), std::io::Error>;
fn print_status(&self) {
if let Err(e) = self.print_status_into(&mut std::io::stdout()) {
eprintln!("Unexpected print error: {:?}", e);
}
}
}

View File

@@ -1,5 +1,6 @@
use crate::{Device, PrintStatus};
use std::collections::HashMap;
use std::io::Write;
#[derive(Debug)]
pub struct Room {
@@ -29,11 +30,12 @@ impl Room {
}
impl PrintStatus for Room {
fn print_status(&self) {
fn print_status_into(&self, out: &mut impl Write) -> Result<(), std::io::Error> {
for (name, device) in self.devices.iter() {
print!("{} => ", name);
device.print_status();
out.write_fmt(format_args!("{} => ", name))?;
device.print_status_into(out)?;
}
Ok(())
}
}