1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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
}