From f3ee4e2413e0ad750201a3bbc868620505b39114 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Fri, 29 Nov 2024 14:45:35 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20Code=20tweak?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagetop/src/config.rs | 52 ++++++++++++++++++++++++------------------- pagetop/src/locale.rs | 44 ++++++++++++------------------------ 2 files changed, 43 insertions(+), 53 deletions(-) diff --git a/pagetop/src/config.rs b/pagetop/src/config.rs index 765ef81e..07924057 100644 --- a/pagetop/src/config.rs +++ b/pagetop/src/config.rs @@ -3,13 +3,9 @@ //! These settings are loaded from [TOML](https://toml.io) files as `key = value` pairs and mapped //! into type-safe structures with predefined values. //! -//! The [Twelve-Factor App](https://12factor.net/config) methodology defines **application -//! configuration as everything that varies across deployments**, such as development, staging, -//! or production environments. -//! -//! Storing configuration values as code constants violates this methodology. `PageTop` advocates -//! for a **strict separation between code and configuration**, ensuring configuration varies per -//! deployment while the code remains constant. +//! Following the [Twelve-Factor App](https://12factor.net/config) methodology, `PageTop` separates +//! code from configuration. This approach allows configurations to vary across deployments, such as +//! development, staging, or production, without changing the codebase. //! //! //! # Loading configuration settings @@ -20,22 +16,32 @@ //! `PageTop` automatically loads configuration settings by reading the following TOML files in //! order (all files are optional): //! -//! 1. **config/common.toml**: Contains settings shared across all environments. These values can be -//! overridden by the subsequent files. +//! 1. **config/common.toml**, for settings shared across all environments. This approach simplifies +//! maintenance by centralizing common configuration values. //! -//! 2. **config/{file}.toml**, where `{file}` corresponds to the environment variable +//! 2. **config/{rm}.toml**, where `{rm}` corresponds to the environment variable //! `PAGETOP_RUN_MODE`: //! //! * If `PAGETOP_RUN_MODE` is not set, it defaults to `default`, and `PageTop` attempts to load //! *config/default.toml* if available. //! -//! * This enables separate configurations for environments like *devel.toml*, *staging.toml*, -//! or *production.toml*, or setups such as *server1.toml*. Only one file will be loaded. +//! * Useful for environment-specific configurations, ensuring that each environment +//! (e.g., development, staging, production) has its own settings without affecting others, +//! such as API keys, URLs, or performance-related adjustments. //! -//! * These files are suitable for storing sensitive values like passwords. Avoid committing -//! them to Git for security reasons. +//! 3. **config/local.{rm}.toml**, useful for local machine-specific configurations: //! -//! 3. **config/local.toml**: Used to add or override settings from the previous files. +//! * This file allows you to add or override settings specific to the environment. For example, +//! `local.devel.toml` for development or `local.production.toml` for production tweaks. +//! +//! * It enables developers to tailor settings for their machines within a given environment and +//! is typically not shared or committed to version control systems. +//! +//! 4. **config/local.toml**, for general local settings across all environments, ideal for quick +//! adjustments or temporary values not tied to any specific environment. +//! +//! The configuration settings are merged in the order listed above, with later files overriding +//! earlier ones if there are conflicts. //! //! //! # Adding configuration settings @@ -128,8 +134,8 @@ use std::sync::LazyLock; use std::env; use std::path::Path; -/// Original configuration values in `key = value` pairs gathered from configuration files. -pub static CONFIG_DATA: LazyLock = LazyLock::new(|| { +/// Original values read from configuration files in `key = value` pairs. +pub static CONFIG_VALUES: LazyLock = LazyLock::new(|| { // Identify the configuration directory. let config_dir = env::var("CARGO_MANIFEST_DIR") .map(|manifest_dir| { @@ -145,11 +151,11 @@ pub static CONFIG_DATA: LazyLock = LazyLock::new(|| { // Execution mode based on the environment variable PAGETOP_RUN_MODE, defaults to 'default'. let rm = env::var("PAGETOP_RUN_MODE").unwrap_or_else(|_| "default".into()); - // Initialize settings. - let mut settings = ConfigData::default(); + // Initialize config values. + let mut values = ConfigData::default(); // Merge (optional) configuration files and set the execution mode. - settings + values // First, add the common configuration for all environments. Defaults to 'common.toml'. .merge(File::with_name(&concat_string!(config_dir, "/common.toml")).required(false)) .expect("Failed to merge common configuration (common.toml)") @@ -159,14 +165,14 @@ pub static CONFIG_DATA: LazyLock = LazyLock::new(|| { // Add reserved local configuration for the environment. Defaults to 'local.default.toml'. .merge(File::with_name(&concat_string!(config_dir, "/local.", rm, ".toml")).required(false)) .expect("Failed to merge reserved local environment configuration") - // Add the general reserved local configuration. Defaults to 'local.toml'. + // Add common reserved local configuration. Defaults to 'local.toml'. .merge(File::with_name(&concat_string!(config_dir, "/local.toml")).required(false)) .expect("Failed to merge general reserved local configuration") // Save the execution mode. .set("app.run_mode", rm) .expect("Failed to set application run mode"); - settings + values }); #[macro_export] @@ -177,7 +183,7 @@ macro_rules! include_config { "[`", stringify!($Settings), "`] type." )] pub static $SETTINGS: std::sync::LazyLock<$Settings> = std::sync::LazyLock::new(|| { - let mut settings = $crate::config::CONFIG_DATA.clone(); + let mut settings = $crate::config::CONFIG_VALUES.clone(); $( settings.set_default($key, $value).unwrap(); )* diff --git a/pagetop/src/locale.rs b/pagetop/src/locale.rs index 39c73c68..ef9c1924 100644 --- a/pagetop/src/locale.rs +++ b/pagetop/src/locale.rs @@ -96,7 +96,6 @@ use fluent_templates::StaticLoader as Locales; use unic_langid::langid; -use std::borrow::Cow; use std::collections::HashMap; use std::sync::LazyLock; @@ -195,12 +194,13 @@ enum L10nOp { #[derive(AutoDefault)] pub struct L10n { op: L10nOp, - locales: Option<&'static Locales>, + #[default(&LOCALES_PAGETOP)] + locales: &'static Locales, args: HashMap>, } impl L10n { - pub fn n>>(text: S) -> Self { + pub fn n(text: impl Into) -> Self { L10n { op: L10nOp::Text(text.into().to_string()), ..Default::default() @@ -210,7 +210,6 @@ impl L10n { pub fn l(key: impl Into) -> Self { L10n { op: L10nOp::Translate(key.into()), - locales: Some(&LOCALES_PAGETOP), ..Default::default() } } @@ -218,7 +217,7 @@ impl L10n { pub fn t(key: impl Into, locales: &'static Locales) -> Self { L10n { op: L10nOp::Translate(key.into()), - locales: Some(locales), + locales, ..Default::default() } } @@ -229,23 +228,13 @@ impl L10n { self } - pub fn add_args(mut self, args: HashMap) -> Self { + pub fn with_args(mut self, args: HashMap) -> Self { for (k, v) in args { self.args.insert(k, FluentValue::from(v)); } self } - pub fn with_count(mut self, key: impl Into, count: usize) -> Self { - self.args.insert(key.into(), FluentValue::from(count)); - self - } - - pub fn with_date(mut self, key: impl Into, date: impl Into) -> Self { - self.args.insert(key.into(), FluentValue::from(date.into())); - self - } - pub fn get(&self) -> Option { self.using(&DEFAULT_LANGID) } @@ -254,29 +243,24 @@ impl L10n { match &self.op { L10nOp::None => None, L10nOp::Text(text) => Some(text.to_owned()), - L10nOp::Translate(key) => match self.locales { - Some(locales) => { - if self.args.is_empty() { - locales.try_lookup(langid, key) - } else { - locales.try_lookup_with_args(langid, key, &self.args) - } + L10nOp::Translate(key) => { + if self.args.is_empty() { + self.locales.try_lookup(langid, key) + } else { + self.locales.try_lookup_with_args(langid, key, &self.args) } - None => None, - }, + } } } /// Escapes translated text using the default language identifier. pub fn markup(&self) -> Markup { - let content = self.get().unwrap_or_default(); - PreEscaped(content) + PreEscaped(self.get().unwrap_or_default()) } /// Escapes translated text using the specified language identifier. pub fn escaped(&self, langid: &LanguageIdentifier) -> Markup { - let content = self.using(langid).unwrap_or_default(); - PreEscaped(content) + PreEscaped(self.using(langid).unwrap_or_default()) } } @@ -287,6 +271,6 @@ impl fmt::Display for L10n { L10nOp::Text(text) => text.clone(), L10nOp::Translate(key) => self.get().unwrap_or_else(|| format!("No <{}>", key)), }; - write!(f, "{}", content) + write!(f, "{content}") } }