diff --git a/src/config.rs b/src/config.rs index 0f31970..d3ca438 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,7 +13,7 @@ use tracing::debug; use crate::{ auth::OpenIDConfig, debug_bridge::DebugBridgeConfig, - devices::{self, AudioSetup, ContactSensor, IkeaOutlet, KasaOutlet, WakeOnLAN}, + devices::{AudioSetup, ContactSensor, Device, IkeaOutlet, KasaOutlet, WakeOnLAN}, error::{ConfigParseError, CreateDeviceError, MissingEnv}, event::EventChannel, hue_bridge::HueBridgeConfig, @@ -34,7 +34,7 @@ pub struct Config { pub hue_bridge: Option, pub debug_bridge: Option, #[serde(default)] - pub devices: HashMap, + pub devices: HashMap, } #[derive(Debug, Clone, Deserialize)] @@ -124,12 +124,12 @@ pub struct MqttDeviceConfig { #[derive(Debug, Clone, Deserialize)] #[serde(tag = "type")] -pub enum Device { - IkeaOutlet(::Config), - WakeOnLAN(::Config), - KasaOutlet(::Config), +pub enum DeviceConfig { AudioSetup(::Config), ContactSensor(::Config), + IkeaOutlet(::Config), + KasaOutlet(::Config), + WakeOnLAN(::Config), } impl Config { @@ -175,37 +175,30 @@ pub trait CreateDevice { Self: Sized; } -impl Device { +macro_rules! create { + (($self:ident, $id:ident, $event_channel:ident, $client:ident, $presence_topic:ident), [ $( $Variant:ident ),* ]) => { + match $self { + $(DeviceConfig::$Variant(c) => Box::new($Variant::create($id, c, $event_channel, $client, $presence_topic)?),)* + } + }; +} + +impl DeviceConfig { pub fn create( self, id: &str, event_channel: &EventChannel, client: &AsyncClient, - presence: &str, - ) -> Result, CreateDeviceError> { - let device: Box = match self { - // TODO: It would be nice if this would be more automatic, not sure how to do that... - Device::IkeaOutlet(c) => { - Box::new(IkeaOutlet::create(id, c, event_channel, client, presence)?) - } - Device::WakeOnLAN(c) => { - Box::new(WakeOnLAN::create(id, c, event_channel, client, presence)?) - } - Device::KasaOutlet(c) => { - Box::new(KasaOutlet::create(id, c, event_channel, client, presence)?) - } - Device::AudioSetup(c) => { - Box::new(AudioSetup::create(id, c, event_channel, client, presence)?) - } - Device::ContactSensor(c) => Box::new(ContactSensor::create( - id, - c, - event_channel, - client, - presence, - )?), - }; - - Ok(device) + presence_topic: &str, + ) -> Result, CreateDeviceError> { + Ok(create! { + (self, id, event_channel, client, presence_topic), [ + AudioSetup, + ContactSensor, + IkeaOutlet, + KasaOutlet, + WakeOnLAN + ] + }) } } diff --git a/src/devices.rs b/src/devices.rs index 85cf5cc..1ebbd6c 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -86,20 +86,6 @@ impl DevicesHandle { Ok(rx.await??) } - // TODO: Finish implementing this - // pub fn create_device(&self, identifier: &str, config: T::Config, presence_topic: &str) -> Result - // where - // T: CreateDevice, - // { - // T::create( - // identifier, - // config, - // self.event_channel, - // self.client, - // presence_topic: presence_topic.to_owned(), - // ) - // } - pub async fn add_device(&self, device: Box) -> Result<(), DevicesError> { let (tx, rx) = oneshot::channel(); self.tx.send(Command::AddDevice { device, tx }).await?; diff --git a/src/devices/audio_setup.rs b/src/devices/audio_setup.rs index 5fe3a4c..1c92e95 100644 --- a/src/devices/audio_setup.rs +++ b/src/devices/audio_setup.rs @@ -19,8 +19,8 @@ use super::{As, Device}; pub struct AudioSetupConfig { #[serde(flatten)] mqtt: MqttDeviceConfig, - mixer: Box, - speakers: Box, + mixer: Box, + speakers: Box, } // TODO: We need a better way to store the children devices