use crate::eg::{Result, SearchResult};
use regex::Regex;
mod version;
mod cache;
mod extraction;
mod search;
pub use version::VersionResolver;
pub use cache::CacheManager;
pub use extraction::CrateExtractor;
pub use search::CrateSearcher;
pub struct RustCrateSearch {
crate_name: String,
version_spec: Option<String>,
pattern: Option<Regex>,
context_lines: usize,
}
impl RustCrateSearch {
pub fn new(name: &str) -> Self {
Self {
crate_name: name.to_string(),
version_spec: None,
pattern: None,
context_lines: 2, }
}
pub fn version(mut self, version: &str) -> Self {
self.version_spec = Some(version.to_string());
self
}
pub fn pattern(mut self, pattern: &str) -> Result<Self> {
let regex = Regex::new(pattern)
.map_err(|e| crate::eg::EgError::Other(format!("Invalid regex pattern: {}", e)))?;
self.pattern = Some(regex);
Ok(self)
}
pub async fn search(self) -> Result<SearchResult> {
let resolver = VersionResolver::new();
let version = resolver.resolve_version(&self.crate_name, self.version_spec.as_deref()).await?;
let cache_manager = CacheManager::new()?;
let extractor = CrateExtractor::new();
let checkout_path = cache_manager.get_or_extract_crate(&self.crate_name, &version, &extractor).await?;
let searcher = CrateSearcher::new();
let (example_matches, other_matches) = if let Some(pattern) = &self.pattern {
searcher.search_crate(&checkout_path, pattern, self.context_lines)?
} else {
(Vec::new(), Vec::new())
};
Ok(SearchResult {
version,
checkout_path,
example_matches,
other_matches,
})
}
}