diff --git a/src/main.rs b/src/main.rs index 70d7976..233ccf4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,21 +69,12 @@ 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)) - .routes(routes!(routes::book_instance::sell_book_instance)) - .routes(routes!(routes::book_instance::bulk_create_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 9eb8bea..eb635a8 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}", + path = "/book_instance/id/{id}", params(BookInstanceByIdParams), responses( (status = OK, body = book_instance::Model, description = "Found book instance with corresponding ID in the database"), @@ -79,140 +79,3 @@ 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)) - } -} - -#[derive(Deserialize, Serialize, utoipa::ToSchema)] -pub struct BookInstanceSaleParams { - price: i32, -} - -#[axum::debug_handler] -#[utoipa::path( - post, - path = "/book_instance/{id}/sell", - params(BookInstanceByIdParams), - request_body = BookInstanceSaleParams, - responses( - (status = OK, body = book_instance::Model, description = "Successfully sold book instance"), - (status = NOT_FOUND, description = "No book instance with specified id was found"), - ), - summary = "Sell a book instance", - description = "Sell a book instance", - tag = "book-instance-api", -)] -pub async fn sell_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.sold_price = Set(Some(instance_payload.price)); - book_instance.status = Set(book_instance::BookStatus::Sold); - - match book_instance.update(state.db_conn.as_ref()).await { - Err(e) => { - log::error!(target: "api", "Error while selling 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)) - } -} -#[axum::debug_handler] -#[utoipa::path( - post, - path = "/book_instance/bulk", - request_body = Vec, - responses( - (status = OK, description = "Successfully created book instances"), - ), - summary = "Create new book instances in bulk", - description = "Create new book instances in bulk", - tag = "book-instance-api", -)] -pub async fn bulk_create_book_instance( - State(state): State>, - Json(instance_payload): Json>, -) -> StatusCode { - - let instances = instance_payload - .into_iter() - .map(|p| book_instance::ActiveModel { - book_id: Set(p.book_id), - owner_id: Set(p.owner_id), - price: Set(p.price), - status: Set(book_instance::BookStatus::Available), - ..Default::default() - }); - - match BookInstance::insert_many(instances).exec(state.db_conn.as_ref()).await { - Err(e) => { - log::error!(target: "api", "Error while bulk inserting new book instances: {:#?}", e); - StatusCode::INTERNAL_SERVER_ERROR - }, - Ok(_) => StatusCode::OK - } -} diff --git a/src/routes/owner.rs b/src/routes/owner.rs index 0ba5c6c..85bee5f 100644 --- a/src/routes/owner.rs +++ b/src/routes/owner.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use axum::{extract::{Path, State}, Json}; use reqwest::{StatusCode}; -use sea_orm::{ActiveModelTrait, ActiveValue::{NotSet, Set, Unchanged}, EntityTrait, TryIntoModel}; +use sea_orm::{ActiveModelTrait, ActiveValue::{NotSet, Set}, EntityTrait, TryIntoModel}; use serde::{Deserialize, Serialize}; use utoipa::IntoParams; @@ -82,86 +82,3 @@ pub async fn create_owner( } } } - -#[derive(Deserialize, Serialize, utoipa::ToSchema)] -pub struct OwnerUpdateParams { - first_name: Option, - last_name: Option, - contact: Option -} - -#[axum::debug_handler] -#[utoipa::path( - patch, - path = "/owner/{id}", - params(OwnerByIdParams), - request_body = OwnerUpdateParams, - responses( - (status = OK, body = owner::Model, description = "Successfully updated owner"), - (status = NOT_FOUND, description = "No owner with this id exists in the database") - ), - summary = "Update an owner", - description = "Update an owner", - tag = "owner-api", -)] -pub async fn update_owner( - State(state): State>, - Path(id): Path, - Json(instance_payload): Json, -) -> (StatusCode, Json>) { - - if let Ok(Some(owner)) = Owner::find_by_id(id).one(state.db_conn.as_ref()).await { - let mut owner: owner::ActiveModel = owner.into(); - owner.first_name = match instance_payload.first_name { - None => owner.first_name, - Some(v) => Set(v) - }; - owner.last_name = match instance_payload.last_name { - None => owner.last_name, - Some(v) => Set(v) - }; - owner.contact = match instance_payload.contact { - None => owner.contact, - Some(v) => Set(v) - }; - - match owner.update(state.db_conn.as_ref()).await { - Err(e) => { - log::error!(target: "api", "Error while updating owner 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 owner is saved"); - let _ = state.event_bus.send(Event::WebsocketBroadcast(WebsocketMessage::NewOwner(Arc::new(model.clone())))); - (StatusCode::OK, Json(Some(model))) - } - } - } else { - (StatusCode::NOT_FOUND, Json(None)) - } -} - -#[axum::debug_handler] -#[utoipa::path( - get, - path = "/owners", - responses( - (status = OK, body = Vec, description = "List of owners"), - ), - summary = "List book owners", - description = "List book owners", - tag = "owner-api", -)] -pub async fn get_owners( - State(state): State>, -) -> (StatusCode, Json>>) { - match Owner::find().all(state.db_conn.as_ref()).await { - Err(e) => { - log::error!(target: "api", "Error while getting owner list: {:#?}", e); - (StatusCode::INTERNAL_SERVER_ERROR, Json(None)) - } - Ok(owners) => { - (StatusCode::OK, Json(Some(owners))) - } - } -} diff --git a/src/routes/websocket.rs b/src/routes/websocket.rs index 264697a..8590755 100644 --- a/src/routes/websocket.rs +++ b/src/routes/websocket.rs @@ -5,8 +5,9 @@ use axum::{ ws::{Message, Utf8Bytes, WebSocket, WebSocketUpgrade}, ConnectInfo, State - }, response::IntoResponse + }, http, response::IntoResponse }; +use reqwest::StatusCode; use crate::{utils::events, AppState}; @@ -72,7 +73,6 @@ async fn handle_socket(mut socket: WebSocket, who: SocketAddr, state: Arc { match event { events::Event::WebsocketBroadcast(message) => { - log::debug!(target: "websocket", "Sent {message:?} to {who}"); let _ = sender.send(Message::Text(Utf8Bytes::from(message.to_json().to_string()))).await; } } diff --git a/src/utils/events.rs b/src/utils/events.rs index 1715fa3..6ca8285 100644 --- a/src/utils/events.rs +++ b/src/utils/events.rs @@ -9,7 +9,7 @@ pub enum Event { WebsocketBroadcast(WebsocketMessage) } -#[derive(Clone, Debug)] +#[derive(Clone)] pub enum WebsocketMessage { NewOwner(Arc) }