pub mod local;
pub mod remote;
use serde::Serialize;
use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum SearchScope {
Local,
Remote,
RemoteRepo(String),
}
#[derive(Debug, Clone)]
pub struct SearchQuery {
pub query: String,
pub scope: SearchScope,
pub limit: usize,
pub embedding: Option<bool>,
}
#[derive(Debug, Clone, Serialize)]
pub struct SearchResultItem {
pub id: String,
pub name: String,
pub description: Option<String>,
pub source: String,
pub similarity: Option<f32>,
pub path: Option<String>,
pub repository: Option<String>,
}
impl fmt::Display for SearchResultItem {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}: {}",
self.name,
self.description.as_deref().unwrap_or("No description")
)
}
}
#[derive(Debug, thiserror::Error)]
pub enum SearchError {
#[error("Configuration error: {0}")]
Config(String),
#[error("Validation error: {0}")]
Validation(String),
#[error("Service error: {0}")]
Service(#[from] crate::ServiceError),
#[error("Repository error: {0}")]
Repository(String),
}
pub async fn execute(
query: SearchQuery,
service: &crate::FastSkillService,
) -> Result<Vec<SearchResultItem>, SearchError> {
let scope = query.scope.clone();
match scope {
SearchScope::Local => local::execute_local_search(query, service).await,
SearchScope::Remote => remote::execute_remote_search(query, None).await,
SearchScope::RemoteRepo(repo_name) => {
remote::execute_remote_search(query, Some(repo_name)).await
}
}
}