diff --git a/src/main.rs b/src/main.rs index 38d7f14..e187c25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,14 +69,19 @@ async fn main() { }); let (router, mut api) = OpenApiRouter::new() + // Book API .routes(routes!(routes::book::get_book_by_ean)) .routes(routes!(routes::book::get_book_by_id)) + // Book Instance API .routes(routes!(routes::book_instance::get_book_instance_by_id)) .routes(routes!(routes::book_instance::create_book_instance)) + .routes(routes!(routes::book_instance::update_book_instance)) + // Owner API .routes(routes!(routes::owner::get_owner_by_id)) .routes(routes!(routes::owner::create_owner)) .routes(routes!(routes::owner::update_owner)) .routes(routes!(routes::owner::get_owners)) + // Misc .routes(routes!(routes::websocket::ws_handler)) .route("/", get(index)) .with_state(shared_state) diff --git a/src/routes/book_instance.rs b/src/routes/book_instance.rs index eb635a8..7e10919 100644 --- a/src/routes/book_instance.rs +++ b/src/routes/book_instance.rs @@ -17,7 +17,7 @@ struct BookInstanceByIdParams(u32); #[axum::debug_handler] #[utoipa::path( get, - path = "/book_instance/id/{id}", + path = "/book_instance/{id}", params(BookInstanceByIdParams), responses( (status = OK, body = book_instance::Model, description = "Found book instance with corresponding ID in the database"), @@ -79,3 +79,60 @@ pub async fn create_book_instance( Ok(res) => (StatusCode::OK, Json(Some(res.try_into_model().expect("All fields should be set once the book instance is saved")))) } } + +#[derive(Deserialize, Serialize, utoipa::ToSchema)] +pub struct BookInstanceUpdateParams { + status: Option, + owner_id: Option, + price: Option, +} + +#[axum::debug_handler] +#[utoipa::path( + patch, + path = "/book_instance/{id}", + params(BookInstanceByIdParams), + request_body = BookInstanceUpdateParams, + responses( + (status = OK, body = book_instance::Model, description = "Successfully updated book instance"), + (status = NOT_FOUND, description = "No book instance with specified id was found"), + ), + summary = "Update a book instance", + description = "Update a book instance", + tag = "book-instance-api", +)] +pub async fn update_book_instance( + State(state): State>, + Path(id): Path, + Json(instance_payload): Json, +) -> (StatusCode, Json>) { + + if let Ok(Some(book_instance)) = BookInstance::find_by_id(id).one(state.db_conn.as_ref()).await { + let mut book_instance: book_instance::ActiveModel = book_instance.into(); + book_instance.price = match instance_payload.price { + None => book_instance.price, + Some(v) => Set(v) + }; + book_instance.owner_id = match instance_payload.owner_id { + None => book_instance.owner_id, + Some(v) => Set(v) + }; + book_instance.status = match instance_payload.status { + None => book_instance.status, + Some(v) => Set(v) + }; + + match book_instance.update(state.db_conn.as_ref()).await { + Err(e) => { + log::error!(target: "api", "Error while updating book instance from api: {:#?}", e); + (StatusCode::INTERNAL_SERVER_ERROR, Json(None)) + }, + Ok(res) => { + let model = res.try_into_model().expect("All fields should be set once the book instance is saved"); + (StatusCode::OK, Json(Some(model))) + } + } + } else { + (StatusCode::NOT_FOUND, Json(None)) + } +}