📄 GitBrowser.SyntaxHighlighter/src/lib.rs
use std::ffi::{CStr, CString, c_char};

use syntect::{
    highlighting::ThemeSet,
    html::highlighted_html_for_string,
    parsing::{SyntaxReference, SyntaxSet},
};

#[unsafe(no_mangle)]
pub extern "C" fn highlight_syntax_html(
    file_extension: *const c_char,
    text: *const c_char,
) -> *const c_char {
    let Some((ss, syntax)) = get_syntax(file_extension) else {
        return CString::default().into_raw();
    };

    let Ok(text) = unsafe { CStr::from_ptr(text) }.to_str() else {
        return CString::default().into_raw();
    };

    let ts = ThemeSet::load_defaults();
    let github_theme = &ts.themes["base16-ocean.dark"];

    let Ok(highlighted) = highlighted_html_for_string(text, &ss, &syntax, github_theme) else {
        return CString::default().into_raw();
    };
    CString::new(highlighted)
        .unwrap_or_else(|_| CString::default())
        .into_raw()
}

fn get_syntax(file_extension: *const c_char) -> Option<(SyntaxSet, SyntaxReference)> {
    let Ok(ext) = unsafe { CStr::from_ptr(file_extension) }.to_str() else {
        return None;
    };

    let ss = SyntaxSet::load_defaults_newlines();
    ss.find_syntax_by_extension(ext.chars().skip(1).collect::<String>().as_str())
        .cloned()
        .map(|syntax| (ss, syntax))
}