71 lines
2.4 KiB
Rust
71 lines
2.4 KiB
Rust
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<Arc<AppState>>,
|
|
Json(body): Json<ParseRequest>,
|
|
) -> Result<Json<domain::StoredSong>, (StatusCode, Json<ErrorResponse>)> {
|
|
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<Arc<AppState>>,
|
|
) -> Result<Json<Vec<domain::SongSummary>>, (StatusCode, Json<ErrorResponse>)> {
|
|
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<Arc<AppState>>,
|
|
Path(id): Path<String>,
|
|
) -> Result<Json<domain::Song>, (StatusCode, Json<ErrorResponse>)> {
|
|
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<Arc<AppState>>,
|
|
Path(id): Path<String>,
|
|
) -> Result<StatusCode, (StatusCode, Json<ErrorResponse>)> {
|
|
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() }))),
|
|
}
|
|
}
|