diff options
author | Akshay <[email protected]> | 2020-12-24 13:57:42 +0000 |
---|---|---|
committer | Akshay <[email protected]> | 2020-12-24 13:57:42 +0000 |
commit | b00a1e55ed5fa01cb881c387c8e112249070d8ae (patch) | |
tree | 958e67e4a4368398516a5fd70259891c64070e70 /backend | |
parent | e3c0393c2b28a44c9b2069067e0fb15a9820a3ee (diff) |
add average rating to product listing
Diffstat (limited to 'backend')
-rw-r--r-- | backend/src/handlers/product.rs | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/backend/src/handlers/product.rs b/backend/src/handlers/product.rs index 41a47a0..0113bc8 100644 --- a/backend/src/handlers/product.rs +++ b/backend/src/handlers/product.rs | |||
@@ -74,16 +74,53 @@ pub async fn update_product( | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | #[derive(Serialize, Debug)] | ||
78 | struct CatalogProduct { | ||
79 | pub id: i32, | ||
80 | pub name: String, | ||
81 | pub kind: Option<String>, | ||
82 | pub price: f32, | ||
83 | pub description: Option<String>, | ||
84 | pub average_rating: Option<f64>, | ||
85 | } | ||
86 | |||
77 | pub async fn get_all_products(pool: web::Data<TPool>) -> impl Responder { | 87 | pub async fn get_all_products(pool: web::Data<TPool>) -> impl Responder { |
78 | let conn = pool.get().unwrap(); | 88 | let conn = pool.get().unwrap(); |
79 | info!("Generating and returning catalog ..."); | 89 | info!("Generating and returning catalog ..."); |
80 | match product.load::<Product>(&conn) { | 90 | let product_entries = product |
81 | Ok(products) => return HttpResponse::Ok().json(&products), | 91 | .load::<Product>(&conn) |
82 | Err(_) => { | 92 | .expect("Couldn't connect to DB"); |
83 | return HttpResponse::InternalServerError() | 93 | let with_rating_avg = product_entries |
84 | .body("Unable to fetch product catalog") | 94 | .into_iter() |
85 | } | 95 | .map(move |p| { |
86 | } | 96 | let rating_list = rating::rating |
97 | .filter(rating::product_id.eq(p.id)) | ||
98 | .load::<Rating>(&conn) | ||
99 | .expect("Coundn't connect to DB") | ||
100 | .into_iter() | ||
101 | .map(|r| r.stars) | ||
102 | .collect::<Vec<_>>(); | ||
103 | let (rating_sum, total) = | ||
104 | rating_list.into_iter().fold((0, 0), |(s, t), x| match x { | ||
105 | Some(v) => (s + v, t + 1), | ||
106 | None => (s, t), | ||
107 | }); | ||
108 | let average_rating = if total != 0 { | ||
109 | Some(rating_sum as f64 / total as f64) | ||
110 | } else { | ||
111 | None | ||
112 | }; | ||
113 | CatalogProduct { | ||
114 | average_rating, | ||
115 | name: p.name, | ||
116 | kind: p.kind, | ||
117 | price: p.price, | ||
118 | description: p.description, | ||
119 | id: p.id, | ||
120 | } | ||
121 | }) | ||
122 | .collect::<Vec<_>>(); | ||
123 | return HttpResponse::Ok().json(&with_rating_avg); | ||
87 | } | 124 | } |
88 | 125 | ||
89 | #[derive(Serialize, Deserialize, Debug)] | 126 | #[derive(Serialize, Deserialize, Debug)] |