use ratatui::style::Color;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Theme {
pub name: String,
pub colors: ThemeColors,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThemeColors {
pub background: ColorValue,
pub foreground: ColorValue,
pub border: ColorValue,
pub border_focused: ColorValue,
pub header: ColorValue,
pub status_bar: ColorValue,
pub text_primary: ColorValue,
pub text_secondary: ColorValue,
pub text_disabled: ColorValue,
pub text_highlight: ColorValue,
pub user_message: ColorValue,
pub assistant_message: ColorValue,
pub system_message: ColorValue,
pub code_background: ColorValue,
pub code_foreground: ColorValue,
pub code_keyword: ColorValue,
pub code_string: ColorValue,
pub code_comment: ColorValue,
pub mode_normal: ColorValue,
pub mode_accept_edits: ColorValue,
pub mode_plan: ColorValue,
pub mode_bypass_all: ColorValue,
pub success: ColorValue,
pub warning: ColorValue,
pub error: ColorValue,
pub info: ColorValue,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ColorValue {
Rgb { r: u8, g: u8, b: u8 },
Named(String),
}
impl ColorValue {
pub fn to_color(&self) -> Color {
match self {
ColorValue::Rgb { r, g, b } => Color::Rgb(*r, *g, *b),
ColorValue::Named(name) => match name.as_str() {
"black" => Color::Black,
"red" => Color::Red,
"green" => Color::Green,
"yellow" => Color::Yellow,
"blue" => Color::Blue,
"magenta" => Color::Magenta,
"cyan" => Color::Cyan,
"white" => Color::White,
"gray" | "grey" => Color::Gray,
"dark_gray" | "dark_grey" => Color::DarkGray,
_ => Color::White,
},
}
}
}
impl Theme {
pub fn light() -> Self {
Self {
name: "Light".to_string(),
colors: ThemeColors {
background: ColorValue::Rgb {
r: 250,
g: 250,
b: 250,
},
foreground: ColorValue::Rgb {
r: 30,
g: 30,
b: 30,
},
border: ColorValue::Named("gray".to_string()),
border_focused: ColorValue::Named("blue".to_string()),
header: ColorValue::Named("blue".to_string()),
status_bar: ColorValue::Named("white".to_string()),
text_primary: ColorValue::Named("black".to_string()),
text_secondary: ColorValue::Named("dark_gray".to_string()),
text_disabled: ColorValue::Named("gray".to_string()),
text_highlight: ColorValue::Named("magenta".to_string()),
user_message: ColorValue::Named("blue".to_string()),
assistant_message: ColorValue::Named("green".to_string()),
system_message: ColorValue::Named("yellow".to_string()),
code_background: ColorValue::Rgb {
r: 240,
g: 240,
b: 240,
},
code_foreground: ColorValue::Named("dark_gray".to_string()),
code_keyword: ColorValue::Named("magenta".to_string()),
code_string: ColorValue::Named("green".to_string()),
code_comment: ColorValue::Named("gray".to_string()),
mode_normal: ColorValue::Named("green".to_string()),
mode_accept_edits: ColorValue::Named("yellow".to_string()),
mode_plan: ColorValue::Named("blue".to_string()),
mode_bypass_all: ColorValue::Named("red".to_string()),
success: ColorValue::Named("green".to_string()),
warning: ColorValue::Named("yellow".to_string()),
error: ColorValue::Named("red".to_string()),
info: ColorValue::Named("blue".to_string()),
},
}
}
pub fn dark() -> Self {
Self {
name: "Dark".to_string(),
colors: ThemeColors {
background: ColorValue::Rgb {
r: 20,
g: 20,
b: 20,
},
foreground: ColorValue::Rgb {
r: 230,
g: 230,
b: 230,
},
border: ColorValue::Named("dark_gray".to_string()),
border_focused: ColorValue::Named("cyan".to_string()),
header: ColorValue::Named("cyan".to_string()),
status_bar: ColorValue::Named("black".to_string()),
text_primary: ColorValue::Named("white".to_string()),
text_secondary: ColorValue::Named("gray".to_string()),
text_disabled: ColorValue::Named("dark_gray".to_string()),
text_highlight: ColorValue::Named("yellow".to_string()),
user_message: ColorValue::Named("blue".to_string()),
assistant_message: ColorValue::Named("green".to_string()),
system_message: ColorValue::Named("yellow".to_string()),
code_background: ColorValue::Rgb {
r: 40,
g: 40,
b: 40,
},
code_foreground: ColorValue::Named("gray".to_string()),
code_keyword: ColorValue::Named("magenta".to_string()),
code_string: ColorValue::Named("green".to_string()),
code_comment: ColorValue::Named("dark_gray".to_string()),
mode_normal: ColorValue::Named("green".to_string()),
mode_accept_edits: ColorValue::Named("yellow".to_string()),
mode_plan: ColorValue::Named("blue".to_string()),
mode_bypass_all: ColorValue::Named("red".to_string()),
success: ColorValue::Named("green".to_string()),
warning: ColorValue::Named("yellow".to_string()),
error: ColorValue::Named("red".to_string()),
info: ColorValue::Named("cyan".to_string()),
},
}
}
}