use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::fmt::Debug;
use std::time::Duration;
use crate::error::SearchError;
use crate::types::{ExtractedContent, SearchConfig, SearchOptions, SearchResult};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchEngineInfo {
pub name: String,
pub display_name: String,
pub description: String,
pub supported_sources: Vec<String>,
pub max_results: usize,
pub supported_regions: Vec<String>,
pub supports_time_range: bool,
pub pricing: Option<SearchPricing>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchPricing {
pub cost_per_search: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExtractorInfo {
pub name: String,
pub display_name: String,
pub max_url_length: usize,
pub supports_batch: bool,
pub max_batch_size: usize,
}
#[async_trait]
pub trait SearchEngine: Send + Sync + Debug {
async fn search(
&self,
query: &str,
config: &SearchConfig,
options: &SearchOptions,
) -> Result<SearchResult, SearchError>;
fn engine_info(&self) -> &SearchEngineInfo;
}
#[async_trait]
pub trait ContentExtractor: Send + Sync + Debug {
async fn extract(&self, url: &str) -> Result<ExtractedContent, SearchError>;
async fn extract_batch(
&self,
urls: &[&str],
concurrency: usize,
) -> Result<Vec<ExtractedContent>, SearchError>;
fn extractor_info(&self) -> &ExtractorInfo;
}
#[async_trait]
pub trait SearchCache: Send + Sync + Debug {
async fn get(&self, key: &str) -> Option<SearchResult>;
async fn set(&self, key: &str, result: &SearchResult, ttl: Duration);
async fn invalidate(&self, key: &str);
fn stats(&self) -> CacheStats;
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CacheStats {
pub hits: u64,
pub misses: u64,
pub size_bytes: u64,
pub entry_count: usize,
}