71 lines
1.8 KiB
Rust
71 lines
1.8 KiB
Rust
mod ikea_outlet;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use crate::{mqtt::Listener, state::StateOnOff};
|
|
|
|
pub use self::ikea_outlet::IkeaOutlet;
|
|
|
|
macro_rules! add_cast_for {
|
|
($i:ident) => {
|
|
paste::paste! {
|
|
pub trait [< As $i>] {
|
|
fn cast(&self) -> Option<&dyn $i> {
|
|
None
|
|
}
|
|
fn cast_mut(&mut self) -> Option<&mut dyn $i> {
|
|
None
|
|
}
|
|
}
|
|
impl<T: $i> [< As $i>] for T {
|
|
fn cast(&self) -> Option<&dyn $i> {
|
|
Some(self)
|
|
}
|
|
fn cast_mut(&mut self) -> Option<&mut dyn $i> {
|
|
Some(self)
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
add_cast_for!(Listener);
|
|
add_cast_for!(StateOnOff);
|
|
|
|
pub trait Device: AsListener + AsStateOnOff {
|
|
fn get_identifier(&self) -> &str;
|
|
}
|
|
|
|
pub struct Devices {
|
|
devices: HashMap<String, Box<dyn Device>>,
|
|
}
|
|
|
|
impl Devices {
|
|
pub fn new() -> Self {
|
|
Self { devices: HashMap::new() }
|
|
}
|
|
|
|
pub fn add_device<T: Device + 'static>(&mut self, device: T) {
|
|
self.devices.insert(device.get_identifier().to_owned(), Box::new(device));
|
|
}
|
|
|
|
pub fn get_listeners(&mut self) -> Vec<&mut dyn Listener> {
|
|
self.devices.iter_mut().filter_map(|(_, device)| AsListener::cast_mut(device.as_mut())).collect()
|
|
}
|
|
|
|
pub fn get_device(&mut self, name: &str) -> Option<&mut dyn Device> {
|
|
if let Some(device) = self.devices.get_mut(name) {
|
|
return Some(device.as_mut());
|
|
}
|
|
return None;
|
|
}
|
|
}
|
|
|
|
impl Listener for Devices {
|
|
fn notify(&mut self, message: &rumqttc::Publish) {
|
|
self.get_listeners().iter_mut().for_each(|listener| {
|
|
listener.notify(message);
|
|
})
|
|
}
|
|
}
|