rustfmt
[recipes.git] / backend / src / data / asynchronous.rs
1 //! Functions to be called from actix code. They are asynchonrous and won't block worker thread caller.
2
3 use std::fmt;
4
5 use actix_web::{error::BlockingError, web};
6 use chrono::{prelude::*, Duration};
7
8 use super::db::*;
9 use crate::model;
10 use crate::user::User;
11
12 #[derive(Debug)]
13 pub enum DBAsyncError {
14 DBError(DBError),
15 ActixError(BlockingError),
16 Other(String),
17 }
18
19 impl fmt::Display for DBAsyncError {
20 fn fmt(&self, f: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
21 write!(f, "{:?}", self)
22 }
23 }
24
25 impl std::error::Error for DBAsyncError {}
26
27 impl From<DBError> for DBAsyncError {
28 fn from(error: DBError) -> Self {
29 DBAsyncError::DBError(error)
30 }
31 }
32
33 impl From<BlockingError> for DBAsyncError {
34 fn from(error: BlockingError) -> Self {
35 DBAsyncError::ActixError(error)
36 }
37 }
38
39 impl DBAsyncError {
40 fn from_dyn_error(error: Box<dyn std::error::Error>) -> Self {
41 DBAsyncError::Other(error.to_string())
42 }
43 }
44
45 fn combine_errors<T>(
46 error: std::result::Result<std::result::Result<T, DBAsyncError>, BlockingError>,
47 ) -> Result<T> {
48 error?
49 }
50
51 type Result<T> = std::result::Result<T, DBAsyncError>;
52
53 impl Connection {
54 pub async fn get_all_recipe_titles_async(&self) -> Result<Vec<(i64, String)>> {
55 let self_copy = self.clone();
56 web::block(move || self_copy.get_all_recipe_titles().unwrap_or_default())
57 .await
58 .map_err(DBAsyncError::from)
59 }
60
61 pub async fn get_recipe_async(&self, id: i64) -> Result<model::Recipe> {
62 let self_copy = self.clone();
63 combine_errors(
64 web::block(move || self_copy.get_recipe(id).map_err(DBAsyncError::from)).await,
65 )
66 }
67
68 pub async fn load_user_async(&self, user_id: i64) -> Result<User> {
69 let self_copy = self.clone();
70 combine_errors(
71 web::block(move || self_copy.load_user(user_id).map_err(DBAsyncError::from)).await,
72 )
73 }
74
75 pub async fn sign_up_async(&self, email: &str, password: &str) -> Result<SignUpResult> {
76 let self_copy = self.clone();
77 let email_copy = email.to_string();
78 let password_copy = password.to_string();
79 combine_errors(
80 web::block(move || {
81 self_copy
82 .sign_up(&email_copy, &password_copy)
83 .map_err(DBAsyncError::from)
84 })
85 .await,
86 )
87 }
88
89 pub async fn validation_async(
90 &self,
91 token: &str,
92 validation_time: Duration,
93 ip: &str,
94 user_agent: &str,
95 ) -> Result<ValidationResult> {
96 let self_copy = self.clone();
97 let token_copy = token.to_string();
98 let ip_copy = ip.to_string();
99 let user_agent_copy = user_agent.to_string();
100 combine_errors(
101 web::block(move || {
102 self_copy
103 .validation(&token_copy, validation_time, &ip_copy, &user_agent_copy)
104 .map_err(DBAsyncError::from)
105 })
106 .await,
107 )
108 }
109
110 pub async fn sign_in_async(
111 &self,
112 email: &str,
113 password: &str,
114 ip: &str,
115 user_agent: &str,
116 ) -> Result<SignInResult> {
117 let self_copy = self.clone();
118 let email_copy = email.to_string();
119 let password_copy = password.to_string();
120 let ip_copy = ip.to_string();
121 let user_agent_copy = user_agent.to_string();
122 combine_errors(
123 web::block(move || {
124 self_copy
125 .sign_in(&email_copy, &password_copy, &ip_copy, &user_agent_copy)
126 .map_err(DBAsyncError::from)
127 })
128 .await,
129 )
130 }
131
132 pub async fn authentication_async(
133 &self,
134 token: &str,
135 ip: &str,
136 user_agent: &str,
137 ) -> Result<AuthenticationResult> {
138 let self_copy = self.clone();
139 let token_copy = token.to_string();
140 let ip_copy = ip.to_string();
141 let user_agent_copy = user_agent.to_string();
142 combine_errors(
143 web::block(move || {
144 self_copy
145 .authentication(&token_copy, &ip_copy, &user_agent_copy)
146 .map_err(DBAsyncError::from)
147 })
148 .await,
149 )
150 }
151
152 pub async fn sign_out_async(&self, token: &str) -> Result<()> {
153 let self_copy = self.clone();
154 let token_copy = token.to_string();
155 combine_errors(
156 web::block(move || self_copy.sign_out(&token_copy).map_err(DBAsyncError::from)).await,
157 )
158 }
159
160 pub async fn create_recipe_async(&self, user_id: i64) -> Result<i64> {
161 let self_copy = self.clone();
162 combine_errors(
163 web::block(move || self_copy.create_recipe(user_id).map_err(DBAsyncError::from)).await,
164 )
165 }
166
167 pub async fn set_recipe_title_async(&self, recipe_id: i64, title: &str) -> Result<()> {
168 let self_copy = self.clone();
169 let title_copy = title.to_string();
170 combine_errors(
171 web::block(move || {
172 self_copy
173 .set_recipe_title(recipe_id, &title_copy)
174 .map_err(DBAsyncError::from)
175 })
176 .await,
177 )
178 }
179
180 pub async fn set_recipe_description_async(
181 &self,
182 recipe_id: i64,
183 description: &str,
184 ) -> Result<()> {
185 let self_copy = self.clone();
186 let description_copy = description.to_string();
187 combine_errors(
188 web::block(move || {
189 self_copy
190 .set_recipe_description(recipe_id, &description_copy)
191 .map_err(DBAsyncError::from)
192 })
193 .await,
194 )
195 }
196 }