--- /dev/null
+//! 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<DBError> for DBAsyncError {
+ fn from(error: DBError) -> Self {
+ DBAsyncError::DBError(error)
+ }
+}
+
+impl From<BlockingError> for DBAsyncError {
+ fn from(error: BlockingError) -> Self {
+ DBAsyncError::ActixError(error)
+ }
+}
+
+impl DBAsyncError {
+ fn from_dyn_error(error: Box<dyn std::error::Error>) -> Self {
+ DBAsyncError::Other(error.to_string())
+ }
+}
+
+fn combine_errors<T>(error: std::result::Result<std::result::Result<T, DBAsyncError>, BlockingError>) -> Result<T> {
+ error?
+}
+
+type Result<T> = std::result::Result<T, DBAsyncError>;
+
+impl Connection {
+ pub async fn get_all_recipe_titles_async(&self) -> Result<Vec<(i32, String)>> {
+ 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<model::Recipe> {
+ 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<User> {
+ 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<SignUpResult> {
+ 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<ValidationResult> {
+ 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<SignInResult> {
+ 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<AuthenticationResult> {
+ 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)
+ }
+}
\ No newline at end of file