summaryrefslogtreecommitdiff
path: root/dichroism/src/handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'dichroism/src/handlers.rs')
-rw-r--r--dichroism/src/handlers.rs101
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()))
}