builders - done
This commit is contained in:
@@ -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).
|
||||
|
||||
|
||||
11
smart-house/src/bin/room_builder.rs
Normal file
11
smart-house/src/bin/room_builder.rs
Normal 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();
|
||||
}
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(self) -> House {
|
||||
House::new(self.rooms)
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomBuilder {
|
||||
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()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user