use axum::{ extract::{Path, State}, http::StatusCode, routing::{get, post}, Json, Router, }; use serde::{Deserialize, Serialize}; use crate::indexer::{MusicSearchCriteria, SearchResult}; use crate::services::IndexerInfo; use crate::AppState; pub fn routes() -> Router { Router::new() .route("/", get(list_indexers)) .route("/search", post(search)) .route("/:name/test", get(test_indexer)) } async fn list_indexers(State(state): State) -> Json> { let state = state.read().await; Json(state.indexer_service.list_indexers()) } #[derive(Debug, Deserialize)] pub struct SearchRequest { pub artist: String, pub album: Option, pub year: Option, pub limit: Option, pub indexer: Option, } #[derive(Debug, Serialize)] pub struct SearchResponse { pub results: Vec, pub total: usize, } async fn search( State(state): State, Json(req): Json, ) -> Result, (StatusCode, String)> { let mut criteria = MusicSearchCriteria::new(&req.artist); if let Some(album) = &req.album { criteria = criteria.with_album(album); } if let Some(year) = req.year { criteria = criteria.with_year(year); } if let Some(limit) = req.limit { criteria = criteria.with_limit(limit); } let state = state.read().await; let results = state .indexer_service .search(&criteria, req.indexer.as_deref()) .await .map_err(|e| (StatusCode::BAD_GATEWAY, e.to_string()))?; let total = results.len(); Ok(Json(SearchResponse { results, total })) } #[derive(Debug, Serialize)] pub struct TestResponse { pub success: bool, pub message: String, } async fn test_indexer( State(state): State, Path(name): Path, ) -> Result, (StatusCode, Json)> { let state = state.read().await; match state.indexer_service.test_indexer(&name).await { Ok(()) => Ok(Json(TestResponse { success: true, message: "Connection successful".to_string(), })), Err(e) => Err(( StatusCode::BAD_GATEWAY, Json(TestResponse { success: false, message: e.to_string(), }), )), } }