#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThemeColor {
Primary,
Secondary,
Error,
Success,
Warning,
Info,
Foreground,
Background,
Muted,
Highlight,
Rgb(u8, u8, u8),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Emphasis {
Normal,
Bold,
Italic,
Underline,
Dim,
}
pub trait Theme {
fn name(&self) -> &str;
fn primary(&self) -> ThemeColor;
fn secondary(&self) -> ThemeColor;
fn error(&self) -> ThemeColor;
fn success(&self) -> ThemeColor;
fn warning(&self) -> ThemeColor;
fn info(&self) -> ThemeColor;
fn foreground(&self) -> ThemeColor;
fn background(&self) -> ThemeColor;
}
pub trait ThemePresets: Theme + Sized {
fn dark() -> Self;
fn light() -> Self;
fn high_contrast() -> Self;
}
#[derive(Debug, Clone)]
pub struct ThemeConfig {
pub name: String,
pub primary: ThemeColor,
pub secondary: ThemeColor,
pub error: ThemeColor,
pub success: ThemeColor,
pub warning: ThemeColor,
pub info: ThemeColor,
pub foreground: ThemeColor,
pub background: ThemeColor,
}
impl Default for ThemeConfig {
fn default() -> Self {
Self::dark()
}
}
impl ThemeConfig {
pub fn dark() -> Self {
Self {
name: "dark".into(),
primary: ThemeColor::Rgb(96, 165, 250), secondary: ThemeColor::Rgb(250, 204, 21), error: ThemeColor::Rgb(239, 68, 68), success: ThemeColor::Rgb(34, 197, 94), warning: ThemeColor::Rgb(251, 146, 60), info: ThemeColor::Rgb(14, 165, 233), foreground: ThemeColor::Rgb(229, 229, 229), background: ThemeColor::Rgb(23, 23, 23), }
}
pub fn light() -> Self {
Self {
name: "light".into(),
primary: ThemeColor::Rgb(59, 130, 246), secondary: ThemeColor::Rgb(202, 138, 4), error: ThemeColor::Rgb(220, 38, 38), success: ThemeColor::Rgb(22, 163, 74), warning: ThemeColor::Rgb(234, 88, 12), info: ThemeColor::Rgb(6, 182, 212), foreground: ThemeColor::Rgb(23, 23, 23), background: ThemeColor::Rgb(255, 255, 255), }
}
pub fn with_primary(mut self, color: ThemeColor) -> Self {
self.primary = color;
self
}
pub fn with_secondary(mut self, color: ThemeColor) -> Self {
self.secondary = color;
self
}
pub fn with_error(mut self, color: ThemeColor) -> Self {
self.error = color;
self
}
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = name.into();
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_theme_config_default() {
let theme = ThemeConfig::default();
assert_eq!(theme.name, "dark");
}
#[test]
fn test_theme_config_light() {
let theme = ThemeConfig::light();
assert_eq!(theme.name, "light");
}
#[test]
fn test_theme_config_builder() {
let theme = ThemeConfig::dark()
.with_name("custom")
.with_primary(ThemeColor::Rgb(255, 0, 0));
assert_eq!(theme.name, "custom");
assert_eq!(theme.primary, ThemeColor::Rgb(255, 0, 0));
}
#[test]
fn test_theme_color_equality() {
let color1 = ThemeColor::Rgb(255, 0, 0);
let color2 = ThemeColor::Rgb(255, 0, 0);
let color3 = ThemeColor::Rgb(0, 255, 0);
assert_eq!(color1, color2);
assert_ne!(color1, color3);
}
#[test]
fn test_emphasis() {
let bold = Emphasis::Bold;
let normal = Emphasis::Normal;
assert_eq!(bold, Emphasis::Bold);
assert_ne!(bold, normal);
}
}