Improved code
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-01-18 20:03:33 +01:00
parent d36a6eb518
commit b6bf8a82a2
8 changed files with 110 additions and 103 deletions

View File

@@ -7,7 +7,7 @@ use rumqttc::{AsyncClient, has_wildcards};
use serde::Deserialize;
use eui48::MacAddress;
use crate::{devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet}, error::{FailedToParseConfig, MissingEnv, MissingWildcard, Error, FailedToCreateDevice}};
use crate::{devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet, self}, error::{FailedToParseConfig, MissingEnv, MissingWildcard, Error, FailedToCreateDevice}};
#[derive(Debug, Deserialize)]
pub struct Config {
@@ -132,7 +132,7 @@ pub struct PresenceDeviceConfig {
impl PresenceDeviceConfig {
/// Set the mqtt topic to an appropriate value if it is not already set
fn generate_topic(&mut self, class: &str, identifier: &str, config: &Config) -> Result<(), MissingWildcard> {
fn generate_topic(mut self, class: &str, identifier: &str, config: &Config) -> Result<PresenceDeviceConfig, MissingWildcard> {
if self.mqtt.is_none() {
if !has_wildcards(&config.presence.topic) {
return Err(MissingWildcard::new(&config.presence.topic).into());
@@ -145,7 +145,7 @@ impl PresenceDeviceConfig {
self.mqtt = Some(MqttDeviceConfig { topic });
}
Ok(())
Ok(self)
}
}
@@ -213,23 +213,27 @@ impl Config {
}
}
// Quick helper function to box up the devices,
// passing in Box::new would be ideal, however the return type is incorrect
// Maybe there is a better way to solve this?
fn device_box<T: devices::Device + 'static>(device: T) -> DeviceBox {
let a: DeviceBox = Box::new(device);
a
}
impl Device {
#[async_recursion]
pub async fn create(self, identifier: &str, config: &Config, client: AsyncClient) -> Result<DeviceBox, FailedToCreateDevice> {
let device: Result<DeviceBox, Error> = match self {
Device::IkeaOutlet { info, mqtt, kettle } => {
trace!(id = identifier, "IkeaOutlet [{} in {:?}]", info.name, info.room);
match IkeaOutlet::build(&identifier, info, mqtt, kettle, client).await {
Ok(device) => Ok(Box::new(device)),
Err(err) => Err(err),
}
IkeaOutlet::build(&identifier, info, mqtt, kettle, client).await
.map(device_box)
},
Device::WakeOnLAN { info, mqtt, mac_address } => {
trace!(id = identifier, "WakeOnLan [{} in {:?}]", info.name, info.room);
match WakeOnLAN::build(&identifier, info, mqtt, mac_address, client).await {
Ok(device) => Ok(Box::new(device)),
Err(err) => Err(err),
}
WakeOnLAN::build(&identifier, info, mqtt, mac_address, client).await
.map(device_box)
},
Device::KasaOutlet { ip } => {
trace!(id = identifier, "KasaOutlet [{}]", identifier);
@@ -243,22 +247,18 @@ impl Device {
let speakers_id = identifier.to_owned() + ".speakers";
let speakers = (*speakers).create(&speakers_id, config, client.clone()).await?;
match AudioSetup::build(&identifier, mqtt, mixer, speakers, client).await {
Ok(device) => Ok(Box::new(device)),
Err(err) => Err(err),
}
AudioSetup::build(&identifier, mqtt, mixer, speakers, client).await
.map(device_box)
},
Device::ContactSensor { mqtt, mut presence } => {
Device::ContactSensor { mqtt, presence } => {
trace!(id = identifier, "ContactSensor [{}]", identifier);
if let Some(presence) = &mut presence {
presence.generate_topic("contact", &identifier, &config)
.map_err(|err| FailedToCreateDevice::new(&identifier, err.into()))?;
}
let presence = presence
.map(|p| p.generate_topic("contact", &identifier, &config))
.transpose()
.map_err(|err| FailedToCreateDevice::new(&identifier, err.into()))?;
match ContactSensor::build(&identifier, mqtt, presence, client).await {
Ok(device) => Ok(Box::new(device)),
Err(err) => Err(err),
}
ContactSensor::build(&identifier, mqtt, presence, client).await
.map(device_box)
},
};