mqtt_system_monitor/
configuration.rs

1use serde::Deserialize;
2use serde_inline_default::serde_inline_default;
3use std::error::Error;
4
5#[serde_inline_default]
6#[derive(Deserialize)]
7pub struct Mqtt {
8    #[serde_inline_default(String::from("localhost"))]
9    pub host: String,
10    #[serde_inline_default(1883)]
11    pub port: u16,
12
13    #[serde(default)]
14    pub user: String,
15
16    #[serde(default)]
17    pub password: String,
18
19    #[serde_inline_default(String::from("homeassistant"))]
20    #[serde(rename = "registration-prefix")]
21    pub registration_prefix: String,
22
23    #[serde_inline_default(10)]
24    pub update_period: u64,
25
26    #[serde(default = "hostname")]
27    pub entity: String,
28}
29#[derive(Deserialize)]
30pub struct Sensors {
31    pub temperature: Option<String>,
32    pub network: Option<String>,
33}
34
35#[serde_inline_default]
36#[derive(Deserialize)]
37pub struct Configuration {
38    pub mqtt: Mqtt,
39
40    pub sensors: Sensors,
41
42    #[serde_inline_default(2)]
43    #[serde(rename = "log-verbosity")]
44    pub log_verbosity: usize,
45}
46
47fn hostname() -> String {
48    sysinfo::System::host_name().expect("Cannot read hostname")
49}
50
51impl Configuration {
52    pub fn load(path: &str) -> Result<Configuration, Box<dyn Error>> {
53        toml::from_str(std::fs::read_to_string(path)?.as_str()).map_err(|err| err.into())
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60
61    /// Test that we can properly load the default configuration
62    #[test]
63    fn test_default_config() -> Result<(), Box<dyn Error>> {
64        let conf = Configuration::load("conf/mqtt-system-monitor.conf")?;
65
66        assert_eq!(conf.mqtt.host, String::from("localhost"));
67        assert_eq!(conf.mqtt.registration_prefix, String::from("homeassistant"));
68
69        // By default, the entity name will be the hostname of the machine
70        assert_eq!(conf.mqtt.entity, hostname());
71
72        // Sensors are off by default
73        assert_eq!(conf.sensors.temperature, None);
74        assert_eq!(conf.sensors.network, None);
75
76        Ok(())
77    }
78}