use std::{fs::File, io::Read, process, time::Duration}; use rumqttc::{Client, Connection, MqttOptions}; use serde::Deserialize; use crate::PROGRAM; #[derive(Deserialize)] pub struct Credentials { pub username: String, pub password: String, } fn default_host() -> String { "localhost".to_string() } fn default_port() -> u16 { 1883 } fn default_id_prefix() -> String { PROGRAM.to_string() } #[derive(Deserialize)] pub struct Config { #[serde(default = "default_host")] pub host: String, #[serde(default = "default_port")] pub port: u16, #[serde(default = "default_id_prefix")] pub id_prefix: String, pub credentials: Option, } impl Config { pub fn mqtt_client(&self) -> (Client, Connection) { let client_id = format!("{}_{}", self.id_prefix, process::id()); let mut options = MqttOptions::new(client_id, &self.host, self.port); if let Some(credentials) = &self.credentials { options.set_credentials(&credentials.username, &credentials.password); } options.set_keep_alive(Duration::from_secs(5)); Client::new(options, 10) } } pub fn get() -> Config { let config = if let Ok(dirs) = xdg::BaseDirectories::with_prefix(PROGRAM) { if let Some(config_file) = dirs.find_config_file("config.toml") { let mut config_file = File::open(config_file).unwrap(); let mut config = String::new(); config_file.read_to_string(&mut config).unwrap(); Some(config) } else { None } } else { None }; let config = config.unwrap_or_default(); toml::from_str(&config).unwrap() }