1use std::convert::Infallible;
2use std::collections::HashMap;
3use warp::http::StatusCode;
4use log::*;
5
6use crate::db::{self, DbConn};
7use crate::models::comment::{self, Comment};
8use crate::models::reply::{self, Reply};
9use crate::models::upvote::{self, Upvote};
10use crate::models::downvote::{self, Downvote};
11use crate::models::status::Status;
12
13pub async fn list_comments(
14 db_conn: DbConn,
15) -> Result<impl warp::Reply, Infallible> {
16 let mut results: Vec<Comment> = Vec::new();
17 match db::get_all_comments(db_conn).await {
18 Ok(data) => results = data,
19 Err(message) => error!("{:?} occurred in handlers::list_comments()", message),
20 };
21 let filtered: Vec<Comment> = results.into_iter().filter(|each|
22 each.status == Status::Pending
23 || each.status == Status::Approved
24 || each.status == Status:: Disabled
25 ).collect();
26 Ok( warp::reply::json( &filtered ) )
27}
28
29pub async fn more_comments(
30 count: usize,
31 db_conn: DbConn,
32) -> Result<impl warp::Reply, Infallible> {
33 let mut results: Vec<Comment> = Vec::new();
34 match db::get_more_comments(count, db_conn).await {
35 Ok(data) => results = data,
36 Err(message) => error!("{:?} occurred in handlers::more_comments()", message),
37 };
38 let filtered: Vec<Comment> = results.into_iter().filter(|each|
39 each.status == Status::Pending
40 || each.status == Status::Approved
41 || each.status == Status:: Disabled
42 ).collect();
43 Ok( warp::reply::json( &filtered ) )
44}
45
46pub async fn add_comment(
47 new_comment: Comment,
48 db_conn: DbConn,
49) -> Result<impl warp::Reply, Infallible> {
50 debug!("add comment: {:?}", new_comment);
51 let mut comment_clone = new_comment.clone();
52 comment::assign_uid(&mut comment_clone);
53 comment::assign_created_date(&mut comment_clone);
54 let result = db::add_comment(&comment_clone, db_conn).await;
55 let code = process_db_result( result );
56 Ok(code)
57}
58
59fn process_db_result(result: Result<usize, rusqlite::Error>) -> warp::http::StatusCode {
60 match result {
61 Ok(count) => {
62 match count {
63 1 => StatusCode::NO_CONTENT,
64 _ => StatusCode::NOT_FOUND
65 }
66 },
67 Err(error) => {
68 error!("Error: {} occurred in process_db_result...........", &error);
69 StatusCode::NOT_FOUND
70 }
71 }
72}
73
74pub async fn update_comment(
75 uid: String,
76 mut comment: Comment,
77 db_conn: DbConn,
78) -> Result<impl warp::Reply, Infallible> {
79 debug!("update comment: uid = {}, comment = {:?}", uid, comment);
80 comment.unique_id = uid;
81 comment.remarks = String::from("several fields are updated");
82 comment::assign_updated_date(&mut comment);
83 let result = db::update_comment(&comment, db_conn).await;
84 let code = process_db_result( result );
85 Ok(code)
86}
87
88pub async fn update_comment_status(
89 stat: String,
90 uid: String,
91 db_conn: DbConn,
92) -> Result<impl warp::Reply, Infallible> {
93 debug!("update comment status: stat = {}, uid = {}", &stat, uid);
94 let now: String = comment::timestamp_now();
95 let status: Status = Status::from_string(stat);
96 let result = db::update_comment_status(status, uid, now, db_conn).await;
97 let code = process_db_result( result );
98 Ok(code)
99}
100
101pub async fn update_comment_message(
102 uid: String,
103 map: HashMap<String, String>,
104 db_conn: DbConn,
105) -> Result<impl warp::Reply, Infallible> {
106 debug!("update comment message: uid = {}, new-message: {:?}+++++++++++++++++++++++++++", &uid, &map);
107 let now: String = comment::timestamp_now();
108 let msg = map.get("message").unwrap();
109 let result = db::update_comment_message(msg.to_string(), uid, now, db_conn).await;
110 let code = process_db_result(result);
111 Ok(code)
112}
113
114pub async fn delete_comment(
115 uid: String,
116 db_conn: DbConn
117) -> Result<impl warp::Reply, Infallible> {
118 debug!("delete comment: uid = {}", uid);
119 let now: String = comment::timestamp_now();
120 let result = db::delete_comment(&uid, now, db_conn).await;
121 let code = process_db_result( result );
122 Ok(code)
123}
124
125pub async fn get_comment(
126 uid: String,
127 db_conn: DbConn
128) -> Result<impl warp::Reply, Infallible> {
129 debug!("get comment: uid = {}", uid);
131 match db::get_comment(&uid, db_conn).await {
132 Ok(data) => Ok( warp::reply::json( &data ) ),
133 Err(message) => {
134 error!("{} occurred in handlers::get_comment()", message);
135 Ok( warp::reply::json( &"No Data Found" ) )
136 },
137 }
138
139}
140
141pub async fn comments_total(
142 db_conn: DbConn,
143) -> Result<impl warp::Reply, Infallible> {
144 let total: u32 = match db::get_comments_total(db_conn).await {
145 Ok(data) => data,
146 Err(message) => {
147 error!("{:?} occurred in handlers::comments_total()", message);
148 0u32
149 }
150 };
151 Ok( warp::reply::json( &total ) )
152}
153
154pub async fn add_reply(
156 new_reply: Reply,
157 db_conn: DbConn,
158) -> Result<impl warp::Reply, Infallible> {
159 debug!("add reply: {:?}", new_reply);
160 let mut reply_clone = new_reply.clone();
161 reply::assign_uid(&mut reply_clone);
162 reply::assign_created_date(&mut reply_clone);
163 let result = db::add_reply(&reply_clone, db_conn).await;
164 let code = process_db_result( result );
165 Ok(code)
166}
167
168pub async fn list_replies(
169 comment_id: String,
170 db_conn: DbConn,
171) -> Result<impl warp::Reply, Infallible> {
172 let mut results: Vec<Reply> = Vec::new();
173 match db::get_replies(comment_id, &Status::Pending.to_string(), db_conn).await {
174 Ok(data) => results = data,
175 Err(message) => error!("{:?} occurred in handlers::list_replies()", message),
176 };
177 Ok( warp::reply::json( &results ) )
178}
179
180pub async fn update_reply(
181 uid: String,
182 mut reply: Reply,
183 db_conn: DbConn,
184) -> Result<impl warp::Reply, Infallible> {
185 debug!("update reply: uid = {}, reply = {:?}", uid, reply);
186 reply.unique_id = uid;
187 reply.status = Status::Approved;
188 reply.remarks = String::from("updated");
189 reply::assign_updated_date(&mut reply);
190 let result = db::update_reply(&reply, db_conn).await;
191 let code = process_db_result( result );
192 Ok(code)
193}
194
195pub async fn update_reply_message(
196 uid: String,
197 map: HashMap<String, String>,
198 db_conn: DbConn,
199) -> Result<impl warp::Reply, Infallible> {
200 debug!("update reply message: uid = {}, new-message: {:?}+++++++++++++++++++++++++++", &uid, &map);
201 let now: String = comment::timestamp_now();
202 let msg = map.get("message").unwrap();
203 let result = db::update_reply_message(msg.to_string(), uid, now, db_conn).await;
204 let code = process_db_result( result );
205 Ok(code)
206}
207
208pub async fn delete_reply(
209 uid: String,
210 db_conn: DbConn
211) -> Result<impl warp::Reply, Infallible> {
212 debug!("delete reply: uid = {}", uid);
213 let now: String = comment::timestamp_now();
214 let result = db::delete_reply(&uid, now, db_conn).await;
215 let code = process_db_result( result );
216 Ok(code)
217}
218
219pub async fn get_reply(
220 uid: String,
221 db_conn: DbConn
222) -> Result<impl warp::Reply, Infallible> {
223 debug!("get reply: uid = {}", uid);
225 match db::get_reply(&uid, db_conn).await {
226 Ok(data) => Ok( warp::reply::json( &data ) ),
227 Err(message) => {
228 error!("{} occurred in handlers::get_reply()", message);
229 Ok( warp::reply::json( &"No Data Found" ) )
230 },
231 }
232}
233
234pub async fn add_upvote(
240 new_upvote: Upvote,
241 db_conn: DbConn,
242) -> Result<impl warp::Reply, Infallible> {
243 debug!("add upvote: {:?}", new_upvote);
244 let mut upvote_clone = new_upvote.clone();
245 upvote::assign_created_date(&mut upvote_clone);
246 match db::add_upvote(&upvote_clone, db_conn.clone()).await {
247 Ok(count) => {
248 match count {
249 1 => Ok(StatusCode::CREATED),
250 _ => Ok(StatusCode::BAD_REQUEST)
251 }
252 },
253 Err(rusqlite::Error::SqliteFailure(error, _options)) => { let mut code = StatusCode::BAD_REQUEST;
255 let is_constraint_error = error.code == rusqlite::ErrorCode::ConstraintViolation
256 && error.extended_code == "2067".parse::<i32>().unwrap();
257 if is_constraint_error {
258 code = revoke_upvote(&upvote_clone, db_conn.clone()).await;
259 }
260 Ok(code)
261 },
262 Err(error) => {
263 error!("{:?} occurred in handlers::add_upvote()", &error);
264 Ok(StatusCode::BAD_REQUEST)
265 },
266 }
267}
268
269async fn revoke_upvote(upvote: &Upvote, db_conn: DbConn) -> warp::http::StatusCode {
270 let now: String = upvote::timestamp_now();
271 let result = db::delete_upvote(&upvote.comment_id, &upvote.user_id, now, db_conn).await;
272 process_db_result(result)
273}
274
275pub async fn delete_upvote(
276 comment_id: String,
277 user_id: String,
278 db_conn: DbConn
279) -> Result<impl warp::Reply, Infallible> {
280 debug!("delete upvote: comment_id = {}, user_id = {}", &comment_id, &user_id);
281 let now: String = upvote::timestamp_now();
282 let result = db::delete_upvote(&comment_id, &user_id, now, db_conn).await;
283 let code = process_db_result(result);
284 Ok(code)
285}
286
287pub async fn upvotes_total(
288 comment_id: String,
289 db_conn: DbConn,
290) -> Result<impl warp::Reply, Infallible> {
291 let total: u32 = match db::get_upvotes_total(&comment_id, db_conn).await {
292 Ok(data) => data,
293 Err(message) => {
294 error!("{:?} occurred in handlers::upvotes_total()", message);
295 0u32
296 }
297 };
298 Ok( warp::reply::json( &total ) )
299}
300
301pub async fn add_downvote(
308 new_downvote: Downvote,
309 db_conn: DbConn,
310) -> Result<impl warp::Reply, Infallible> {
311 debug!("add downvote: {:?}", new_downvote);
312 let mut downvote_clone = new_downvote.clone();
313 downvote::assign_created_date(&mut downvote_clone);
314 match db::add_downvote(&downvote_clone, db_conn.clone()).await {
315 Ok(count) => {
316 match count {
317 1 => Ok(StatusCode::CREATED),
318 _ => Ok(StatusCode::BAD_REQUEST)
319 }
320 },
321 Err(rusqlite::Error::SqliteFailure(error, _options)) => { let mut code = StatusCode::BAD_REQUEST;
323 let is_constraint_error = error.code == rusqlite::ErrorCode::ConstraintViolation
324 && error.extended_code == "2067".parse::<i32>().unwrap();
325 if is_constraint_error {
326 code = revoke_downvote(&downvote_clone, db_conn.clone()).await;
327 }
328 Ok(code)
329 },
330 Err(error) => {
331 error!("{:?} occurred in handlers::add_downvote()", &error);
332 Ok(StatusCode::BAD_REQUEST)
333 },
334 }
335}
336
337async fn revoke_downvote(downvote: &Downvote, db_conn: DbConn) -> warp::http::StatusCode {
338 let now: String = downvote::timestamp_now();
339 let result = db::delete_downvote(&downvote.comment_id, &downvote.user_id, now, db_conn).await;
340 process_db_result(result)
341}
342
343pub async fn delete_downvote(
344 comment_id: String,
345 user_id: String,
346 db_conn: DbConn
347) -> Result<impl warp::Reply, Infallible> {
348 debug!("delete downvote: comment_id = {}, user_id = {}", &comment_id, &user_id);
349 let now: String = downvote::timestamp_now();
350 let result = db::delete_downvote(&comment_id, &user_id, now, db_conn).await;
351 let code = process_db_result(result);
352 Ok(code)
353}
354
355pub async fn downvotes_total(
356 comment_id: String,
357 db_conn: DbConn,
358) -> Result<impl warp::Reply, Infallible> {
359 let total: u32 = match db::get_downvotes_total(&comment_id, db_conn).await {
360 Ok(data) => data,
361 Err(message) => {
362 error!("{:?} occurred in handlers::downvotes_total()", message);
363 0u32
364 }
365 };
366 Ok( warp::reply::json( &total ) )
367}
368