diff options
Diffstat (limited to 'dichroism/src/handlers.rs')
-rw-r--r-- | dichroism/src/handlers.rs | 101 |
1 files changed, 83 insertions, 18 deletions
diff --git a/dichroism/src/handlers.rs b/dichroism/src/handlers.rs index b4b117c..7c1d302 100644 --- a/dichroism/src/handlers.rs +++ b/dichroism/src/handlers.rs @@ -1,8 +1,15 @@ use crate::dtos::*; +use crate::image_service; +use crate::models::Product; use crate::repo; use crate::types::DbPool; use actix_web::{get, patch, post, web, Error, HttpResponse, Responder}; +fn to_internal_error(e: impl std::error::Error) -> HttpResponse { + eprintln!("{}", e); + HttpResponse::InternalServerError().body(e.to_string()) +} + #[get("/")] async fn hello() -> impl Responder { HttpResponse::Ok().body("Hey, this is an API!") @@ -10,34 +17,92 @@ async fn hello() -> impl Responder { #[get("/products")] async fn get_products(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> { - let conn = pool.get().expect("Couldn't get DB connection from pool."); - let products: Vec<Product> = web::block(move || repo::read_products(&conn)) + let conn = pool.get().map_err(to_internal_error)?; + let products: Vec<ProductGet> = web::block(move || repo::find_all(&conn)) .await - .map_err(|e| { - eprintln!("{}", e); - HttpResponse::InternalServerError().body(e.to_string()) - })? + .map_err(to_internal_error)? .into_iter() .map(|p| p.into()) .collect(); Ok(HttpResponse::Ok().json(products)) } -#[patch("/products/{id}")] -async fn update_product( - _pool: web::Data<DbPool>, - id: web::Path<u32>, - updated_product: web::Json<ProductPatch>, +#[patch("/products")] +async fn patch_product( + pool: web::Data<DbPool>, + patch: web::Json<ProductPatch>, ) -> Result<HttpResponse, Error> { - dbg!(id, updated_product); - Ok(HttpResponse::Ok().finish()) + let patch = patch.into_inner(); + let id = patch.id; + + let conn = pool.get().map_err(to_internal_error)?; + let mut product = web::block(move || repo::find(&conn, id)) + .await + .map_err(to_internal_error)? + .ok_or_else(|| HttpResponse::NotFound().finish())?; + + if let Some(data_uri) = patch.photo_data { + // create new photo_set + let photo_set = image_service::generate_photo_set(&data_uri).map_err(|e| { + eprintln!("{}", e.to_string()); + HttpResponse::InternalServerError().body(e.to_string()) + })?; + let conn = pool.get().map_err(to_internal_error)?; + let photo_set = web::block(move || repo::store_photo_set(&conn, photo_set)) + .await + .map_err(to_internal_error)?; + product.photo_set = photo_set; + } + + // patch the rest of the product + product.name = patch.name.unwrap_or(product.name); + product.quantity = patch.quantity.unwrap_or(product.quantity); + product.cents = patch.cents.unwrap_or(product.cents); + product.description = patch.description.unwrap_or(product.description); + product.featured = patch.featured.unwrap_or(product.featured); + product.category = patch.category_path.unwrap_or(product.category); + + // store the updated product + let conn = pool.get().map_err(to_internal_error)?; + let product = web::block(move || repo::store_product(&conn, product)) + .await + .map_err(to_internal_error)?; + + Ok(HttpResponse::Ok().json(ProductGet::from(product))) } #[post("/products")] -async fn create_product( - _pool: web::Data<DbPool>, - new_product: web::Json<NewProduct>, +async fn post_product( + pool: web::Data<DbPool>, + post: web::Json<ProductPost>, ) -> Result<HttpResponse, Error> { - dbg!(new_product); - Ok(HttpResponse::Ok().finish()) + let post = post.into_inner(); + + // create new photo_set + let photo_set = image_service::generate_photo_set(&post.photo_data).map_err(|e| { + eprintln!("{}", e.to_string()); + HttpResponse::InternalServerError().body(e.to_string()) + })?; + let conn = pool.get().map_err(to_internal_error)?; + let photo_set = web::block(move || repo::store_photo_set(&conn, photo_set)) + .await + .map_err(to_internal_error)?; + + let product = Product { + id: None, + name: post.name, + quantity: post.quantity, + cents: post.cents, + description: post.description, + featured: post.featured, + category: post.category_path, + photo_set, + }; + + let conn = pool.get().map_err(to_internal_error)?; + let product = web::block(move || repo::store_product(&conn, product)) + .await + .map_err(to_internal_error)?; + + Ok(HttpResponse::Ok().json::<ProductGet>(product.into())) } |