use crate::types::{SearchOptions, SearchResult};
use std::path::Path;
pub trait SearchEngine: Send + Sync {
fn search(
&self,
query: &str,
path: &Path,
options: &SearchOptions,
) -> Result<Vec<SearchResult>, Box<dyn std::error::Error>>;
}
pub trait Analyzer: Send + Sync {
type Output;
fn analyze(
&self,
path: &Path,
extensions: Option<&[String]>,
) -> Result<Self::Output, Box<dyn std::error::Error>>;
}
pub trait GraphBuilder: Send + Sync {
type Graph;
fn build(
&self,
source: &str,
name: Option<&str>,
) -> Result<Self::Graph, Box<dyn std::error::Error>>;
}
#[cfg(test)]
mod tests {
use super::*;
struct MockSearchEngine {
results: Vec<SearchResult>,
}
impl SearchEngine for MockSearchEngine {
fn search(
&self,
_query: &str,
_path: &Path,
_options: &SearchOptions,
) -> Result<Vec<SearchResult>, Box<dyn std::error::Error>> {
Ok(self.results.clone())
}
}
struct MockAnalyzer {
output: String,
}
impl Analyzer for MockAnalyzer {
type Output = String;
fn analyze(
&self,
_path: &Path,
_extensions: Option<&[String]>,
) -> Result<Self::Output, Box<dyn std::error::Error>> {
Ok(self.output.clone())
}
}
#[test]
fn test_mock_search_engine() {
let engine = MockSearchEngine { results: vec![] };
let options = SearchOptions::default();
let result = engine.search("test", Path::new("."), &options);
assert!(result.is_ok());
assert_eq!(result.unwrap().len(), 0);
}
#[test]
fn test_mock_analyzer() {
let analyzer = MockAnalyzer {
output: "test output".to_string(),
};
let result = analyzer.analyze(Path::new("."), None);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "test output");
}
}