🧑💻 Simplifica uso de archivos de configuración
This commit is contained in:
parent
df6eaf19cc
commit
68af9caef0
16 changed files with 216 additions and 202 deletions
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<FIGfont> = 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<FIGfont> = 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<DbConn> = 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::<u16>("database.db_port") != 0 {
|
||||
tmp_uri.set_port(Some(config::get_value::<u16>("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<DbConn> = 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<DbConn> = LazyStatic::new(|| {
|
|||
|
||||
run_now(Database::connect::<ConnectOptions>({
|
||||
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::<u32>("database.max_pool_size"));
|
||||
db_opt
|
||||
}))
|
||||
.expect_or_log("Failed to connect to database")
|
||||
|
|
|
|||
|
|
@ -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<LanguageIdentifier> =
|
||||
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",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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<WorkerGuard> = 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<WorkerGuard> = 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<WorkerGuard> = 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<WorkerGuard> = LazyStatic::new(|| {
|
|||
_ => {
|
||||
println!(
|
||||
"Tracing format \"{}\" not valid. Using \"Full\". Check the settings file.",
|
||||
SETTINGS.log.format,
|
||||
config::get("log.format"),
|
||||
);
|
||||
subscriber.init();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ fn hello_world() -> Container {
|
|||
.with_component(
|
||||
Paragraph::with(html! {
|
||||
(e("hello_intro", &args![
|
||||
"app" => format!("<span class=\"app-name\">{}</span>", &SETTINGS.app.name)
|
||||
"app" => format!("<span class=\"app-name\">{}</span>", 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!("<span class=\"app-name\">{}</span>", &SETTINGS.app.name)
|
||||
"app" => format!("<span class=\"app-name\">{}</span>", config::get("app.name"))
|
||||
]))
|
||||
})
|
||||
.with_display(HeadingDisplay::Subtitle),
|
||||
|
|
|
|||
|
|
@ -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<Config> = 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<Config> = 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<RwLock<HashMap<&str, &str>>> = 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<T: FromStr + Default>(key: &str) -> T where <T as FromStr>::Err: Debug {
|
||||
get(key).parse::<T>().unwrap_or(Default::default())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,45 @@
|
|||
// EXTERNAL RE-EXPORTS.
|
||||
//! <div align="center">
|
||||
//!
|
||||
//! <img src="https://raw.githubusercontent.com/manuelcillero/pagetop/main/pagetop/static/pagetop-banner.png" />
|
||||
//!
|
||||
//! <h1>PageTop</h1>
|
||||
//!
|
||||
//! [](https://crates.io/crates/pagetop)
|
||||
//! [](https://docs.rs/pagetop)
|
||||
//!
|
||||
//! </div>
|
||||
//!
|
||||
//! **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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<ThemeStaticRef> =
|
||||
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,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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<Option<String>> = 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<Option<String>> = LazyStatic::new(|| {
|
|||
});
|
||||
|
||||
static DEFAULT_DIRECTION: LazyStatic<Option<String>> = 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<Option<String>> = LazyStatic::new(|| {
|
|||
_ => {
|
||||
trace::warn!(
|
||||
"Text direction \"{}\" not valid, {}",
|
||||
SETTINGS.app.direction,
|
||||
config::get("app.direction"),
|
||||
"check the settings file"
|
||||
);
|
||||
None
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue