diff --git a/src/core/theme.rs b/src/core/theme.rs index fa9708cd..bad50216 100644 --- a/src/core/theme.rs +++ b/src/core/theme.rs @@ -118,7 +118,7 @@ //! [`ReservedRegions`]: crate::response::ReservedRegions mod color; -pub use color::{ColorName, CoreColors}; +pub use color::{ColorName, CoreColors, IntoColor}; mod layout; pub use layout::{CoreRegions, RegionName, RegionRef}; diff --git a/src/core/theme/color.rs b/src/core/theme/color.rs index 1a4cb4a2..62cf5cd0 100644 --- a/src/core/theme/color.rs +++ b/src/core/theme/color.rs @@ -5,13 +5,41 @@ use crate::AutoDefault; /// Interfaz común para los colores de la paleta de un tema. /// /// 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 { /// Devuelve el nombre asociado al color (p. ej. `"primary"`, `"danger"`, etc.). Normalmente se /// usará para generar la clase CSS del componente. 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 From for T` junto con `impl From for Option` al +/// resolver un `C` genérico acotado por [`ColorName`]. Al ser [`IntoColor`] un trait propio, +/// ninguna implementación de [`ColorName`] cubre nunca `Option` 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 IntoColor for C { + fn into_color(self) -> Option<&'static str> { + Some(self.name()) + } +} + +impl IntoColor for Option { + fn into_color(self) -> Option<&'static str> { + self.map(ColorName::name) + } +} + // **< CoreColors >********************************************************************************* /// Paleta de colores predeterminada de PageTop.