// SPDX-FileCopyrightText: 2025 Tomasz Kramkowski // SPDX-License-Identifier: GPL-3.0-or-later use std::{ fs, io, path::{Path, PathBuf}, 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_root() -> PathBuf { option_env!("DEFAULT_ROOT") .unwrap_or(&format!("/var/run/{PROGRAM}")) .into() } fn default_host() -> String { "localhost".to_string() } fn default_port() -> u16 { 1883 } fn default_id() -> String { PROGRAM.to_string() } #[derive(Deserialize)] pub struct Config { #[serde(default = "default_root")] pub root: PathBuf, #[serde(default = "default_host")] pub host: String, #[serde(default = "default_port")] pub port: u16, pub credentials: Option, #[serde(default = "default_id")] pub id: String, } impl Config { pub fn mqtt_client(&self) -> (Client, Connection) { let client_id = format!("{}_{}", self.id, 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)); options.set_max_packet_size(10 * 1024 * 1024, 10 * 1024 * 1024); Client::new(options, 10) } } pub fn load>(path: P) -> anyhow::Result { let config = match fs::read_to_string(&path) { Ok(s) => Ok(s), Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(String::new()), Err(e) => Err(e), }?; Ok(toml::from_str(&config)?) }