Compare commits
2 Commits
master
...
trash/2025
| Author | SHA1 | Date | |
|---|---|---|---|
| 133aa1b9c4 | |||
| e90cdef7b4 |
@@ -21,20 +21,20 @@
|
||||
Для библиотеки:
|
||||
|
||||
- [x] Реализована в виде lib крейта.
|
||||
- [ ] Опишите тип: умный термометр. Тип должен предоставлять следующий функционал:
|
||||
- [ ] Конструктор, принимающий значения полей.
|
||||
- [ ] Возвращать значение текущей температуры (произвольное число).
|
||||
- [ ] Опишите тип: умная розетка. Тип должен предоставлять следующий функционал:
|
||||
- [ ] Конструктор, принимающий значения полей.
|
||||
- [ ] Включение/выключение + возможность узнать текущее состояние.
|
||||
- [ ] Возвращать текущую мощность: если выключено — ноль, иначе произвольное число.
|
||||
- [ ] Опишите тип: умное устройство. Тип должен содержать одно из устройств (умный термометр или розетку) и предоставлять следующий функционал:
|
||||
- [ ] Выводить в стандартный вывод сообщение о состоянии устройства.
|
||||
- [ ] Опишите тип: комната, содержащая массив умных устройств. Тип должен предоставлять следующий функционал:
|
||||
- [ ] Конструктор, принимающий массив устройств.
|
||||
- [ ] Можно получить ссылку на устройство по указанному индексу.
|
||||
- [ ] Можно получить мутабельную ссылку на устройство по указанному индексу.
|
||||
- [ ] Выводить в стандартный вывод отчёт о всех устройствах в комнате.
|
||||
- [x] Опишите тип: умный термометр. Тип должен предоставлять следующий функционал:
|
||||
- [x] Конструктор, принимающий значения полей.
|
||||
- [x] Возвращать значение текущей температуры (произвольное число).
|
||||
- [x] Опишите тип: умная розетка. Тип должен предоставлять следующий функционал:
|
||||
- [x] Конструктор, принимающий значения полей.
|
||||
- [x] Включение/выключение + возможность узнать текущее состояние.
|
||||
- [x] Возвращать текущую мощность: если выключено — ноль, иначе произвольное число.
|
||||
- [x] Опишите тип: умное устройство. Тип должен содержать одно из устройств (умный термометр или розетку) и предоставлять следующий функционал:
|
||||
- [x] Выводить в стандартный вывод сообщение о состоянии устройства.
|
||||
- [x] Опишите тип: комната, содержащая массив умных устройств. Тип должен предоставлять следующий функционал:
|
||||
- [x] Конструктор, принимающий массив устройств.
|
||||
- [x] Можно получить ссылку на устройство по указанному индексу.
|
||||
- [x] Можно получить мутабельную ссылку на устройство по указанному индексу.
|
||||
- [x] Выводить в стандартный вывод отчёт о всех устройствах в комнате.
|
||||
- [ ] Опишите тип: умный дом, содержащий массив комнат. Тип должен предоставлять следующий функционал:
|
||||
- [ ] Конструктор, принимающий массив комнат.
|
||||
- [ ] Можно получить ссылку на комнату по указанному индексу.
|
||||
|
||||
14
smart-house/src/device.rs
Normal file
14
smart-house/src/device.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
#![allow(unused)]
|
||||
|
||||
mod power_socket;
|
||||
mod thermometer;
|
||||
|
||||
pub trait Device {
|
||||
fn print_status(&self);
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn as_mut_any(&mut self) -> &mut dyn Any;
|
||||
}
|
||||
|
||||
pub use power_socket::PowerSocket;
|
||||
use std::any::Any;
|
||||
pub use thermometer::Thermometer;
|
||||
72
smart-house/src/device/power_socket.rs
Normal file
72
smart-house/src/device/power_socket.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use crate::device::Device;
|
||||
use std::any::Any;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub struct PowerSocket {
|
||||
power_rate: f32,
|
||||
on: bool,
|
||||
}
|
||||
|
||||
impl PowerSocket {
|
||||
pub fn new(power_rate: f32, on: bool) -> Self {
|
||||
Self { power_rate, on }
|
||||
}
|
||||
|
||||
pub fn is_on(&self) -> bool {
|
||||
self.on
|
||||
}
|
||||
|
||||
pub fn set_on(&mut self, on: bool) {
|
||||
self.on = on
|
||||
}
|
||||
|
||||
pub fn get_power(&self) -> f32 {
|
||||
if self.on { self.power_rate } else { 0.0 }
|
||||
}
|
||||
|
||||
pub fn display(&self) -> impl Display {
|
||||
let state = if self.is_on() { "ON" } else { "OFF" };
|
||||
format!("PowerSocket[ {} : {:02.1} ]", state, self.get_power())
|
||||
}
|
||||
}
|
||||
|
||||
impl Device for PowerSocket {
|
||||
fn print_status(&self) {
|
||||
println!("{}", self.display())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_any(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn smoke_test() {
|
||||
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());
|
||||
assert_eq!(power_socket.get_power(), 0.0);
|
||||
|
||||
power_socket.set_on(true);
|
||||
assert!(power_socket.is_on());
|
||||
assert_eq!(power_socket.get_power(), 12.4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_test() {
|
||||
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 ]");
|
||||
}
|
||||
}
|
||||
54
smart-house/src/device/thermometer.rs
Normal file
54
smart-house/src/device/thermometer.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use std::any::Any;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub struct Thermometer {
|
||||
temperature: f32,
|
||||
}
|
||||
|
||||
impl Thermometer {
|
||||
pub fn new(temperature: f32) -> Self {
|
||||
Self { temperature }
|
||||
}
|
||||
|
||||
pub fn get_temperature(&self) -> f32 {
|
||||
self.temperature
|
||||
}
|
||||
|
||||
pub fn display(&self) -> impl Display {
|
||||
format!("Thermometer[ {:02.1} ]", self.get_temperature())
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Device for Thermometer {
|
||||
fn print_status(&self) {
|
||||
println!("{}", self.display())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_mut_any(&mut self) -> &mut dyn Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn smoke_test() {
|
||||
let thermometer = Thermometer::new(20.0);
|
||||
assert_eq!(thermometer.temperature, 20.0);
|
||||
assert_eq!(thermometer.get_temperature(), 20.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn display_test() {
|
||||
assert_eq!(format!("{}", Thermometer::new(19.550).display()), "Thermometer[ 19.5 ]");
|
||||
assert_eq!(format!("{}", Thermometer::new(19.551).display()), "Thermometer[ 19.6 ]");
|
||||
}
|
||||
}
|
||||
1
smart-house/src/house.rs
Normal file
1
smart-house/src/house.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
|
||||
mod device;
|
||||
mod house;
|
||||
mod room;
|
||||
|
||||
77
smart-house/src/room.rs
Normal file
77
smart-house/src/room.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
#![allow(unused)]
|
||||
use crate::device::Device;
|
||||
|
||||
struct Room<'a> {
|
||||
name: String,
|
||||
devices: &'a mut [Box<dyn Device>],
|
||||
}
|
||||
|
||||
impl<'a> Room<'a> {
|
||||
pub fn new(name: impl AsRef<str>, devices: &'a mut [Box<dyn Device>]) -> Self {
|
||||
Self {
|
||||
name: name.as_ref().to_string(),
|
||||
devices,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&'a self, idx: usize) -> &'a dyn Device {
|
||||
if idx >= self.devices.len() {
|
||||
panic!("Index is out of bounds")
|
||||
}
|
||||
self.devices[idx].as_ref()
|
||||
}
|
||||
|
||||
pub fn get_mut(&'a mut self, idx: usize) -> &'a mut dyn Device {
|
||||
if idx >= self.devices.len() {
|
||||
panic!("Index is out of bounds")
|
||||
}
|
||||
self.devices[idx].as_mut()
|
||||
}
|
||||
|
||||
pub fn print(&self) {
|
||||
println!("{}", "=".repeat(16));
|
||||
println!("{}:", self.name);
|
||||
println!("{}", "-".repeat(16));
|
||||
for d in self.devices.iter() {
|
||||
d.print_status();
|
||||
}
|
||||
println!("{}", "=".repeat(16));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::device::{PowerSocket, Thermometer};
|
||||
use std::fmt::format;
|
||||
use std::mem;
|
||||
|
||||
#[test]
|
||||
fn smoke_test() {
|
||||
let mut devices = Box::new([Box::new(PowerSocket::new(12.34, false)) as Box<dyn Device>, Box::new(Thermometer::new(21.56))]);
|
||||
let mut room = Room::new("test_room", &mut *devices);
|
||||
assert_eq!(room.name, "test_room");
|
||||
room.print();
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", room.get(0).as_any().downcast_ref::<PowerSocket>().unwrap().display()),
|
||||
"PowerSocket[ OFF : 0.0 ]"
|
||||
);
|
||||
assert_eq!(
|
||||
format!("{}", room.get(1).as_any().downcast_ref::<Thermometer>().unwrap().display()),
|
||||
"Thermometer[ 21.6 ]"
|
||||
);
|
||||
|
||||
room.get_mut(0).as_mut_any().downcast_mut::<PowerSocket>().unwrap().set_on(true);
|
||||
|
||||
// room.print(); // TODO satisfy compiler
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "Index is out of bounds")]
|
||||
fn panic_test() {
|
||||
let mut devices = [Box::new(PowerSocket::new(12.34, false)) as Box<dyn Device>, Box::new(Thermometer::new(21.56))];
|
||||
let mut room = Room::new("test_room", &mut devices);
|
||||
room.get(2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user