openserve 2.0.3

A modern, high-performance, AI-enhanced file server built in Rust
Documentation
//! Search handlers

use axum::{
    extract::{Query, State},
    response::IntoResponse,
    Json,
};
use serde::Deserialize;
use tracing::{debug, error};
use serde_json;
use axum::http::StatusCode;

use crate::{
    server::AppState,
    models::SearchRequest,
    handlers::{error_response, success_response},
};

/// Query parameters for search operations.
#[derive(Debug, Deserialize)]
pub struct SearchQuery {
    /// The search query string.
    pub q: String,
    /// The maximum number of results to return.
    pub limit: Option<usize>,
}

/// Full-text search
pub async fn search(
    Query(query): Query<SearchQuery>,
    State(state): State<AppState>,
) -> impl IntoResponse {
    debug!("Searching for: {}", query.q);

    let limit = query.limit.unwrap_or(20);

    match state.search_service.search(&query.q, limit).await {
        Ok(results) => success_response(StatusCode::OK, &serde_json::to_string(&results).unwrap_or_default()),
        Err(e) => {
            error!("Search failed: {}", e);
            error_response(axum::http::StatusCode::INTERNAL_SERVER_ERROR, &e.to_string())
        }
    }
}

/// Semantic search using AI
pub async fn semantic_search(
    State(state): State<AppState>,
    Json(request): Json<SearchRequest>,
) -> impl IntoResponse {
    debug!("Semantic search for: {}", request.query);

    let limit = request.limit.unwrap_or(10);

    match state.search_service.semantic_search(&request.query, limit).await {
        Ok(results) => success_response(StatusCode::OK, &serde_json::to_string(&results).unwrap_or_default()),
        Err(e) => {
            error!("Semantic search failed: {}", e);
            error_response(axum::http::StatusCode::INTERNAL_SERVER_ERROR, &e.to_string())
        }
    }
}

/// File-based search (search through filenames and metadata)
pub async fn file_search(
    Query(query): Query<SearchQuery>,
    State(state): State<AppState>,
) -> impl IntoResponse {
    debug!("File search for: {}", query.q);

    let limit = query.limit.unwrap_or(20);

    match state.search_service.search(&query.q, limit).await {
        Ok(results) => success_response(StatusCode::OK, &serde_json::to_string(&results).unwrap_or_default()),
        Err(e) => {
            error!("File search failed: {}", e);
            error_response(axum::http::StatusCode::INTERNAL_SERVER_ERROR, &e.to_string())
        }
    }
}