Hassliebe/src/config.rs

72 lines
1.9 KiB
Rust

use std::fs::File;
use std::io::{ErrorKind, Read};
use std::path::Path;
use anyhow::{Context, Result};
use serde::Deserialize;
use validator::Validate;
use crate::modules;
#[derive(Deserialize, Validate)]
pub struct Mqtt {
#[validate(length(min = 1))]
pub host: String,
pub port: u16,
#[serde(default)]
#[validate(nested)]
pub credentials: Option<MqttCredentials>,
}
#[derive(Deserialize, Validate)]
pub struct MqttCredentials {
pub user: String,
pub password: String,
}
#[derive(Deserialize, Validate)]
pub struct Internal {
#[validate(length(min = 2))]
pub stable_id: String,
}
#[derive(Deserialize, Validate)]
pub struct Config {
#[validate(custom(function = "crate::util::validate_hass_id"))]
pub friendly_id: String,
#[validate(length(min = 1))]
pub display_name: String,
#[validate(nested)]
pub mqtt: Mqtt,
#[validate(nested)]
pub modules: modules::Config,
}
pub fn load(config_file_path: &Path) -> Result<Option<Config>> {
match File::open(config_file_path) {
Ok(mut file) => {
log::info!("Reading configuration file: {}", config_file_path.to_string_lossy());
let mut string_content = String::new();
file.read_to_string(&mut string_content).context("while reading the configuration file")?;
let parsed = toml::from_str::<Config>(string_content.as_str()).context("while parsing the configuration file")?;
Validate::validate(&parsed).context("while validating the configuration file")?;
Ok(Some(parsed))
}
Err(error) if error.kind() == ErrorKind::NotFound => {
log::error!("The configuration file does not exist: {}", config_file_path.to_string_lossy());
log::info!("See the documentation: {}", env!("CARGO_PKG_HOMEPAGE"));
Ok(None)
}
Err(error) => Err(error).context("while opening the configuration file"),
}
}