use std::sync::{Arc, LazyLock};
pub use syntect::{
dumps,
highlighting::{Theme, ThemeSet},
};
use crate::resource::HighlightResource;
#[derive(Debug, Clone)]
pub enum HlightThemeSet<'set> {
Ref(&'set ThemeSet),
Arc(Arc<ThemeSet>),
}
impl From<ThemeSet> for HlightThemeSet<'_> {
fn from(value: ThemeSet) -> Self {
Self::Arc(Arc::new(value))
}
}
impl<'set> From<&'set ThemeSet> for HlightThemeSet<'set> {
fn from(value: &'set ThemeSet) -> Self {
Self::Ref(value)
}
}
impl HlightThemeSet<'_> {
pub fn get_inner(&self) -> &ThemeSet {
match self {
Self::Ref(theme_set) => theme_set,
Self::Arc(theme_set) => theme_set,
}
}
}
pub const READ_DUMP_DATA_ERR: &str = "Failed to read dump data";
pub mod names {
pub use compact_str::CompactString as CmString;
#[inline]
pub const fn new(s: &'static str) -> CmString {
CmString::const_new(s)
}
pub const fn monokai() -> CmString {
new("Monokai Extended")
}
pub const fn ayu_dark() -> CmString {
new("ayu-dark")
}
}
pub fn load_theme_set(set: Option<&[u8]>) -> ThemeSet {
let msg = READ_DUMP_DATA_ERR;
match set {
Some(x) => dumps::from_uncompressed_data(x).expect(msg),
#[cfg(feature = "preset-theme-set")]
_ => dumps::from_uncompressed_data(set.unwrap_or(hlight_assets::THEME_SET))
.expect(msg),
#[cfg(not(feature = "preset-theme-set"))]
_ => ThemeSet::default(),
}
}
impl HighlightResource<'_> {
pub fn get_or_init_theme(&self) -> &Theme {
self
.get_theme()
.get_or_init(|| {
let name = self.get_theme_name().as_str();
use HlightThemeSet::*;
match self.get_theme_set() {
Arc(set) => &set.themes[name],
Ref(set) => &set.themes[name],
}
.clone()
})
}
pub fn static_theme_set() -> &'static ThemeSet {
static S: LazyLock<ThemeSet> = LazyLock::new(|| load_theme_set(None));
&S
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn get_theme_set() {
let themes = &HighlightResource::static_theme_set().themes;
for t in themes.keys() {
println!("{t}")
}
}
#[ignore]
#[test]
fn test_load_custom_theme() {
use crate::{HighlightResource, theme::load_theme_set};
const THEMES: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../hlight-assets",
"/assets/set/theme.packdump"
));
fn show_theme_set(set: &HlightThemeSet) {
set
.get_inner()
.themes
.keys()
.for_each(|k| println!("{k}"))
}
let set = load_theme_set(Some(THEMES));
let res = HighlightResource::default()
.with_theme_set(set.into())
.with_theme_name("Custom-theme-name".into());
show_theme_set(res.get_theme_set())
}
}