🚧 (config): Nueva gestión de opciones enumeradas

This commit is contained in:
Manuel Cillero 2025-12-15 17:24:00 +01:00
parent 7b340a19f3
commit 16d6afbd98
5 changed files with 121 additions and 48 deletions

View file

@ -78,7 +78,7 @@ impl Application {
use colored::Colorize;
use terminal_size::{terminal_size, Width};
if global::SETTINGS.app.startup_banner.to_lowercase() != "off" {
if global::SETTINGS.app.startup_banner != global::StartupBanner::Off {
// Nombre de la aplicación, ajustado al ancho del terminal si es necesario.
let mut app_ff = String::new();
let app_name = &global::SETTINGS.app.name;

View file

@ -10,21 +10,11 @@ pub static FIGFONT: LazyLock<FIGfont> = LazyLock::new(|| {
let speed = include_str!("speed.flf");
let starwars = include_str!("starwars.flf");
FIGfont::from_content(
match global::SETTINGS.app.startup_banner.to_lowercase().as_str() {
"off" => slant,
"slant" => slant,
"small" => small,
"speed" => speed,
"starwars" => starwars,
_ => {
println!(
"\n FIGfont \"{}\" not found for banner. Using \"Slant\". Check settings.",
global::SETTINGS.app.startup_banner,
);
slant
}
},
)
FIGfont::from_content(match global::SETTINGS.app.startup_banner {
global::StartupBanner::Off | global::StartupBanner::Slant => slant,
global::StartupBanner::Small => small,
global::StartupBanner::Speed => speed,
global::StartupBanner::Starwars => starwars,
})
.unwrap()
});

View file

@ -1,9 +1,15 @@
//! Opciones de configuración globales.
use crate::{include_config, AutoDefault};
use crate::include_config;
use serde::Deserialize;
mod lang_negotiation;
pub use lang_negotiation::LangNegotiation;
mod startup_banner;
pub use startup_banner::StartupBanner;
// **< SETTINGS >***********************************************************************************
include_config!(SETTINGS: Settings => [
@ -32,35 +38,6 @@ include_config!(SETTINGS: Settings => [
"server.session_lifetime" => 604_800,
]);
// **< LangNegotiation >****************************************************************************
/// Modos disponibles para negociar el idioma de una petición HTTP.
///
/// El ajuste [`global::SETTINGS.app.lang_negotiation`](crate::global::App::lang_negotiation)
/// determina qué fuentes intervienen en la resolución del idioma efectivo utilizado por
/// [`RequestLocale`](crate::locale::RequestLocale) y en la generación de URLs mediante
/// [`Context::route()`](crate::core::component::Context::route).
#[derive(AutoDefault, Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
pub enum LangNegotiation {
/// Usa todas las fuentes disponibles para determinar el idioma, en este orden: comprueba el
/// parámetro `?lang` de la URL; si no está presente o no es válido, usa la cabecera HTTP
/// `Accept-Language`; si tampoco está disponible o no es válido, usa el idioma configurado en
/// [`global::SETTINGS.app.language`](crate::global::App::language) o, en su defecto, el idioma
/// de respaldo. Es el comportamiento por defecto.
#[default]
Full,
/// Igual que `LangNegotiation::Full`, pero sin tener en cuenta el parámetro `?lang` de la URL.
/// El idioma depende únicamente de la cabecera `Accept-Language` del navegador y, en última
/// instancia, de la configuración o idioma de respaldo.
NoQuery,
/// Usa sólo la configuración o, en su defecto, el idioma de respaldo; ignora la cabecera
/// `Accept-Language` y el parámetro de la URL. Este modo proporciona un comportamiento estable
/// con idioma fijo.
ConfigOnly,
}
// **< Settings >***********************************************************************************
#[derive(Debug, Deserialize)]
@ -101,7 +78,7 @@ pub struct App {
pub lang_negotiation: LangNegotiation,
/// Banner ASCII mostrado al inicio: *"Off"* (desactivado), *"Slant"*, *"Small"*, *"Speed"* o
/// *"Starwars"*.
pub startup_banner: String,
pub startup_banner: StartupBanner,
/// Activa la página de bienvenida de PageTop.
///
/// Si está activada, se instala la extensión [`Welcome`](crate::base::extension::Welcome), que

View file

@ -0,0 +1,56 @@
use crate::AutoDefault;
use serde::{Deserialize, Deserializer};
/// Modos disponibles para negociar el idioma de una petición HTTP.
///
/// El ajuste [`global::SETTINGS.app.lang_negotiation`](crate::global::App::lang_negotiation)
/// determina qué fuentes intervienen en la resolución del idioma efectivo utilizado por
/// [`RequestLocale`](crate::locale::RequestLocale) y en la generación de URLs mediante
/// [`Context::route()`](crate::core::component::Context::route).
#[derive(AutoDefault, Clone, Copy, Debug, Eq, PartialEq)]
pub enum LangNegotiation {
/// Usa todas las fuentes disponibles para determinar el idioma, en este orden: comprueba el
/// parámetro `?lang` de la URL; si no está presente o no es válido, usa la cabecera HTTP
/// `Accept-Language`; si tampoco está disponible o no es válido, usa el idioma configurado en
/// [`global::SETTINGS.app.language`](crate::global::App::language) o, en su defecto, el idioma
/// de respaldo. Es el comportamiento por defecto.
#[default]
Full,
/// Igual que `LangNegotiation::Full`, pero sin tener en cuenta el parámetro `?lang` de la URL.
/// El idioma depende únicamente de la cabecera `Accept-Language` del navegador y, en última
/// instancia, de la configuración o idioma de respaldo.
NoQuery,
/// Usa sólo la configuración o, en su defecto, el idioma de respaldo; ignora la cabecera
/// `Accept-Language` y el parámetro de la URL. Este modo proporciona un comportamiento estable
/// con idioma fijo.
ConfigOnly,
}
impl<'de> Deserialize<'de> for LangNegotiation {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let raw = String::deserialize(deserializer)?;
let result = match raw.trim().to_ascii_lowercase().as_str() {
"full" => Self::Full,
"noquery" => Self::NoQuery,
"configonly" => Self::ConfigOnly,
_ => {
let default = Self::default();
println!(
concat!(
"\nInvalid value \"{}\" for [app].lang_negotiation. ",
"Using \"{:?}\". Check settings.",
),
raw, default,
);
default
}
};
Ok(result)
}
}

View file

@ -0,0 +1,50 @@
use crate::AutoDefault;
use serde::{Deserialize, Deserializer};
/// Opciones para el *banner* ASCII mostrado al arrancar la aplicación.
///
/// Se obtiene de [`global::SETTINGS.app.startup_banner`](crate::global::App::startup_banner) y
/// controla si se muestra un *banner* en la salida estándar al arrancar la aplicación.
#[derive(AutoDefault, Clone, Copy, Debug, Eq, PartialEq)]
pub enum StartupBanner {
/// No muestra ningún banner de inicio.
Off,
/// Banner en estilo "Slant". Es el comportamiento por defecto.
#[default]
Slant,
/// Banner en estilo "Small".
Small,
/// Banner en estilo "Speed".
Speed,
/// Banner en estilo "Starwars".
Starwars,
}
impl<'de> Deserialize<'de> for StartupBanner {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let raw = String::deserialize(deserializer)?;
let result = match raw.trim().to_ascii_lowercase().as_str() {
"off" => Self::Off,
"slant" => Self::Slant,
"small" => Self::Small,
"speed" => Self::Speed,
"starwars" => Self::Starwars,
_ => {
let default = Self::default();
println!(
concat!(
"\nInvalid value \"{}\" for [app].startup_banner. ",
"Using \"{:?}\". Check settings.",
),
raw, default,
);
default
}
};
Ok(result)
}
}