//! Functions to be called from actix code. They are asynchonrous and won't block worker thread caller. use std::fmt; use chrono::{prelude::*, Duration}; use actix_web::{web, error::BlockingError}; use super::db::*; use crate::model; use crate::user::User; #[derive(Debug)] pub enum DBAsyncError { DBError(DBError), ActixError(BlockingError), Other(String), } impl fmt::Display for DBAsyncError { fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> { write!(f, "{:?}", self) } } impl std::error::Error for DBAsyncError { } impl From for DBAsyncError { fn from(error: DBError) -> Self { DBAsyncError::DBError(error) } } impl From for DBAsyncError { fn from(error: BlockingError) -> Self { DBAsyncError::ActixError(error) } } impl DBAsyncError { fn from_dyn_error(error: Box) -> Self { DBAsyncError::Other(error.to_string()) } } fn combine_errors(error: std::result::Result, BlockingError>) -> Result { error? } type Result = std::result::Result; impl Connection { pub async fn get_all_recipe_titles_async(&self) -> Result> { let self_copy = self.clone(); web::block(move || { self_copy.get_all_recipe_titles().unwrap_or_default() }).await.map_err(DBAsyncError::from) } pub async fn get_recipe_async(&self, id: i32) -> Result { let self_copy = self.clone(); combine_errors(web::block(move || { self_copy.get_recipe(id).map_err(DBAsyncError::from) }).await) } pub async fn load_user_async(&self, user_id: i32) -> Result { let self_copy = self.clone(); combine_errors(web::block(move || { self_copy.load_user(user_id).map_err(DBAsyncError::from) }).await) } pub async fn sign_up_async(&self, email: &str, password: &str) -> Result { let self_copy = self.clone(); let email_copy = email.to_string(); let password_copy = password.to_string(); combine_errors(web::block(move || { self_copy.sign_up(&email_copy, &password_copy).map_err(DBAsyncError::from) }).await) } pub async fn validation_async(&self, token: &str, validation_time: Duration, ip: &str, user_agent: &str) -> Result { let self_copy = self.clone(); let token_copy = token.to_string(); let ip_copy = ip.to_string(); let user_agent_copy = user_agent.to_string(); combine_errors(web::block(move || { self_copy.validation(&token_copy, validation_time, &ip_copy, &user_agent_copy).map_err(DBAsyncError::from) }).await) } pub async fn sign_in_async(&self, email: &str, password: &str, ip: &str, user_agent: &str) -> Result { let self_copy = self.clone(); let email_copy = email.to_string(); let password_copy = password.to_string(); let ip_copy = ip.to_string(); let user_agent_copy = user_agent.to_string(); combine_errors(web::block(move || { self_copy.sign_in(&email_copy, &password_copy, &ip_copy, &user_agent_copy).map_err(DBAsyncError::from) }).await) } pub async fn authentication_async(&self, token: &str, ip: &str, user_agent: &str) -> Result { let self_copy = self.clone(); let token_copy = token.to_string(); let ip_copy = ip.to_string(); let user_agent_copy = user_agent.to_string(); combine_errors(web::block(move || { self_copy.authentication(&token_copy, &ip_copy, &user_agent_copy).map_err(DBAsyncError::from) }).await) } pub async fn sign_out_async(&self, token: &str) -> Result<()> { let self_copy = self.clone(); let token_copy = token.to_string(); combine_errors(web::block(move || { self_copy.sign_out(&token_copy).map_err(DBAsyncError::from) }).await) } }