🚧 (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

@ -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)
}
}