use anyhow::{Context, Result}; use serde::Deserialize; use std::path::Path; #[derive(Debug, Deserialize)] pub struct SiteConfig { pub site: Site, pub i18n: I18n, pub highlight: Option, } #[derive(Debug, Deserialize)] pub struct Site { pub title: String, pub version: Option, pub base_url: String, #[serde(default)] pub base_path: String, } #[derive(Debug, Deserialize)] pub struct I18n { pub default_lang: String, pub langs: Vec, } #[derive(Debug, Deserialize)] pub struct Highlight { pub theme: Option, pub theme_light: Option, } impl SiteConfig { pub fn load(src_dir: &Path) -> Result { let path = src_dir.join("config.toml"); let content = std::fs::read_to_string(&path).with_context(|| format!("Failed to read {}", path.display()))?; let mut config: SiteConfig = toml::from_str(&content).with_context(|| format!("Failed to parse {}", path.display()))?; // Normalize base_path: strip trailing slash (but keep empty for root) let bp = config.site.base_path.trim_end_matches('/').to_string(); config.site.base_path = bp; Ok(config) } pub fn highlight_theme(&self) -> &str { self.highlight .as_ref() .and_then(|h| h.theme.as_deref()) .unwrap_or("base16-ocean.dark") } pub fn highlight_theme_light(&self) -> Option<&str> { self.highlight .as_ref() .and_then(|h| h.theme_light.as_deref()) } }