use std::{collections::HashMap, net::Ipv4Addr};
use config::{ConfigError, File, FileFormat};
use once_cell::sync::OnceCell;
use serde::Deserialize;
use crate::{log_level::LogLevel, measure::MeasureKind, sensor_kind::SensorKind};
pub static CONFIG_FILE: OnceCell<&str> = OnceCell::new();
#[derive(Debug, Deserialize)]
pub struct Config {
pub esp: EspConfig,
pub mqtt: Option<MqttConfig>,
#[serde(default)]
pub sensors: Vec<SensorConfig>,
pub wifi: Option<WifiConfig>,
}
impl Config {
pub fn check(config: &str) -> Result<(), ConfigError> {
let c = config::Config::builder()
.add_source(File::from_str(config, FileFormat::Toml))
.build()
.expect("Failed to build configuration")
.try_deserialize::<Config>()?;
println!("Configuration: {:#?}", c);
Ok(())
}
pub fn set(file: &'static str) {
CONFIG_FILE
.set(file)
.expect("Configuration file has already been set")
}
}
#[derive(Debug, Deserialize)]
pub struct EspConfig {
pub id: String,
#[serde(default)]
pub log_level: LogLevel,
}
#[derive(Debug, Deserialize)]
pub struct WifiConfig {
#[serde(default)]
pub auth_method: String,
pub pwd: String,
pub ssid: String,
#[serde(default = "timeout")]
pub timeout: u64,
}
#[derive(Debug, Deserialize)]
pub struct MqttConfig {
#[serde(default = "channel_size")]
pub channel_size: usize,
pub ip: Ipv4Addr,
#[serde(default = "port")]
pub port: u16,
}
#[derive(Clone, Debug, Deserialize)]
pub struct SensorConfig {
#[serde(default = "freq")]
pub freq: u32,
pub kind: SensorKind,
pub metrics: HashMap<MeasureKind, String>,
pub id: String,
}
fn channel_size() -> usize {
50
}
fn freq() -> u32 {
1
}
fn port() -> u16 {
1883
}
fn timeout() -> u64 {
10
}