use std::collections::HashMap;
use std::sync::{Arc, Mutex, OnceLock};
use comrak::plugins::syntect::{SyntectAdapter, SyntectAdapterBuilder};
pub(crate) const DEFAULT_CODE_THEME: &str = "base16-ocean.dark";
const KNOWN_THEMES: &[&str] = &[
"base16-ocean.dark",
"base16-eighties.dark",
"base16-mocha.dark",
"base16-ocean.light",
"InspiredGitHub",
"Solarized (dark)",
"Solarized (light)",
];
static ADAPTERS: OnceLock<Mutex<HashMap<String, Arc<SyntectAdapter>>>> = OnceLock::new();
pub(crate) fn adapter_for(theme_name: &str) -> Arc<SyntectAdapter> {
let resolved = if KNOWN_THEMES.contains(&theme_name) {
theme_name
} else {
DEFAULT_CODE_THEME
};
let cache = ADAPTERS.get_or_init(|| Mutex::new(HashMap::new()));
{
let map = cache
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
if let Some(adapter) = map.get(resolved) {
return Arc::clone(adapter);
}
}
let adapter = Arc::new(SyntectAdapterBuilder::new().theme(resolved).build());
let mut map = cache
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
Arc::clone(map.entry(resolved.to_string()).or_insert(adapter))
}