use crate::error::CCSwarmError;
use async_trait::async_trait;
#[derive(Debug, Clone)]
pub struct SearchResult {
pub title: String,
pub url: String,
pub snippet: String,
pub source: String,
pub score: f64,
pub relevance_score: f64,
}
#[derive(Debug, Clone)]
pub struct SearchQuery {
pub keywords: Vec<String>,
pub context: Option<SearchContext>,
pub filters: Option<SearchFilters>,
}
#[derive(Debug, Clone)]
pub enum SearchContext {
CapabilityGap {
current: Vec<String>,
required: Vec<String>,
desired: Vec<String>,
},
ErrorResolution {
error_type: String,
context: String,
},
FeatureImplementation {
feature: String,
technology: String,
},
}
#[derive(Debug, Clone)]
pub struct SearchFilters {
pub language: Option<String>,
pub framework: Option<String>,
pub date_range: Option<(String, String)>,
pub min_relevance: f64,
pub max_complexity: f64,
pub preferred_sources: Vec<String>,
pub relevance_threshold: f64,
}
#[async_trait]
pub trait SearchStrategy: Send + Sync {
async fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>, CCSwarmError>;
fn name(&self) -> &str;
}
pub struct DocumentationSearchStrategy;
impl Default for DocumentationSearchStrategy {
fn default() -> Self {
Self::new()
}
}
impl DocumentationSearchStrategy {
pub fn new() -> Self {
Self
}
}
#[async_trait]
impl SearchStrategy for DocumentationSearchStrategy {
async fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>, CCSwarmError> {
let keywords = query.keywords.join(" ");
Ok(vec![SearchResult {
title: format!("MDN: {} Documentation", keywords),
url: format!("https://developer.mozilla.org/search?q={}", keywords),
snippet: format!("Documentation for {} from MDN Web Docs", keywords),
source: "MDN".to_string(),
score: 0.95,
relevance_score: 0.95,
}])
}
fn name(&self) -> &str {
"MDN Documentation"
}
}
pub struct GitHubSearchStrategy;
impl Default for GitHubSearchStrategy {
fn default() -> Self {
Self::new()
}
}
impl GitHubSearchStrategy {
pub fn new() -> Self {
Self
}
}
#[async_trait]
impl SearchStrategy for GitHubSearchStrategy {
async fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>, CCSwarmError> {
let keywords = query.keywords.join(" ");
Ok(vec![SearchResult {
title: format!("GitHub: {} Examples", keywords),
url: format!("https://github.com/search?q={}", keywords),
snippet: format!("Code examples for {} from GitHub repositories", keywords),
source: "GitHub".to_string(),
score: 0.85,
relevance_score: 0.85,
}])
}
fn name(&self) -> &str {
"GitHub"
}
}
pub struct StackOverflowSearchStrategy;
#[async_trait]
impl SearchStrategy for StackOverflowSearchStrategy {
async fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>, CCSwarmError> {
let keywords = query.keywords.join(" ");
Ok(vec![SearchResult {
title: format!("StackOverflow: {} Questions", keywords),
url: format!("https://stackoverflow.com/search?q={}", keywords),
snippet: format!(
"Questions and answers about {} from StackOverflow",
keywords
),
source: "StackOverflow".to_string(),
score: 0.90,
relevance_score: 0.90,
}])
}
fn name(&self) -> &str {
"StackOverflow"
}
}