use actix_web::{web, HttpResponse}; use crate::{ actions, models::{self, ApiResponse, Pagination, UserId, UserSearchRequest}, }; use crate::{errors::DomainError, AppData}; use actix_web::error::ResponseError; /// Finds user by UID. #[tracing::instrument( level = "debug", skip(app_data), fields( user_id = %user_id.0 ) )] pub async fn get_user( app_data: web::Data, user_id: web::Path, ) -> Result { let u_id = user_id.into_inner(); let u_id2 = u_id.clone(); let _ = tracing::info!("Getting user with id {}", u_id); // use web::block to offload blocking Diesel code without blocking server thread let res = web::block(move || { let pool = &app_data.pool; let conn = pool.get()?; actions::find_user_by_uid(&u_id2, &conn) }) .await .map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?; let _ = tracing::trace!("{:?}", res); if let Some(user) = res { Ok(HttpResponse::Ok().json(ApiResponse::successful(user))) } else { let err = DomainError::new_entity_does_not_exist_error(format!( "No user found with uid: {}", u_id )); Err(err) } } // #[get("/get/users/{user_id}")] // pub async fn get_user2( // user_service: web::Data, // user_id: web::Path, // ) -> Result { // let u_id = user_id.into_inner(); // let user = user_service.find_user_by_uid(u_id)?; // if let Some(user) = user { // Ok(HttpResponse::Ok().json(user)) // } else { // let err = DomainError::new_entity_does_not_exist_error(format!( // "No user found with uid: {}", // u_id // )); // Err(err) // } // } ///List all users #[tracing::instrument(level = "debug", skip(app_data))] pub async fn get_all_users( app_data: web::Data, ) -> Result { // use web::block to offload blocking Diesel code without blocking server thread let users = web::block(move || { let pool = &app_data.pool; let conn = pool.get()?; actions::get_all(&conn) }) .await .map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?; let _ = tracing::trace!("{:?}", users); if !users.is_empty() { Ok(HttpResponse::Ok().json(ApiResponse::successful(users))) } else { Err(DomainError::new_entity_does_not_exist_error( "No users available".to_owned(), )) } } #[tracing::instrument(level = "debug", skip(app_data))] pub async fn get_users_paginated( app_data: web::Data, pagination: web::Query, ) -> Result { let _ = tracing::info!("Paginated users request"); let users = web::block(move || { let pool = &app_data.pool; let conn = pool.get()?; let p: Pagination = pagination.into_inner(); actions::get_users_paginated(&p, &conn) }) .await .map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?; let _ = tracing::trace!("{:?}", users); Ok(HttpResponse::Ok().json(ApiResponse::successful(users))) } #[tracing::instrument(level = "debug", skip(app_data))] pub async fn search_users( app_data: web::Data, query: web::Query, pagination: web::Query, ) -> Result { let _ = tracing::info!("Search users request"); let users = web::block(move || { let pool = &app_data.pool; let conn = pool.get()?; let p: Pagination = pagination.into_inner(); actions::search_users(query.q.as_str(), &p, &conn) }) .await .map_err(|err| DomainError::new_thread_pool_error(err.to_string()))?; let _ = tracing::trace!("{:?}", users); Ok(HttpResponse::Ok().json(ApiResponse::successful(users))) } /// Inserts new user with name defined in form. #[tracing::instrument(level = "debug", skip(app_data))] pub async fn add_user( app_data: web::Data, form: web::Json, ) -> Result { // use web::block to offload blocking Diesel code without blocking server thread web::block(move || { let pool = &app_data.pool; let conn = pool.get()?; actions::insert_new_user(form.0, &conn, Some(app_data.config.hash_cost)) }) .await .map(|user| { let _ = tracing::trace!("{:?}", user); HttpResponse::Created().json(ApiResponse::successful(user)) }) }