use regex::Regex;
use crate::models::SymbolKind;
#[derive(Debug, Clone)]
pub struct QueryFilter {
pub language: Option<crate::models::Language>,
pub kind: Option<SymbolKind>,
pub use_ast: bool,
pub use_regex: bool,
pub limit: Option<usize>,
pub symbols_mode: bool,
pub expand: bool,
pub file_pattern: Option<String>,
pub exact: bool,
pub use_contains: bool,
pub timeout_secs: u64,
pub glob_patterns: Vec<String>,
pub exclude_patterns: Vec<String>,
pub paths_only: bool,
pub offset: Option<usize>,
pub force: bool,
pub suppress_output: bool,
pub include_dependencies: bool,
pub context_lines: usize,
#[doc(hidden)]
pub test_large_index_threshold: Option<usize>,
#[doc(hidden)]
pub test_short_pattern_threshold: Option<usize>,
}
impl Default for QueryFilter {
fn default() -> Self {
Self {
language: None,
kind: None,
use_ast: false,
use_regex: false,
limit: Some(100), symbols_mode: false,
expand: false,
file_pattern: None,
exact: false,
use_contains: false, timeout_secs: 30, glob_patterns: Vec::new(),
exclude_patterns: Vec::new(),
paths_only: false,
offset: None,
force: false, suppress_output: false, include_dependencies: false, context_lines: 0, test_large_index_threshold: None, test_short_pattern_threshold: None, }
}
}
pub fn keyword_to_kind(keyword: &str) -> Option<SymbolKind> {
match keyword {
"class" => Some(SymbolKind::Class),
"struct" => Some(SymbolKind::Struct),
"enum" => Some(SymbolKind::Enum),
"interface" => Some(SymbolKind::Interface),
"trait" => Some(SymbolKind::Trait),
"type" => Some(SymbolKind::Type),
"record" => Some(SymbolKind::Struct), "function" | "fn" | "def" | "func" => Some(SymbolKind::Function),
"const" | "static" => Some(SymbolKind::Constant),
"var" | "let" => Some(SymbolKind::Variable),
"mod" | "module" | "namespace" => Some(SymbolKind::Module),
"impl" | "async" => None,
_ => None,
}
}
pub fn has_word_boundary_match(line: &str, pattern: &str) -> bool {
let escaped_pattern = regex::escape(pattern);
let pattern_with_boundaries = format!(r"\b{}\b", escaped_pattern);
if let Ok(re) = Regex::new(&pattern_with_boundaries) {
re.is_match(line)
} else {
log::debug!(
"Word boundary regex failed for pattern '{}', falling back to substring",
pattern
);
line.contains(pattern)
}
}