use ratatui::style::Color;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
#[derive(Default)]
pub enum Theme {
#[default]
Default,
Dark,
Light,
}
impl Theme {
pub fn colors(&self) -> ColorScheme {
match self {
Self::Default => ColorScheme::default(),
Self::Dark => ColorScheme::dark(),
Self::Light => ColorScheme::light(),
}
}
}
impl FromStr for Theme {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"default" => Ok(Self::Default),
"dark" => Ok(Self::Dark),
"light" => Ok(Self::Light),
_ => Err(format!(
"Invalid theme '{}'. Valid options: default, dark, light",
s
)),
}
}
}
impl fmt::Display for Theme {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Default => write!(f, "default"),
Self::Dark => write!(f, "dark"),
Self::Light => write!(f, "light"),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct ColorScheme {
pub border: Color,
pub highlight_bg: Color,
pub text_primary: Color,
pub text_secondary: Color,
pub text_muted: Color,
pub status_clean: Color,
pub status_dirty: Color,
pub status_conflict: Color,
pub status_sync: Color,
pub key_action: Color,
pub key_warning: Color,
pub key_danger: Color,
pub repo_name: Color,
pub branch_name: Color,
pub commit_ahead: Color,
pub commit_behind: Color,
pub section_remote: Color,
pub section_commit: Color,
pub section_stash: Color,
}
impl Default for ColorScheme {
fn default() -> Self {
Self {
border: Color::White,
highlight_bg: Color::DarkGray,
text_primary: Color::White,
text_secondary: Color::Gray,
text_muted: Color::DarkGray,
status_clean: Color::Green,
status_dirty: Color::Yellow,
status_conflict: Color::Red,
status_sync: Color::Cyan,
key_action: Color::Green,
key_warning: Color::Yellow,
key_danger: Color::Red,
repo_name: Color::Cyan,
branch_name: Color::Green,
commit_ahead: Color::Cyan,
commit_behind: Color::Yellow,
section_remote: Color::Blue,
section_commit: Color::Magenta,
section_stash: Color::Magenta,
}
}
}
impl ColorScheme {
pub fn dark() -> Self {
Self {
border: Color::Rgb(80, 80, 80),
highlight_bg: Color::Rgb(40, 45, 50),
text_primary: Color::Rgb(220, 225, 230),
text_secondary: Color::Rgb(150, 155, 160),
text_muted: Color::Rgb(90, 95, 100),
status_clean: Color::Rgb(80, 200, 120), status_dirty: Color::Rgb(230, 190, 90), status_conflict: Color::Rgb(240, 90, 90), status_sync: Color::Rgb(90, 180, 230),
key_action: Color::Rgb(100, 220, 150), key_warning: Color::Rgb(250, 200, 100), key_danger: Color::Rgb(250, 100, 100),
repo_name: Color::Rgb(100, 200, 240), branch_name: Color::Rgb(120, 230, 150), commit_ahead: Color::Rgb(110, 200, 240), commit_behind: Color::Rgb(240, 190, 100),
section_remote: Color::Rgb(130, 170, 240), section_commit: Color::Rgb(230, 150, 230), section_stash: Color::Rgb(210, 140, 230), }
}
pub fn light() -> Self {
Self {
border: Color::Rgb(180, 185, 190),
highlight_bg: Color::Rgb(235, 240, 245), text_primary: Color::Rgb(20, 20, 25), text_secondary: Color::Rgb(70, 75, 80), text_muted: Color::Rgb(140, 145, 150),
status_clean: Color::Rgb(0, 130, 50), status_dirty: Color::Rgb(200, 120, 0), status_conflict: Color::Rgb(200, 20, 20), status_sync: Color::Rgb(0, 100, 180),
key_action: Color::Rgb(0, 140, 70), key_warning: Color::Rgb(210, 130, 0), key_danger: Color::Rgb(220, 20, 20),
repo_name: Color::Rgb(0, 90, 180), branch_name: Color::Rgb(0, 130, 60), commit_ahead: Color::Rgb(0, 110, 200), commit_behind: Color::Rgb(190, 100, 0),
section_remote: Color::Rgb(30, 80, 200), section_commit: Color::Rgb(170, 50, 170), section_stash: Color::Rgb(150, 50, 180), }
}
}