#[cfg(feature = "serde")]
use serde::Deserialize;
use ratatui::style::Color;
use crate::Theme;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Deserialize))]
pub struct CustomTheme {
pub name: String,
pub id: String,
pub accent: Color,
#[cfg_attr(feature = "serde", serde(default = "default_dark_gray"))]
pub accent_dim: Color,
#[cfg_attr(feature = "serde", serde(default = "default_white"))]
pub text: Color,
#[cfg_attr(feature = "serde", serde(default = "default_gray"))]
pub text_dim: Color,
#[cfg_attr(feature = "serde", serde(default = "default_white"))]
pub text_bright: Color,
#[cfg_attr(feature = "serde", serde(default = "default_green"))]
pub success: Color,
#[cfg_attr(feature = "serde", serde(default = "default_red"))]
pub error: Color,
#[cfg_attr(feature = "serde", serde(default = "default_yellow"))]
pub warning: Color,
#[cfg_attr(feature = "serde", serde(default = "default_cyan"))]
pub info: Color,
#[cfg_attr(feature = "serde", serde(default = "default_green"))]
pub diff_added: Color,
#[cfg_attr(feature = "serde", serde(default = "default_red"))]
pub diff_removed: Color,
#[cfg_attr(feature = "serde", serde(default = "default_dark_gray"))]
pub diff_context: Color,
#[cfg_attr(feature = "serde", serde(default = "default_dark_gray"))]
pub border: Color,
#[cfg_attr(feature = "serde", serde(default = "default_black"))]
pub surface: Color,
}
impl Theme for CustomTheme {
fn name(&self) -> &str {
&self.name
}
fn id(&self) -> &str {
&self.id
}
fn accent(&self) -> Color {
self.accent
}
fn accent_dim(&self) -> Color {
self.accent_dim
}
fn text(&self) -> Color {
self.text
}
fn text_dim(&self) -> Color {
self.text_dim
}
fn text_bright(&self) -> Color {
self.text_bright
}
fn success(&self) -> Color {
self.success
}
fn error(&self) -> Color {
self.error
}
fn warning(&self) -> Color {
self.warning
}
fn info(&self) -> Color {
self.info
}
fn diff_added(&self) -> Color {
self.diff_added
}
fn diff_removed(&self) -> Color {
self.diff_removed
}
fn diff_context(&self) -> Color {
self.diff_context
}
fn border(&self) -> Color {
self.border
}
fn surface(&self) -> Color {
self.surface
}
}
#[cfg(feature = "serde")]
fn default_dark_gray() -> Color {
Color::DarkGray
}
#[cfg(feature = "serde")]
fn default_white() -> Color {
Color::White
}
#[cfg(feature = "serde")]
fn default_gray() -> Color {
Color::Gray
}
#[cfg(feature = "serde")]
fn default_green() -> Color {
Color::Green
}
#[cfg(feature = "serde")]
fn default_red() -> Color {
Color::Red
}
#[cfg(feature = "serde")]
fn default_yellow() -> Color {
Color::Yellow
}
#[cfg(feature = "serde")]
fn default_cyan() -> Color {
Color::Cyan
}
#[cfg(feature = "serde")]
fn default_black() -> Color {
Color::Black
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn custom_theme_all_slots_accessible() {
let t = CustomTheme {
name: "Test".to_owned(),
id: "test".to_owned(),
accent: Color::Magenta,
accent_dim: Color::DarkGray,
text: Color::White,
text_dim: Color::Gray,
text_bright: Color::White,
success: Color::Green,
error: Color::Red,
warning: Color::Yellow,
info: Color::Cyan,
diff_added: Color::Green,
diff_removed: Color::Red,
diff_context: Color::DarkGray,
border: Color::DarkGray,
surface: Color::Black,
};
let theme: &dyn Theme = &t;
assert_eq!(theme.accent(), Color::Magenta);
assert_eq!(theme.success(), Color::Green);
assert_eq!(theme.block_pass(), theme.success());
assert_eq!(theme.indicator_failed(), theme.error());
}
#[test]
#[cfg(feature = "serde")]
fn custom_theme_deserialize_minimal() {
let toml_str = r#"
name = "Minimal"
id = "minimal"
accent = "Magenta"
"#;
let theme: CustomTheme = toml::from_str(toml_str).unwrap();
assert_eq!(theme.name, "Minimal");
assert_eq!(theme.id, "minimal");
assert_eq!(theme.accent, Color::Magenta);
assert_eq!(theme.success, Color::Green);
assert_eq!(theme.error, Color::Red);
assert_eq!(theme.text, Color::White);
assert_eq!(theme.border, Color::DarkGray);
}
#[test]
#[cfg(feature = "serde")]
fn custom_theme_deserialize_rgb() {
let toml_str = r#"
name = "RGB Theme"
id = "rgb"
accent = { Rgb = [249, 115, 22] }
text = { Rgb = [220, 220, 220] }
"#;
let theme: CustomTheme = toml::from_str(toml_str).unwrap();
assert_eq!(theme.accent, Color::Rgb(249, 115, 22));
assert_eq!(theme.text, Color::Rgb(220, 220, 220));
}
#[test]
#[cfg(feature = "serde")]
fn custom_theme_deserialize_indexed() {
let toml_str = r#"
name = "Indexed"
id = "indexed"
accent = { Indexed = 208 }
"#;
let theme: CustomTheme = toml::from_str(toml_str).unwrap();
assert_eq!(theme.accent, Color::Indexed(208));
}
}