(theme): Añade IntoColor para colores opcionales

Permite que métodos como `with_color(color: impl IntoColor)` acepten un
color directo o uno opcional (`Some(...)`/`None`) sin la ambigüedad que
produce un `Into<Option<C>>` genérico.
This commit is contained in:
Manuel Cillero 2026-08-21 08:18:28 +02:00
parent bb6855e41f
commit b50d186fb1
2 changed files with 30 additions and 2 deletions

View file

@ -118,7 +118,7 @@
//! [`ReservedRegions`]: crate::response::ReservedRegions //! [`ReservedRegions`]: crate::response::ReservedRegions
mod color; mod color;
pub use color::{ColorName, CoreColors}; pub use color::{ColorName, CoreColors, IntoColor};
mod layout; mod layout;
pub use layout::{CoreRegions, RegionName, RegionRef}; pub use layout::{CoreRegions, RegionName, RegionRef};

View file

@ -5,13 +5,41 @@ use crate::AutoDefault;
/// Interfaz común para los colores de la paleta de un tema. /// Interfaz común para los colores de la paleta de un tema.
/// ///
/// PageTop ofrece una implementación predeterminada en [`CoreColors`], aunque probablemente cada /// PageTop ofrece una implementación predeterminada en [`CoreColors`], aunque probablemente cada
/// tema proporcionará su propia lista de colores implementando este *trait*. /// tema proporcionará su propia lista de colores implementando este trait.
pub trait ColorName { pub trait ColorName {
/// Devuelve el nombre asociado al color (p. ej. `"primary"`, `"danger"`, etc.). Normalmente se /// Devuelve el nombre asociado al color (p. ej. `"primary"`, `"danger"`, etc.). Normalmente se
/// usará para generar la clase CSS del componente. /// usará para generar la clase CSS del componente.
fn name(self) -> &'static str; fn name(self) -> &'static str;
} }
// **< IntoColor >**********************************************************************************
/// Convierte un color, o su ausencia, en el nombre ya resuelto.
///
/// Permite que un método como `with_color(color: impl IntoColor)` acepte indistintamente un color
/// directo (`CoreColors::Danger`) o uno opcional (`Some(CoreColors::Danger)`, o `None` para no
/// aplicar ninguno).
///
/// Evita la ambigüedad de `impl<T> From<T> for T` junto con `impl<T> From<T> for Option<T>` al
/// resolver un `C` genérico acotado por [`ColorName`]. Al ser [`IntoColor`] un trait propio,
/// ninguna implementación de [`ColorName`] cubre nunca `Option<C>` y la resolución no es ambigua.
pub trait IntoColor {
/// Devuelve el nombre del color ya resuelto, o `None` si no se aplica ninguno.
fn into_color(self) -> Option<&'static str>;
}
impl<C: ColorName> IntoColor for C {
fn into_color(self) -> Option<&'static str> {
Some(self.name())
}
}
impl<C: ColorName> IntoColor for Option<C> {
fn into_color(self) -> Option<&'static str> {
self.map(ColorName::name)
}
}
// **< CoreColors >********************************************************************************* // **< CoreColors >*********************************************************************************
/// Paleta de colores predeterminada de PageTop. /// Paleta de colores predeterminada de PageTop.