use anyhow::{Context, Result}; use serde::Deserialize; use std::{env, fs::File, io::BufReader}; /// Email server credentials. #[derive(Deserialize)] pub struct EmailServer { pub server_name: String, pub email: String, pub password: String, } /// UTC offset for time formatting. #[derive(Deserialize)] pub struct UtcOffset { pub hours: i8, pub minutes: i8, } /// Error messages for localization. #[derive(Deserialize)] pub struct ErrorMessages { pub captcha_error: String, pub email_error: String, } /// Field localization strings in a form with label and invalid feedback on wrong field input. #[derive(Deserialize)] pub struct Field { pub label: String, pub invalid_feedback: String, } /// Localization strings. #[derive(Deserialize)] pub struct Strings { pub description: String, pub title: String, pub name_field: Field, pub email_field: Field, /// No invalid feedback because it is optional. pub telefon_field_label: String, pub message_field: Field, pub captcha_field: Field, pub submit: String, pub success: String, } /// Configuration. #[derive(Deserialize)] pub struct Config { /// The language tag of the HTML file. pub lang: String, /// The path prefix of all routes. pub path_prefix: String, /// The server socket address including port. pub socket_address: String, pub email_server: EmailServer, /// From mailbox. pub email_from: String, /// To mailbox. pub email_to: String, pub log_file: String, pub utc_offset: UtcOffset, pub error_messages: ErrorMessages, pub strings: Strings, } impl Config { /// Parses the configuration from the config path in the environment variable. pub fn build() -> Result { // The environment variable with the path to the config file. let config_file_var = "CF_CONFIG_FILE"; let config_path = env::var(config_file_var) .with_context(|| format!("Environment variable {config_file_var} missing!"))?; let file = File::open(&config_path) .with_context(|| format!("Can not open the config file at the path {config_path}"))?; let reader = BufReader::new(file); let config = serde_yaml::from_reader(reader).context("Can not parse the YAML config file!")?; Ok(config) } }