Applied rust fmt
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-04-10 01:33:39 +02:00
parent de9203b8d5
commit 3645b53f7c
29 changed files with 842 additions and 375 deletions

View File

@@ -1,13 +1,20 @@
use std::{fs, net::{Ipv4Addr, SocketAddr}, collections::HashMap};
use std::{
collections::HashMap,
fs,
net::{Ipv4Addr, SocketAddr},
};
use async_recursion::async_recursion;
use regex::{Regex, Captures};
use tracing::{debug, trace};
use rumqttc::{AsyncClient, has_wildcards};
use serde::Deserialize;
use eui48::MacAddress;
use regex::{Captures, Regex};
use rumqttc::{has_wildcards, AsyncClient};
use serde::Deserialize;
use tracing::{debug, trace};
use crate::{devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet, self}, error::{MissingEnv, MissingWildcard, ConfigParseError, DeviceCreationError}};
use crate::{
devices::{self, AudioSetup, ContactSensor, DeviceBox, IkeaOutlet, KasaOutlet, WakeOnLAN},
error::{ConfigParseError, DeviceCreationError, MissingEnv, MissingWildcard},
};
#[derive(Debug, Deserialize)]
pub struct Config {
@@ -26,7 +33,7 @@ pub struct Config {
#[derive(Debug, Clone, Deserialize)]
pub struct OpenIDConfig {
pub base_url: String
pub base_url: String,
}
#[derive(Debug, Clone, Deserialize)]
@@ -56,7 +63,10 @@ impl From<FullfillmentConfig> for SocketAddr {
impl Default for FullfillmentConfig {
fn default() -> Self {
Self { ip: default_fullfillment_ip(), port: default_fullfillment_port() }
Self {
ip: default_fullfillment_ip(),
port: default_fullfillment_port(),
}
}
}
@@ -134,20 +144,33 @@ pub struct PresenceDeviceConfig {
pub mqtt: Option<MqttDeviceConfig>,
// TODO: Maybe make this an option? That way if no timeout is set it will immediately turn the
// device off again?
pub timeout: u64 // Timeout in seconds
pub timeout: u64, // Timeout in seconds
}
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<PresenceDeviceConfig, 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));
}
// TODO: This is not perfect, if the topic is some/+/thing/# this will fail
let offset = config.presence.topic.find('+').or(config.presence.topic.find('#')).unwrap();
let topic = format!("{}/{class}/{identifier}", &config.presence.topic[..offset-1]);
let offset = config
.presence
.topic
.find('+')
.or(config.presence.topic.find('#'))
.unwrap();
let topic = format!(
"{}/{class}/{identifier}",
&config.presence.topic[..offset - 1]
);
trace!("Setting presence mqtt topic: {topic}");
self.mqtt = Some(MqttDeviceConfig { topic });
}
@@ -183,14 +206,14 @@ pub enum Device {
AudioSetup {
#[serde(flatten)]
mqtt: MqttDeviceConfig,
mixer: Box::<Device>,
speakers: Box::<Device>,
mixer: Box<Device>,
speakers: Box<Device>,
},
ContactSensor {
#[serde(flatten)]
mqtt: MqttDeviceConfig,
presence: Option<PresenceDeviceConfig>,
}
},
}
fn default_outlet_type() -> OutletType {
@@ -239,42 +262,77 @@ fn device_box<T: devices::Device + 'static>(device: T) -> DeviceBox {
impl Device {
#[async_recursion]
pub async fn create(self, identifier: &str, config: &Config, client: AsyncClient) -> Result<DeviceBox, DeviceCreationError> {
pub async fn create(
self,
identifier: &str,
config: &Config,
client: AsyncClient,
) -> Result<DeviceBox, DeviceCreationError> {
let device = match self {
Device::IkeaOutlet { info, mqtt, outlet_type, timeout } => {
trace!(id = identifier, "IkeaOutlet [{} in {:?}]", info.name, info.room);
IkeaOutlet::build(identifier, info, mqtt, outlet_type, timeout, client).await
Device::IkeaOutlet {
info,
mqtt,
outlet_type,
timeout,
} => {
trace!(
id = identifier,
"IkeaOutlet [{} in {:?}]",
info.name,
info.room
);
IkeaOutlet::build(identifier, info, mqtt, outlet_type, timeout, client)
.await
.map(device_box)?
},
Device::WakeOnLAN { info, mqtt, mac_address, broadcast_ip } => {
trace!(id = identifier, "WakeOnLan [{} in {:?}]", info.name, info.room);
WakeOnLAN::build(identifier, info, mqtt, mac_address, broadcast_ip, client).await
}
Device::WakeOnLAN {
info,
mqtt,
mac_address,
broadcast_ip,
} => {
trace!(
id = identifier,
"WakeOnLan [{} in {:?}]",
info.name,
info.room
);
WakeOnLAN::build(identifier, info, mqtt, mac_address, broadcast_ip, client)
.await
.map(device_box)?
},
}
Device::KasaOutlet { ip } => {
trace!(id = identifier, "KasaOutlet [{}]", identifier);
device_box(KasaOutlet::new(identifier, ip))
}
Device::AudioSetup { mqtt, mixer, speakers } => {
Device::AudioSetup {
mqtt,
mixer,
speakers,
} => {
trace!(id = identifier, "AudioSetup [{}]", identifier);
// Create the child devices
let mixer_id = format!("{}.mixer", identifier);
let mixer = (*mixer).create(&mixer_id, config, client.clone()).await?;
let speakers_id = format!("{}.speakers", identifier);
let speakers = (*speakers).create(&speakers_id, config, client.clone()).await?;
let speakers = (*speakers)
.create(&speakers_id, config, client.clone())
.await?;
AudioSetup::build(identifier, mqtt, mixer, speakers, client).await
AudioSetup::build(identifier, mqtt, mixer, speakers, client)
.await
.map(device_box)?
},
}
Device::ContactSensor { mqtt, presence } => {
trace!(id = identifier, "ContactSensor [{}]", identifier);
let presence = presence
.map(|p| p.generate_topic("contact", identifier, config))
.transpose()?;
ContactSensor::build(identifier, mqtt, presence, client).await
ContactSensor::build(identifier, mqtt, presence, client)
.await
.map(device_box)?
},
}
};
Ok(device)