pub type DataFiles = &'static [(&'static str, &'static [u8])];
pub struct MermaidColors {
pub background: &'static str,
pub primary_color: &'static str,
pub secondary_color: &'static str,
pub tertiary_color: &'static str,
pub primary_text_color: &'static str,
pub text_color: &'static str,
pub primary_border_color: &'static str,
pub line_color: &'static str,
pub edge_label_background: &'static str,
pub cluster_background: &'static str,
pub cluster_border: &'static str,
pub sequence_actor_fill: &'static str,
pub sequence_actor_border: &'static str,
pub sequence_actor_line: &'static str,
pub sequence_note_fill: &'static str,
pub sequence_note_border: &'static str,
pub sequence_activation_fill: &'static str,
pub sequence_activation_border: &'static str,
}
pub struct ThemeEntry {
pub name: &'static str,
pub source: &'static str,
pub data_files: DataFiles,
pub sidebar_bg: &'static str,
pub sidebar_fg: &'static str,
pub mermaid: MermaidColors,
}
pub const THEMES: &[ThemeEntry] = &[
ThemeEntry {
name: "catppuccin",
source: include_str!("../themes/catppuccin.typ"),
data_files: &[(
"catppuccin-mocha.tmTheme",
include_bytes!("../themes/catppuccin-mocha.tmTheme"),
)],
sidebar_bg: "#1e1e2e", sidebar_fg: "#6c7086", mermaid: MermaidColors {
background: "#1e1e2e", primary_color: "#313244", secondary_color: "#45475a", tertiary_color: "#585b70", primary_text_color: "#cdd6f4", text_color: "#cdd6f4", primary_border_color: "#585b70", line_color: "#a6adc8", edge_label_background: "#1e1e2e", cluster_background: "#313244", cluster_border: "#585b70", sequence_actor_fill: "#313244",
sequence_actor_border: "#585b70",
sequence_actor_line: "#a6adc8",
sequence_note_fill: "#45475a",
sequence_note_border: "#f5c2e7", sequence_activation_fill: "#45475a",
sequence_activation_border: "#585b70",
},
},
ThemeEntry {
name: "catppuccin-latte",
source: include_str!("../themes/catppuccin-latte.typ"),
data_files: &[(
"catppuccin-latte.tmTheme",
include_bytes!("../themes/catppuccin-latte.tmTheme"),
)],
sidebar_bg: "#e6e9ef", sidebar_fg: "#8c8fa1", mermaid: MermaidColors {
background: "#FFFFFF",
primary_color: "#F8FAFC",
secondary_color: "#E2E8F0",
tertiary_color: "#FFFFFF",
primary_text_color: "#0F172A",
text_color: "#0F172A",
primary_border_color: "#94A3B8",
line_color: "#64748B",
edge_label_background: "#FFFFFF",
cluster_background: "#F1F5F9",
cluster_border: "#CBD5E1",
sequence_actor_fill: "#F8FAFC",
sequence_actor_border: "#94A3B8",
sequence_actor_line: "#64748B",
sequence_note_fill: "#FFF7ED",
sequence_note_border: "#FDBA74",
sequence_activation_fill: "#E2E8F0",
sequence_activation_border: "#94A3B8",
},
},
];
pub const DEFAULT_THEME: &str = "auto";
pub fn resolve_theme_name(name: &str, is_light: bool) -> &str {
match name {
"auto" => {
if is_light {
"catppuccin-latte"
} else {
"catppuccin"
}
}
"dark" => "catppuccin",
"light" => "catppuccin-latte",
_ => name,
}
}
fn find(name: &str) -> Option<&'static ThemeEntry> {
THEMES.iter().find(|t| t.name == name)
}
pub fn get(name: &str) -> Option<&'static str> {
find(name).map(|t| t.source)
}
pub fn data_files(name: &str) -> DataFiles {
find(name).map(|t| t.data_files).unwrap_or(&[])
}
pub fn sidebar_colors(name: &str) -> (&'static str, &'static str) {
find(name)
.map(|t| (t.sidebar_bg, t.sidebar_fg))
.unwrap_or(("#1e1e2e", "#6c7086"))
}
pub fn mermaid_colors(name: &str) -> &'static MermaidColors {
find(name).map(|t| &t.mermaid).unwrap_or(&THEMES[0].mermaid)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_theme_is_auto() {
assert_eq!(DEFAULT_THEME, "auto");
}
#[test]
fn unknown_theme_returns_none() {
assert!(get("nonexistent").is_none());
}
#[test]
fn sidebar_colors_known_theme() {
let (bg, fg) = sidebar_colors("catppuccin");
assert_eq!(bg, "#1e1e2e");
assert_eq!(fg, "#6c7086");
}
#[test]
fn sidebar_colors_latte() {
let (bg, fg) = sidebar_colors("catppuccin-latte");
assert_eq!(bg, "#e6e9ef");
assert_eq!(fg, "#8c8fa1");
}
#[test]
fn sidebar_colors_unknown_falls_back() {
let (bg, fg) = sidebar_colors("nonexistent");
assert_eq!(bg, "#1e1e2e");
assert_eq!(fg, "#6c7086");
}
#[test]
fn mermaid_colors_dark() {
let mc = mermaid_colors("catppuccin");
assert_eq!(mc.background, "#1e1e2e");
assert_eq!(mc.primary_text_color, "#cdd6f4");
}
#[test]
fn mermaid_colors_light() {
let mc = mermaid_colors("catppuccin-latte");
assert_eq!(mc.background, "#FFFFFF");
assert_eq!(mc.primary_text_color, "#0F172A");
}
#[test]
fn mermaid_colors_unknown_falls_back() {
let mc = mermaid_colors("nonexistent");
assert_eq!(mc.background, "#1e1e2e"); }
#[test]
fn resolve_auto_dark() {
assert_eq!(resolve_theme_name("auto", false), "catppuccin");
}
#[test]
fn resolve_auto_light() {
assert_eq!(resolve_theme_name("auto", true), "catppuccin-latte");
}
#[test]
fn resolve_explicit_theme() {
assert_eq!(resolve_theme_name("catppuccin", true), "catppuccin");
assert_eq!(
resolve_theme_name("catppuccin-latte", false),
"catppuccin-latte"
);
}
#[test]
fn resolve_dark_alias() {
assert_eq!(resolve_theme_name("dark", false), "catppuccin");
assert_eq!(resolve_theme_name("dark", true), "catppuccin");
}
#[test]
fn resolve_light_alias() {
assert_eq!(resolve_theme_name("light", false), "catppuccin-latte");
assert_eq!(resolve_theme_name("light", true), "catppuccin-latte");
}
}