mod llm_parser;
mod parser_trait;
mod rule_based;
pub use llm_parser::{ApiType, LlmParser};
pub use parser_trait::*;
pub use rule_based::RuleBasedParser;
use std::sync::Arc;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ParserType {
#[default]
RuleBased,
Llm,
}
#[derive(Debug, Clone)]
pub struct ParserConfig {
pub parser_type: ParserType,
pub llm_model_path: Option<String>,
pub llm_threads: usize,
pub llm_context_size: usize,
}
impl Default for ParserConfig {
fn default() -> Self {
Self {
parser_type: ParserType::RuleBased,
llm_model_path: None,
llm_threads: 4,
llm_context_size: 2048,
}
}
}
impl ParserConfig {
pub fn rule_based() -> Self {
Self::default()
}
pub fn llm(model_path: impl Into<String>) -> Self {
Self {
parser_type: ParserType::Llm,
llm_model_path: Some(model_path.into()),
..Default::default()
}
}
}
pub fn create_parser(config: ParserConfig) -> Arc<dyn QueryParser> {
match config.parser_type {
ParserType::RuleBased => Arc::new(RuleBasedParser::new()),
#[cfg(feature = "llm-parser")]
ParserType::Llm => {
let model_path = config
.llm_model_path
.expect("LLM model path required for LLM parser");
Arc::new(
LlmParser::new(&model_path, config.llm_threads, config.llm_context_size)
.expect("Failed to load LLM model"),
)
}
#[cfg(not(feature = "llm-parser"))]
ParserType::Llm => {
tracing::warn!("LLM parser requested but 'llm-parser' feature not enabled, falling back to rule-based");
Arc::new(RuleBasedParser::new())
}
}
}