use axum::{ extract::{Path, State}, http::StatusCode, Json, }; use domain::RepositoryError; use std::sync::Arc; use uuid::Uuid; use crate::routes::tabs::{AppState, ErrorResponse, ParseRequest, resolve_html}; pub async fn create_song( State(state): State>, Json(body): Json, ) -> Result, (StatusCode, Json)> { let html = resolve_html(&state, body).await.map_err(|e| { (StatusCode::BAD_REQUEST, Json(ErrorResponse { error: e })) })?; let song = state.parser.parse(&html).map_err(|e| { (StatusCode::UNPROCESSABLE_ENTITY, Json(ErrorResponse { error: e.to_string() })) })?; let stored = state.songs.save(&song).await.map_err(|e| { (StatusCode::INTERNAL_SERVER_ERROR, Json(ErrorResponse { error: e.to_string() })) })?; Ok(Json(stored)) } pub async fn list_songs( State(state): State>, ) -> Result>, (StatusCode, Json)> { let songs = state.songs.list().await.map_err(|e| { (StatusCode::INTERNAL_SERVER_ERROR, Json(ErrorResponse { error: e.to_string() })) })?; Ok(Json(songs)) } pub async fn get_song( State(state): State>, Path(id): Path, ) -> Result, (StatusCode, Json)> { let uuid = Uuid::parse_str(&id).map_err(|_| { (StatusCode::BAD_REQUEST, Json(ErrorResponse { error: "Invalid ID".into() })) })?; match state.songs.get(uuid).await { Ok(Some(song)) => Ok(Json(song)), Ok(None) => Err((StatusCode::NOT_FOUND, Json(ErrorResponse { error: "Not found".into() }))), Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ErrorResponse { error: e.to_string() }))), } } pub async fn delete_song( State(state): State>, Path(id): Path, ) -> Result)> { let uuid = Uuid::parse_str(&id).map_err(|_| { (StatusCode::BAD_REQUEST, Json(ErrorResponse { error: "Invalid ID".into() })) })?; match state.songs.delete(uuid).await { Ok(()) => Ok(StatusCode::NO_CONTENT), Err(RepositoryError::NotFound) => { Err((StatusCode::NOT_FOUND, Json(ErrorResponse { error: "Not found".into() }))) } Err(e) => Err((StatusCode::INTERNAL_SERVER_ERROR, Json(ErrorResponse { error: e.to_string() }))), } }