codesnap/utils/
theme_provider.rs

1use syntect::{
2    dumps::from_binary,
3    highlighting::{Color, Theme, ThemeSet},
4};
5
6use anyhow::Context;
7
8use crate::{components::interface::render_error::RenderError, config::SnapshotConfig};
9
10const PRESET_THEMES: &[u8] = include_bytes!("../../assets/code_themes/default.themedump");
11
12pub struct ThemeColor(Color);
13
14#[derive(Debug, Clone)]
15pub struct ThemeProvider {
16    pub theme: Theme,
17}
18
19impl Into<tiny_skia::Color> for ThemeColor {
20    fn into(self) -> tiny_skia::Color {
21        tiny_skia::Color::from_rgba8(self.0.r, self.0.g, self.0.b, self.0.a)
22    }
23}
24
25impl ThemeProvider {
26    pub fn from(themes_folders: Vec<String>, theme: &str) -> anyhow::Result<ThemeProvider> {
27        let mut theme_set: ThemeSet = from_binary(PRESET_THEMES);
28
29        for folder in themes_folders {
30            theme_set
31                .add_from_folder(folder)
32                .map_err(|_| RenderError::HighlightThemeLoadFailed)?;
33        }
34
35        let theme = theme_set
36            .themes
37            .get(theme)
38            .context(format!("Cannot find {} theme", theme))?
39            .to_owned();
40
41        Ok(ThemeProvider { theme })
42    }
43
44    pub fn from_config(config: &SnapshotConfig) -> anyhow::Result<ThemeProvider> {
45        ThemeProvider::from(config.themes_folders.clone(), &config.theme)
46    }
47
48    pub fn theme_background(&self) -> ThemeColor {
49        ThemeColor(self.theme.settings.background.unwrap_or(Color {
50            r: 0,
51            g: 0,
52            b: 0,
53            a: 0,
54        }))
55    }
56}