ockam_api 0.93.0

Ockam's request-response API
use crate::Result;
use miette::{miette, IntoDiagnostic};
use once_cell::sync::Lazy;
use std::time::Duration;
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, Theme, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet};
use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings};

pub static SYNTAX_SET_NEWLINES: Lazy<SyntaxSet> = Lazy::new(SyntaxSet::load_defaults_newlines);

pub static THEME: Lazy<Theme> = Lazy::new(|| {
    let mut theme_set = ThemeSet::load_defaults();
    let default_theme = theme_set.themes.remove("base16-ocean.dark").unwrap_or(
        theme_set.themes.remove("base16-ocean.light").unwrap_or(
            theme_set
                .themes
                .pop_first()
                .map(|(_, theme)| theme)
                .unwrap_or_default(),
        ),
    );
    match termbg::theme(Duration::from_millis(100)) {
        Ok(termbg::Theme::Light) => theme_set.themes.remove("base16-ocean.light"),
        Ok(termbg::Theme::Dark) => theme_set.themes.remove("base16-ocean.dark"),
        Err(_) => None,
    }
    .unwrap_or(default_theme)
});

pub struct TextHighlighter<'a> {
    pub syntax: &'a SyntaxReference,
    pub theme: &'a Theme,
}

impl TextHighlighter<'_> {
    pub fn new(syntax: &str) -> Result<Self> {
        let syntax = SYNTAX_SET_NEWLINES
            .find_syntax_by_extension(syntax)
            .ok_or_else(|| miette!("Syntax {syntax} not found"))?;
        Ok(Self {
            syntax,
            theme: &THEME,
        })
    }

    pub fn process(&self, text: &str) -> Result<String> {
        let mut h = HighlightLines::new(self.syntax, self.theme);
        let mut highlighted_text = String::new();
        for line in LinesWithEndings::from(text) {
            let ranges: Vec<(Style, &str)> = h
                .highlight_line(line, &SYNTAX_SET_NEWLINES)
                .into_diagnostic()?;
            highlighted_text.push_str(&as_24_bit_terminal_escaped(&ranges[..], false));
        }
        Ok(highlighted_text)
    }
}