use anyhow::{Context, Result, bail};
use std::collections::HashMap;
use tree_sitter::{Language, Parser};
use crate::config::QueryConfig;
pub struct LanguageEntry {
pub language: Language,
pub queries: HashMap<String, QueryConfig>,
}
pub fn build_registry(
user_configs: &HashMap<String, crate::config::LanguageConfig>,
book_root: &std::path::Path,
) -> Result<HashMap<String, LanguageEntry>> {
let mut registry: HashMap<String, LanguageEntry> = HashMap::new();
{
registry.insert(
"rs".into(),
LanguageEntry {
language: Language::new(tree_sitter_rust::LANGUAGE),
queries: HashMap::new(),
},
);
}
{
registry.insert(
"toml".into(),
LanguageEntry {
language: tree_sitter_toml::language(),
queries: HashMap::new(),
},
);
}
{
registry.insert(
"md".into(),
LanguageEntry {
language: Language::new(tree_sitter_md::LANGUAGE),
queries: HashMap::new(),
},
);
}
for (lang_name, lang_cfg) in user_configs {
let ext = lang_name_to_ext(lang_name);
if let Some(parser_path_str) = &lang_cfg.parser {
let parser_path = if std::path::Path::new(parser_path_str).is_absolute() {
std::path::PathBuf::from(parser_path_str)
} else {
book_root.join(parser_path_str)
};
let language = unsafe { load_language_from_so(&parser_path)? };
let entry = registry
.entry(ext.to_string())
.or_insert_with(|| LanguageEntry {
language: language.clone(),
queries: HashMap::new(),
});
entry.language = language;
}
if let Some(entry) = registry.get_mut(ext) {
for (qname, qcfg) in &lang_cfg.queries {
entry.queries.insert(qname.clone(), qcfg.clone());
}
}
}
Ok(registry)
}
fn lang_name_to_ext(name: &str) -> &str {
match name {
"rust" => "rs",
"markdown" => "md",
"javascript" => "js",
"typescript" => "ts",
"python" => "py",
"c" => "c",
"cpp" | "c++" => "cpp",
"go" => "go",
other => other,
}
}
unsafe fn load_language_from_so(_path: &std::path::Path) -> Result<Language> {
bail!(
"Dynamic parser loading from `{}` is not yet supported in this build.",
_path.display()
)
}
pub fn make_parser(language: &Language) -> Result<Parser> {
let mut parser = Parser::new();
parser
.set_language(language)
.context("Failed to configure parser")?;
Ok(parser)
}