From 68af9caef051aaebd04ca86709d1ae1646f506d3 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Tue, 18 Oct 2022 21:22:28 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Simplifica?= =?UTF-8?q?=20uso=20de=20archivos=20de=20configuraci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pagetop-user/src/lib.rs | 2 +- pagetop/Cargo.toml | 5 +- pagetop/src/app/application.rs | 5 +- pagetop/src/app/banner.rs | 14 +- pagetop/src/app/banner/figfont.rs | 7 +- pagetop/src/app/db.rs | 28 +-- pagetop/src/app/locale.rs | 7 +- pagetop/src/app/tracing.rs | 17 +- pagetop/src/base/module/homepage.rs | 4 +- pagetop/src/config.rs | 255 +++++++++++------------- pagetop/src/core/theme/definition.rs | 6 +- pagetop/src/lib.rs | 52 ++++- pagetop/src/prelude.rs | 2 +- pagetop/src/response/page/context.rs | 4 +- pagetop/src/response/page/definition.rs | 8 +- pagetop/src/util.rs | 2 +- 16 files changed, 216 insertions(+), 202 deletions(-) diff --git a/pagetop-user/src/lib.rs b/pagetop-user/src/lib.rs index 22c14c41..d45a2259 100644 --- a/pagetop-user/src/lib.rs +++ b/pagetop-user/src/lib.rs @@ -58,7 +58,7 @@ fn form_login() -> Form { t( "username_help", &args![ - "app" => SETTINGS.app.name.to_owned() + "app" => config::get("app.name").to_owned() ], ) .as_str(), diff --git a/pagetop/Cargo.toml b/pagetop/Cargo.toml index 897ea673..59b051ca 100644 --- a/pagetop/Cargo.toml +++ b/pagetop/Cargo.toml @@ -24,7 +24,6 @@ categories = [ [dependencies] async-trait = "0.1.57" concat-string = "1.0.1" -doc-comment = "0.3.3" figlet-rs = "0.1.4" futures = "0.3.24" once_cell = "1.15.0" @@ -33,7 +32,7 @@ substring = "1.4.5" term_size = "0.3.2" url = "2.3.1" -config_rs = { package = "config", version = "0.11.0", features = ["toml"] } +config_rs = { package = "config", version = "0.13.2", features = ["toml"] } tracing = "0.1.36" tracing-appender = "0.2.2" @@ -51,8 +50,6 @@ static-files = "0.2.3" maud = { version = "0.24.0", features = ["actix-web"] } -serde = { version = "1.0", features = ["derive"] } - [dependencies.sea-orm] version = "0.9.3" features = ["debug-print", "macros", "runtime-async-std-native-tls"] diff --git a/pagetop/src/app/application.rs b/pagetop/src/app/application.rs index a5c18c4c..9d3c7c41 100644 --- a/pagetop/src/app/application.rs +++ b/pagetop/src/app/application.rs @@ -1,5 +1,5 @@ use super::fatal_error::FatalError; -use crate::config::SETTINGS; +use crate::config; use crate::core::module::ModuleStaticRef; use crate::core::{module, theme}; use crate::html::Markup; @@ -55,7 +55,8 @@ impl Application { }) .bind(format!( "{}:{}", - &SETTINGS.webserver.bind_address, &SETTINGS.webserver.bind_port + config::get("webserver.bind_address"), + config::get("webserver.bind_port") ))? .run(); diff --git a/pagetop/src/app/banner.rs b/pagetop/src/app/banner.rs index 1e50e54a..eb52f4a5 100644 --- a/pagetop/src/app/banner.rs +++ b/pagetop/src/app/banner.rs @@ -1,23 +1,23 @@ mod figfont; use figfont::FIGFONT; -use crate::config::SETTINGS; +use crate::config; use substring::Substring; pub fn print_on_startup() { - if SETTINGS.app.startup_banner.to_lowercase() != "off" { + if config::get("app.startup_banner").to_lowercase() != "off" { if let Some((term_width, _)) = term_size::dimensions() { if term_width >= 80 { let maxlen = (term_width / 10) - 2; - let mut app = SETTINGS.app.name.substring(0, maxlen).to_owned(); - if SETTINGS.app.name.len() > maxlen { + let mut app = config::get("app.name").substring(0, maxlen).to_owned(); + if config::get("app.name").len() > maxlen { app = format!("{}...", app); } println!( "\n{} {}\n\n Powered by PageTop {}\n", FIGFONT.convert(&app).unwrap(), - &SETTINGS.app.description, + config::get("app.description"), env!("CARGO_PKG_VERSION") ); return; @@ -25,8 +25,8 @@ pub fn print_on_startup() { } println!( "\n{}\n{}\n\nPowered by PageTop {}\n", - &SETTINGS.app.name, - &SETTINGS.app.description, + config::get("app.name"), + config::get("app.description"), env!("CARGO_PKG_VERSION") ); } diff --git a/pagetop/src/app/banner/figfont.rs b/pagetop/src/app/banner/figfont.rs index d92fe35a..48321dc8 100644 --- a/pagetop/src/app/banner/figfont.rs +++ b/pagetop/src/app/banner/figfont.rs @@ -1,5 +1,4 @@ -use crate::config::SETTINGS; -use crate::LazyStatic; +use crate::{config, LazyStatic}; use figlet_rs::FIGfont; @@ -9,7 +8,7 @@ pub static FIGFONT: LazyStatic = LazyStatic::new(|| { let speed = include_str!("speed.flf"); let starwars = include_str!("starwars.flf"); - FIGfont::from_content(match SETTINGS.app.startup_banner.to_lowercase().as_str() { + FIGfont::from_content(match config::get("app.startup_banner").to_lowercase().as_str() { "off" => slant, "slant" => slant, "small" => small, @@ -18,7 +17,7 @@ pub static FIGFONT: LazyStatic = LazyStatic::new(|| { _ => { println!( "\n FIGfont \"{}\" not found for banner. Using \"Slant\". Check the settings file.", - SETTINGS.app.startup_banner, + config::get("app.startup_banner"), ); slant } diff --git a/pagetop/src/app/db.rs b/pagetop/src/app/db.rs index 98f96e47..61aec6fe 100644 --- a/pagetop/src/app/db.rs +++ b/pagetop/src/app/db.rs @@ -1,4 +1,4 @@ -use crate::config::SETTINGS; +use crate::config; use crate::db::*; use crate::{run_now, trace, LazyStatic}; @@ -8,38 +8,38 @@ use tracing_unwrap::ResultExt; pub static DBCONN: LazyStatic = LazyStatic::new(|| { trace::info!( "Connecting to database \"{}\" using a pool of {} connections", - &SETTINGS.database.db_name, - &SETTINGS.database.max_pool_size + config::get("database.db_name"), + config::get("database.max_pool_size") ); - let db_uri = match SETTINGS.database.db_type.as_str() { + let db_uri = match config::get("database.db_type").as_str() { "mysql" | "postgres" => { let mut tmp_uri = DbUri::parse( format!( "{}://{}/{}", - &SETTINGS.database.db_type, - &SETTINGS.database.db_host, - &SETTINGS.database.db_name + config::get("database.db_type"), + config::get("database.db_host"), + config::get("database.db_name") ) .as_str(), ) .unwrap(); tmp_uri - .set_username(SETTINGS.database.db_user.as_str()) + .set_username(config::get("database.db_user").as_str()) .unwrap(); // https://github.com/launchbadge/sqlx/issues/1624 tmp_uri - .set_password(Some(SETTINGS.database.db_pass.as_str())) + .set_password(Some(config::get("database.db_pass").as_str())) .unwrap(); - if SETTINGS.database.db_port != 0 { - tmp_uri.set_port(Some(SETTINGS.database.db_port)).unwrap(); + if config::get_value::("database.db_port") != 0 { + tmp_uri.set_port(Some(config::get_value::("database.db_port"))).unwrap(); } tmp_uri } "sqlite" => DbUri::parse( format!( "{}://{}", - &SETTINGS.database.db_type, &SETTINGS.database.db_name + config::get("database.db_type"), &config::get("database.db_name") ) .as_str(), ) @@ -47,7 +47,7 @@ pub static DBCONN: LazyStatic = LazyStatic::new(|| { _ => { trace::error!( "Unrecognized database type \"{}\"", - &SETTINGS.database.db_type + config::get("database.db_type") ); DbUri::parse("").unwrap() } @@ -55,7 +55,7 @@ pub static DBCONN: LazyStatic = LazyStatic::new(|| { run_now(Database::connect::({ let mut db_opt = ConnectOptions::new(db_uri.to_string()); - db_opt.max_connections(SETTINGS.database.max_pool_size); + db_opt.max_connections(config::get_value::("database.max_pool_size")); db_opt })) .expect_or_log("Failed to connect to database") diff --git a/pagetop/src/app/locale.rs b/pagetop/src/app/locale.rs index 9775867f..55d3abf7 100644 --- a/pagetop/src/app/locale.rs +++ b/pagetop/src/app/locale.rs @@ -1,5 +1,4 @@ -use crate::config::SETTINGS; -use crate::{trace, LazyStatic}; +use crate::{config, trace, LazyStatic}; use unic_langid::LanguageIdentifier; @@ -7,14 +6,14 @@ use unic_langid::LanguageIdentifier; /// (https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier)) de /// la aplicación, obtenido de `SETTINGS.app.language`. pub static LANGID: LazyStatic = - LazyStatic::new(|| match SETTINGS.app.language.parse() { + LazyStatic::new(|| match config::get("app.language").parse() { Ok(language) => language, Err(_) => { trace::warn!( "{}, {} \"{}\"! {}, {}", "Failed to parse language", "unrecognized Unicode Language Identifier", - SETTINGS.app.language, + config::get("app.language"), "Using \"en-US\"", "check the settings file", ); diff --git a/pagetop/src/app/tracing.rs b/pagetop/src/app/tracing.rs index bc6bf515..d2450ac3 100644 --- a/pagetop/src/app/tracing.rs +++ b/pagetop/src/app/tracing.rs @@ -1,5 +1,4 @@ -use crate::config::SETTINGS; -use crate::LazyStatic; +use crate::{config, LazyStatic}; use tracing_appender::non_blocking::WorkerGuard; use tracing_subscriber::EnvFilter; @@ -20,14 +19,14 @@ use tracing_subscriber::EnvFilter; #[rustfmt::skip] pub static TRACING: LazyStatic = LazyStatic::new(|| { let env_filter = - EnvFilter::try_new(&SETTINGS.log.tracing).unwrap_or_else(|_| EnvFilter::new("Info")); + EnvFilter::try_new(config::get("log.tracing")).unwrap_or_else(|_| EnvFilter::new("Info")); - let rolling = SETTINGS.log.rolling.to_lowercase(); + let rolling = config::get("log.rolling").to_lowercase(); let (non_blocking, guard) = match rolling.as_str() { "stdout" => tracing_appender::non_blocking(std::io::stdout()), _ => tracing_appender::non_blocking({ - let path = &SETTINGS.log.path; - let prefix = &SETTINGS.log.prefix; + let path = config::get("log.path"); + let prefix = config::get("log.prefix"); match rolling.as_str() { "daily" => tracing_appender::rolling::daily(path, prefix), "hourly" => tracing_appender::rolling::hourly(path, prefix), @@ -36,7 +35,7 @@ pub static TRACING: LazyStatic = LazyStatic::new(|| { _ => { println!( "Rolling value \"{}\" not valid. Using \"daily\". Check the settings file.", - SETTINGS.log.rolling, + config::get("log.rolling"), ); tracing_appender::rolling::daily(path, prefix) } @@ -47,7 +46,7 @@ pub static TRACING: LazyStatic = LazyStatic::new(|| { .with_env_filter(env_filter) .with_writer(non_blocking) .with_ansi(rolling.as_str() == "stdout"); - match SETTINGS.log.format.to_lowercase().as_str() { + match config::get("log.format").to_lowercase().as_str() { "json" => subscriber.json().init(), "full" => subscriber.init(), "compact" => subscriber.compact().init(), @@ -55,7 +54,7 @@ pub static TRACING: LazyStatic = LazyStatic::new(|| { _ => { println!( "Tracing format \"{}\" not valid. Using \"Full\". Check the settings file.", - SETTINGS.log.format, + config::get("log.format"), ); subscriber.init(); } diff --git a/pagetop/src/base/module/homepage.rs b/pagetop/src/base/module/homepage.rs index 92a3628b..e51fbbf4 100644 --- a/pagetop/src/base/module/homepage.rs +++ b/pagetop/src/base/module/homepage.rs @@ -55,7 +55,7 @@ fn hello_world() -> Container { .with_component( Paragraph::with(html! { (e("hello_intro", &args![ - "app" => format!("{}", &SETTINGS.app.name) + "app" => format!("{}", config::get("app.name")) ])) }) .with_display(ParagraphDisplay::Small), @@ -101,7 +101,7 @@ fn welcome() -> Container { .with_component( Heading::h3(html! { (e("welcome_subtitle", &args![ - "app" => format!("{}", &SETTINGS.app.name) + "app" => format!("{}", config::get("app.name")) ])) }) .with_display(HeadingDisplay::Subtitle), diff --git a/pagetop/src/config.rs b/pagetop/src/config.rs index 76dd5777..aceee2ab 100644 --- a/pagetop/src/config.rs +++ b/pagetop/src/config.rs @@ -1,158 +1,139 @@ +//! Gestión de la configuración. +//! +//! Comprueba el modo de ejecución actual y carga la configuración asociada. +//! +//! PageTop aplica los principios de [The Twelve-Factor App](https://12factor.net/es/) cargando +//! archivos de configuración [TOML](https://toml.io) con pares `clave = valor` que pueden diferir +//! según el modo de ejecución del entorno actual, o al migrar a otros entornos (*desarrollo*, +//! *pre-producción*, *producción*, etc.). +//! +//! # ¿Cómo usar archivos de configuración? +//! +//! Si tu aplicación requiere opciones de configuración, primero debes crear un directorio llamado +//! *config* (ver [`CONFIG_DIR`]) al mismo nivel del archivo *Cargo.toml* de tu proyecto (o del +//! archivo binario ejecutable de la aplicación). +//! +//! Luego guarda la configuración usando archivos TOML asumiendo el siguiente orden de lectura +//! (todos los archivos son opcionales): +//! +//! 1. *config/common.toml*, útil para asignar valores comunes a cualquier entorno. Estos valores +//! pueden ser modificados al fusionar los siguientes archivos de configuración. +//! +//! 2. *config/{archivo}.toml*, donde *{archivo}* puede definirse mediante la variable de entorno +//! PAGETOP_RUN_MODE: +//! +//! * Si no está definido, se asumirá *default* como nombre predeterminado y PageTop cargará el +//! archivo de configuración *config/default.toml* si existe. +//! +//! * De esta manera, se podrían tener diferentes opciones de configuración para diferentes +//! entornos de ejecución. Por ejemplo, para *devel.toml*, *staging.toml* o *production.toml*. +//! O también para *server1.toml* o *server2.toml*. Sólo uno será cargado. +//! +//! 3. *config/local.toml*, para añadir o sobrescribir ajustes. + use crate::LazyStatic; use config_rs::{Config, File}; -use serde::Deserialize; +use std::collections::HashMap; +use std::default::Default; use std::env; +use std::fmt::Debug; +use std::str::FromStr; +use std::sync::RwLock; -/// Nombre del directorio donde se encuentra la configuración. -const CONFIG_DIR: &str = "config"; +#[macro_export] +macro_rules! default_settings { + ( $($key:literal => $value:literal),* ) => {{ + let mut a = std::collections::HashMap::new(); + $( + a.insert($key, $value); + )* + a + }}; +} -/// Al arrancar la aplicación, carga los valores originales "clave = valor" de -/// los archivos de configuración. Con [`config_map`] se asignarán los ajustes -/// globales ([`SETTINGS`]); y se podrán asignar los ajustes específicos de la -/// aplicación, o también de un tema, módulo o componente. -pub static CONFIG: LazyStatic = LazyStatic::new(|| { - // Establece el modo de ejecución según el valor de la variable de entorno - // PAGETOP_RUN_MODE. Asume "default" por defecto. +/// Directorio donde se encuentran los archivos de configuración. +pub const CONFIG_DIR: &str = "config"; + +/// Carga los valores originales "clave = valor" de los archivos de configuración. Con +/// [`config_map`] se asignarán los ajustes globales ([`SETTINGS`]); y se podrán asignar los ajustes +/// específicos de la aplicación, o también de un tema, módulo o componente. +static CONFIG: LazyStatic = LazyStatic::new(|| { + // Modo de ejecución según la variable de entorno PAGETOP_RUN_MODE. Por defecto 'default'. let run_mode = env::var("PAGETOP_RUN_MODE").unwrap_or_else(|_| "default".into()); // Inicializa los ajustes. - let mut settings = Config::default(); + let settings = Config::builder(); // Combina los archivos de configuración y asigna el modo de ejecución. settings - .merge(File::with_name(&format!("{}/{}.toml", CONFIG_DIR, "common")).required(false)) - .unwrap() - .merge(File::with_name(&format!("{}/{}.toml", CONFIG_DIR, run_mode)).required(false)) - .unwrap() - .merge(File::with_name(&format!("{}/{}.toml", CONFIG_DIR, "local")).required(false)) - .unwrap() - .set("app.run_mode", run_mode) - .unwrap(); + // Primero añade configuración común a todos los entornos. Opcional. + .add_source(File::with_name(&format!("{}/{}.toml", CONFIG_DIR, "common")).required(false)) - settings + // Combina la configuración específica del entorno. Por defecto 'default.toml'. Opcional. + .add_source(File::with_name(&format!("{}/{}.toml", CONFIG_DIR, run_mode)).required(false)) + + // Combina la configuración local. Este archivo no debería incluirse en git. Opcional. + .add_source(File::with_name(&format!("{}/{}.toml", CONFIG_DIR, "local")).required(false)) + + // Salvaguarda el modo de ejecución. + .set_default("app.run_mode", run_mode) + + .unwrap() + .build() + .unwrap() }); -#[macro_export] -/// Asigna los ajustes específicos de la aplicación, o de un tema, módulo o -/// componente, en una estructura similar a [`SETTINGS`] con tipos de variables -/// seguros. Produce un *panic!* en caso de asignaciones no válidas. -macro_rules! config_map { - ( - $doc:expr, - $SETTINGS:ident, - $Type:tt - $(, $key:expr => $value:expr)* - ) => { - $crate::doc_comment! { - concat!($doc), +static DEFAULTS: LazyStatic>> = LazyStatic::new(|| + RwLock::new(default_settings![ + // [app] + "app.name" => "PageTop Application", + "app.description" => "Developed with the amazing PageTop framework.", + "app.theme" => "Bootsier", + "app.language" => "en-US", + "app.direction" => "ltr", + "app.startup_banner" => "Slant", - pub static $SETTINGS: $crate::LazyStatic<$Type> = $crate::LazyStatic::new(|| { - let mut settings = $crate::config::CONFIG.clone(); - $( - settings.set_default($key, $value).unwrap(); - )* - match settings.try_into() { - Ok(c) => c, - Err(e) => panic!("Error parsing settings: {}", e), - } - }); - } - }; -} + // [log] + "log.tracing" => "Info", + "log.rolling" => "Stdout", + "log.path" => "log", + "log.prefix" => "tracing.log", + "log.format" => "Full", -#[rustfmt::skip] -#[derive(Debug, Deserialize)] -pub struct App { - pub name : String, - pub description : String, - pub theme : String, - pub language : String, - pub direction : String, - pub startup_banner: String, - pub run_mode : String, -} + // [database] + "database.db_type" => "", + "database.db_name" => "", + "database.db_user" => "", + "database.db_pass" => "", + "database.db_host" => "localhost", + "database.db_port" => "0", + "database.max_pool_size" => "5", -#[rustfmt::skip] -#[derive(Debug, Deserialize)] -pub struct Log { - pub tracing : String, - pub rolling : String, - pub path : String, - pub prefix : String, - pub format : String, -} + // [webserver] + "webserver.bind_address" => "localhost", + "webserver.bind_port" => "8088", -#[rustfmt::skip] -#[derive(Debug, Deserialize)] -pub struct Database { - pub db_type : String, - pub db_name : String, - pub db_user : String, - pub db_pass : String, - pub db_host : String, - pub db_port : u16, - pub max_pool_size : u32, -} - -#[rustfmt::skip] -#[derive(Debug, Deserialize)] -pub struct Webserver { - pub bind_address : String, - pub bind_port : u16, -} - -#[rustfmt::skip] -#[derive(Debug, Deserialize)] -pub struct Dev { - pub static_files : String, -} - -#[rustfmt::skip] -#[derive(Debug, Deserialize)] -pub struct Settings { - pub app : App, - pub log : Log, - pub database : Database, - pub webserver : Webserver, - pub dev : Dev, -} - -config_map!(r#" -Ajustes globales y valores predeterminados para las secciones *\[app\]*, -*\[log\]* y *\[webserver\]* de PageTop. -"#, - SETTINGS, Settings, - - // [app] - "app.name" => "PageTop Application", - "app.description" => "Developed with the amazing PageTop framework.", - "app.theme" => "Bootsier", - "app.language" => "en-US", - "app.direction" => "ltr", - "app.startup_banner" => "Slant", - - // [log] - "log.tracing" => "Info", - "log.rolling" => "Stdout", - "log.path" => "log", - "log.prefix" => "tracing.log", - "log.format" => "Full", - - // [database] - "database.db_type" => "", - "database.db_name" => "", - "database.db_user" => "", - "database.db_pass" => "", - "database.db_host" => "localhost", - "database.db_port" => 0, - "database.max_pool_size" => 5, - - // [webserver] - "webserver.bind_address" => "localhost", - "webserver.bind_port" => 8088, - - // [dev] - "dev.static_files" => "" + // [dev] + "dev.static_files" => "" + ]) ); + +pub fn add_defaults(defaults: HashMap<&'static str, &'static str>) { + DEFAULTS.write().unwrap().extend(defaults); +} + +pub fn get(key: &str) -> String { + match CONFIG.get_string(key) { + Ok(value) => value, + _ => match DEFAULTS.read().unwrap().get(key) { + Some(value) => String::from(*value), + _ => Default::default(), + }, + } +} + +pub fn get_value(key: &str) -> T where ::Err: Debug { + get(key).parse::().unwrap_or(Default::default()) +} diff --git a/pagetop/src/core/theme/definition.rs b/pagetop/src/core/theme/definition.rs index ee3abcbf..68bf1368 100644 --- a/pagetop/src/core/theme/definition.rs +++ b/pagetop/src/core/theme/definition.rs @@ -1,7 +1,7 @@ use crate::app; use crate::base::component::{Container, Html}; use crate::concat_string; -use crate::config::SETTINGS; +use crate::config; use crate::core::component::ComponentTrait; use crate::html::{html, Favicon, Markup}; use crate::response::page::{Page, PageContext, PageOp}; @@ -43,9 +43,9 @@ pub trait ThemeTrait: BaseTheme + Send + Sync { @match page.title().get() { Some(t) => title { - (concat_string!(SETTINGS.app.name, " | ", t)) + (concat_string!(config::get("app.name"), " | ", t)) }, - None => title { (SETTINGS.app.name) } + None => title { (config::get("app.name")) } } @match page.description().get() { diff --git a/pagetop/src/lib.rs b/pagetop/src/lib.rs index cfcaf8ad..a61ee3ad 100644 --- a/pagetop/src/lib.rs +++ b/pagetop/src/lib.rs @@ -1,7 +1,45 @@ -// EXTERNAL RE-EXPORTS. +//!
+//! +//! +//! +//!

PageTop

+//! +//! [![crate](https://img.shields.io/crates/v/pagetop.svg)](https://crates.io/crates/pagetop) +//! [![docs](https://docs.rs/pagetop/badge.svg)](https://docs.rs/pagetop) +//! +//!
+//! +//! **PageTop** es un entorno de desarrollo basado en Rust que reúne algunos de los crates más +//! estables y populares para crear soluciones web modulares, extensibles y configurables. +//! +//! PageTop añade una capa de abstracción para definir una interfaz única que ofrezca de partida: +//! +//! * Gestión de la configuración ([`config`]). +//! +//! * Registro de trazas y eventos de la aplicación ([`trace`]). +//! +//! * Localización ([`locale`]). +//! +//! * HTML en código ([`html`]). +//! +//! * Acceso a base de datos ([`db`]). +//! +//! * APIs esenciales para crear componentes, acciones, módulos y temas ([`core`]). +//! +//! * Tipos de respuestas a peticiones web ([`response`]) +//! +//! * Base de componentes, módulos y temas ([`base`]). +//! +//! * Utilidades de carácter global ([`util`]). +//! +//! # 🚧 Advertencia +//! +//! **PageTop** sólo libera actualmente versiones de desarrollo. La API no es estable y los cambios +//! son constantes. No puede considerarse preparado hasta que se libere la versión **0.1.0**. + +// GLOBAL. pub use concat_string::concat_string; -pub use doc_comment::doc_comment; pub use once_cell::sync::Lazy as LazyStatic; // LOCAL. @@ -9,7 +47,7 @@ pub use once_cell::sync::Lazy as LazyStatic; #[allow(unused_imports)] pub(crate) use futures::executor::block_on as run_now; -// PUBLIC APIs. +// APIs PÚBLICAS. // Gestión de la configuración. pub mod config; @@ -24,19 +62,19 @@ pub mod html; #[cfg(feature = "database")] pub mod db; -// Prepare and run the application. +// Prepara y ejecuta la aplicación. pub mod app; -// Main APIs for components, hooks, modules and themes. +// APIs esenciales para crear componentes, acciones, módulos y temas. pub mod core; -// Tipos de respuestas web. +// Tipos de respuestas a peticiones web. pub mod response; // Base de componentes, módulos y temas. pub mod base; // Macros y funciones útiles. pub mod util; -// INTERNAL RE-EXPORTS. +// RE-EXPORTA API ÚNICA. pub mod prelude; diff --git a/pagetop/src/prelude.rs b/pagetop/src/prelude.rs index a8e21580..620dbcb9 100644 --- a/pagetop/src/prelude.rs +++ b/pagetop/src/prelude.rs @@ -5,7 +5,7 @@ pub use crate::{ args, concat_string, configure_service_for_static_files, pub_const_handler, LazyStatic, }; -pub use crate::config::SETTINGS; +pub use crate::config; pub use crate::trace; diff --git a/pagetop/src/response/page/context.rs b/pagetop/src/response/page/context.rs index 055fa781..4a9c3036 100644 --- a/pagetop/src/response/page/context.rs +++ b/pagetop/src/response/page/context.rs @@ -1,11 +1,11 @@ use super::PageOp; -use crate::config::SETTINGS; +use crate::config; use crate::core::theme::{all::theme_by_single_name, ThemeStaticRef}; use crate::html::{html, Assets, Favicon, IdentifierValue, JavaScript, Markup, ModeJS, StyleSheet}; use crate::{base, concat_string, util, LazyStatic}; static DEFAULT_THEME: LazyStatic = - LazyStatic::new(|| match theme_by_single_name(&SETTINGS.app.theme) { + LazyStatic::new(|| match theme_by_single_name(&config::get("app.theme")) { Some(theme) => theme, None => &base::theme::bootsier::Bootsier, }); diff --git a/pagetop/src/response/page/definition.rs b/pagetop/src/response/page/definition.rs index 3617b40d..82e1c499 100644 --- a/pagetop/src/response/page/definition.rs +++ b/pagetop/src/response/page/definition.rs @@ -1,6 +1,6 @@ use super::{BeforeRenderPageHook, PageContext, PageOp, ResultPage, HOOK_BEFORE_RENDER_PAGE}; use crate::app::fatal_error::FatalError; -use crate::config::SETTINGS; +use crate::config; use crate::core::component::*; use crate::core::hook::{action_ref, run_actions}; use crate::html::{html, AttributeValue, Classes, ClassesOp, Markup, DOCTYPE}; @@ -9,7 +9,7 @@ use crate::{trace, LazyStatic}; use std::collections::HashMap; static DEFAULT_LANGUAGE: LazyStatic> = LazyStatic::new(|| { - let language = SETTINGS.app.language[..2].to_lowercase(); + let language = config::get("app.language")[..2].to_lowercase(); if !language.is_empty() { Some(language) } else { @@ -18,7 +18,7 @@ static DEFAULT_LANGUAGE: LazyStatic> = LazyStatic::new(|| { }); static DEFAULT_DIRECTION: LazyStatic> = LazyStatic::new(|| { - let direction = SETTINGS.app.direction.to_lowercase(); + let direction = config::get("app.direction").to_lowercase(); match direction.as_str() { "auto" => Some("auto".to_owned()), "ltr" => Some("ltr".to_owned()), @@ -27,7 +27,7 @@ static DEFAULT_DIRECTION: LazyStatic> = LazyStatic::new(|| { _ => { trace::warn!( "Text direction \"{}\" not valid, {}", - SETTINGS.app.direction, + config::get("app.direction"), "check the settings file" ); None diff --git a/pagetop/src/util.rs b/pagetop/src/util.rs index 68d20d3e..a4358c02 100644 --- a/pagetop/src/util.rs +++ b/pagetop/src/util.rs @@ -169,7 +169,7 @@ macro_rules! args { #[macro_export] macro_rules! configure_service_for_static_files { ( $cfg:ident, $dir:expr, $embed:ident ) => {{ - let static_files = &$crate::config::SETTINGS.dev.static_files; + let static_files = $crate::config::get("dev.static_files"); if static_files.is_empty() { $cfg.service($crate::app::ResourceFiles::new($dir, $embed())); } else {