use actix_session::Session; use actix_web::{HttpResponse, web}; use serde::Deserialize; use shanty_search::SearchProvider; use crate::auth; use crate::error::ApiError; use crate::state::AppState; #[derive(Deserialize)] pub struct ArtistSearchParams { q: String, #[serde(default = "default_limit")] limit: u32, } #[derive(Deserialize)] pub struct AlbumTrackSearchParams { q: String, artist: Option, #[serde(default = "default_limit")] limit: u32, } fn default_limit() -> u32 { 25 } pub fn configure(cfg: &mut web::ServiceConfig) { cfg.service(web::resource("/search/artist").route(web::get().to(search_artist))) .service(web::resource("/search/album").route(web::get().to(search_album))) .service(web::resource("/search/track").route(web::get().to(search_track))) .service(web::resource("/search/discography/{id}").route(web::get().to(get_discography))); } async fn search_artist( state: web::Data, session: Session, query: web::Query, ) -> Result { auth::require_auth(&session)?; let results = state.search.search_artist(&query.q, query.limit).await?; Ok(HttpResponse::Ok().json(results)) } async fn search_album( state: web::Data, session: Session, query: web::Query, ) -> Result { auth::require_auth(&session)?; let results = state .search .search_album(&query.q, query.artist.as_deref(), query.limit) .await?; Ok(HttpResponse::Ok().json(results)) } async fn search_track( state: web::Data, session: Session, query: web::Query, ) -> Result { auth::require_auth(&session)?; let results = state .search .search_track(&query.q, query.artist.as_deref(), query.limit) .await?; Ok(HttpResponse::Ok().json(results)) } async fn get_discography( state: web::Data, session: Session, path: web::Path, ) -> Result { auth::require_auth(&session)?; let artist_id = path.into_inner(); let disco = state.search.get_discography(&artist_id).await?; Ok(HttpResponse::Ok().json(disco)) }