Skip to main content

sem_core/parser/
registry.rs

1use std::collections::HashMap;
2use std::path::Path;
3
4use super::plugin::SemanticParserPlugin;
5
6pub struct ParserRegistry {
7    plugins: Vec<Box<dyn SemanticParserPlugin>>,
8    extension_map: HashMap<String, usize>, // ext → index into plugins
9}
10
11impl ParserRegistry {
12    pub fn new() -> Self {
13        Self {
14            plugins: Vec::new(),
15            extension_map: HashMap::new(),
16        }
17    }
18
19    pub fn register(&mut self, plugin: Box<dyn SemanticParserPlugin>) {
20        let idx = self.plugins.len();
21        for ext in plugin.extensions() {
22            self.extension_map.insert(ext.to_string(), idx);
23        }
24        self.plugins.push(plugin);
25    }
26
27    pub fn get_plugin(&self, file_path: &str) -> Option<&dyn SemanticParserPlugin> {
28        let ext = get_extension(file_path);
29        if let Some(&idx) = self.extension_map.get(&ext) {
30            return Some(self.plugins[idx].as_ref());
31        }
32        // Fallback plugin
33        self.get_plugin_by_id("fallback")
34    }
35
36    pub fn get_plugin_by_id(&self, id: &str) -> Option<&dyn SemanticParserPlugin> {
37        self.plugins.iter().find(|p| p.id() == id).map(|p| p.as_ref())
38    }
39}
40
41fn get_extension(file_path: &str) -> String {
42    Path::new(file_path)
43        .extension()
44        .and_then(|e| e.to_str())
45        .map(|e| format!(".{}", e.to_lowercase()))
46        .unwrap_or_default()
47}