use super::error::{ResolveError, closest_match};
use super::schema::DocumentConfig;
const DEFAULT_TOML: &str = include_str!("themes/default.toml");
const GITHUB_TOML: &str = include_str!("themes/github.toml");
const ACADEMIC_TOML: &str = include_str!("themes/academic.toml");
const MINIMAL_TOML: &str = include_str!("themes/minimal.toml");
const COMPACT_TOML: &str = include_str!("themes/compact.toml");
const MODERN_TOML: &str = include_str!("themes/modern.toml");
const PRESETS: &[(&str, &str)] = &[
("default", DEFAULT_TOML),
("github", GITHUB_TOML),
("academic", ACADEMIC_TOML),
("minimal", MINIMAL_TOML),
("compact", COMPACT_TOML),
("modern", MODERN_TOML),
];
pub fn load_theme_preset(name: &str) -> Result<DocumentConfig, ResolveError> {
let mut chain: Vec<String> = Vec::new();
load_with_chain(name, &mut chain)
}
fn load_with_chain(name: &str, chain: &mut Vec<String>) -> Result<DocumentConfig, ResolveError> {
if chain.iter().any(|n| n == name) {
chain.push(name.to_string());
return Err(ResolveError::InheritsCycle(chain.clone()));
}
chain.push(name.to_string());
let raw = preset_source(name).ok_or_else(|| ResolveError::UnknownTheme {
name: name.to_string(),
suggestion: closest_match(name, PRESETS.iter().map(|(n, _)| *n), 3)
.map(|s| s.to_string()),
})?;
let cfg: DocumentConfig = toml::from_str(raw).map_err(|e| ResolveError::BadToml {
source: e,
input: raw.to_string(),
file: None,
suggestion: Some(format!("bundled theme `{}` failed to parse — this is a bug, please file an issue", name)),
})?;
if let Some(parent_name) = cfg.inherits.as_deref() {
let parent = load_with_chain(parent_name, chain)?;
let merged = super::merge::merge_documents(parent, cfg);
Ok(merged)
} else {
Ok(cfg)
}
}
fn preset_source(name: &str) -> Option<&'static str> {
PRESETS.iter().find(|(n, _)| *n == name).map(|(_, s)| *s)
}
pub fn available_theme_names() -> &'static [&'static str] {
static NAMES: &[&str] = &["default", "github", "academic", "minimal", "compact", "modern"];
NAMES
}