summaryrefslogtreecommitdiffstats
path: root/src/helpers/highlight.rs
blob: f6ca98f244af9c3974bd0e82c9a63a6635ca2324 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use anyhow::Result;
use cached::Return;
use cached::SizedCache;
use cached::proc_macro::cached;
use syntect::highlighting::Theme;
use syntect::html::highlighted_html_for_string;
use syntect::parsing::SyntaxSet;

#[cached(
    type = "SizedCache<String, Return<String>>",
    create = "{ SizedCache::with_size(100) }",
    convert = r#"{ s.to_string() }"#,

    with_cached_flag = true,
    result = true,
)]
pub fn highlight(s: &str, theme: &Theme, ext: Option<&str>) -> Result<cached::Return<String>> {
    let syntax_set = SyntaxSet::load_defaults_newlines();

    log::trace!("Finding syntax for {:?}", ext);
    let syntax = match ext {
        Some(ext) => {
            log::trace!("Trying by extension ({:?})", ext);
            syntax_set.find_syntax_by_extension(ext)
                .or_else(|| {
                    log::trace!("Trying by first line...");
                    syntax_set.find_syntax_by_first_line(s)
                })
        },
        None => {
            log::trace!("Trying by first line...");
            syntax_set.find_syntax_by_first_line(s)
        },
    }
    .unwrap_or_else(|| {
        log::trace!("Using plaintext");
        syntax_set.find_syntax_plain_text()
    });
    log::trace!("Found syntax for {:?} = {:?}", ext, syntax);

    Ok(Return::new(highlighted_html_for_string(s, &syntax_set, &syntax, theme)))
}