use axum::Json; use axum::http::StatusCode; use axum::{debug_handler, response::IntoResponse}; use axum::extract::{Path, State}; use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use utoipa::{IntoResponses, ToSchema}; use crate::AppState; #[derive(ToSchema, Serialize, Deserialize)] pub struct OkResponse { id: i32, title: String, enabled: bool, time: DateTime, } #[derive(ToSchema, Deserialize)] pub struct PatchRequestBody { title: Option, enabled: Option, time: Option>, } #[derive(IntoResponses)] pub enum Responses { #[response(status = 200)] Ok(#[to_schema] OkResponse), #[response(status = 500, description = "Something failed in the Database when trying to update the alarm")] DbError(String), #[response(status = 404, description = "The alarm you want to update was not found")] NotFound, } impl IntoResponse for Responses { fn into_response(self) -> axum::response::Response { match self { Responses::Ok(body) => (StatusCode::OK, Json(body)).into_response(), Responses::DbError(message) => (StatusCode::INTERNAL_SERVER_ERROR, Json(message)).into_response(), Responses::NotFound => (StatusCode::NOT_FOUND).into_response(), } } } impl From for OkResponse { fn from(value: crate::types::Alarm) -> Self { OkResponse { id: value.id, title: value.title, enabled: value.enabled, time: value.time, } } } #[utoipa::path(patch, path = "/{id}", responses(Responses))] #[debug_handler] pub async fn patch_handler(State(AppState { scheduler }): State, Path(id): Path, Json(body): Json) -> Responses { let result = scheduler.update_alarm(id, body.title, body.enabled, body.time).await; match result { Ok(Some(alarm)) => { Responses::Ok(alarm.into()) }, Ok(None) => { Responses::NotFound }, Err(error) => { Responses::DbError(error.to_string()) } } }