use crate::theme::Theme;
pub trait Themed: Sized {
#[must_use]
fn apply_theme(self, theme: &Theme) -> Self;
#[must_use]
fn themed(self, provider: &impl ThemeProvider) -> Self {
self.apply_theme(&provider.nuance_theme())
}
}
pub trait ThemeProvider {
fn nuance_theme(&self) -> Theme;
}
impl ThemeProvider for Theme {
fn nuance_theme(&self) -> Theme {
self.clone()
}
}
impl<T: ThemeProvider + ?Sized> ThemeProvider for &T {
fn nuance_theme(&self) -> Theme {
(**self).nuance_theme()
}
}
impl<T: ThemeProvider + ?Sized> ThemeProvider for Box<T> {
fn nuance_theme(&self) -> Theme {
(**self).nuance_theme()
}
}
#[cfg(test)]
mod tests {
use super::*;
use ratatui::style::Color;
struct W(Color);
impl Themed for W {
fn apply_theme(self, t: &Theme) -> Self {
W(t.accent)
}
}
struct App;
impl ThemeProvider for App {
fn nuance_theme(&self) -> Theme {
Theme::nord()
}
}
#[test]
fn theme_is_its_own_provider() {
let t = Theme::dracula();
assert_eq!(t.nuance_theme(), t);
}
#[test]
fn themed_uses_provider() {
assert_eq!(W(Color::Reset).themed(&App).0, Theme::nord().accent);
assert_eq!(W(Color::Reset).themed(&&App).0, Theme::nord().accent);
}
#[test]
fn boxed_dyn_provider() {
let b: Box<dyn ThemeProvider> = Box::new(App);
assert_eq!(b.nuance_theme().name, "nord");
assert_eq!(W(Color::Reset).themed(&b).0, Theme::nord().accent);
}
}