smbcloud_network/
network.rs1use {
2 log::{debug, error},
3 reqwest::{RequestBuilder, Response, StatusCode},
4 serde::de::DeserializeOwned,
5 smbcloud_model::{
6 account::SmbAuthorization,
7 error_codes::{ErrorCode, ErrorResponse},
8 login::AccountStatus,
9 },
10};
11
12#[cfg(debug_assertions)]
14const LOG_RESPONSE_BODY: bool = false; #[cfg(not(debug_assertions))]
16const LOG_RESPONSE_BODY: bool = false;
17
18pub async fn check_internet_connection() -> bool {
23 debug!("Checking internet connection");
24 let client = reqwest::Client::builder()
25 .build();
27
28 if let Err(e) = client {
29 error!("Failed to create client for connectivity check: {:?}", e);
30 return false;
31 }
32
33 if let Ok(client) = client {
34 match client.get("https://dns.google").send().await {
35 Ok(response) => {
36 debug!(
37 "Internet connection check successful: {}",
38 response.status()
39 );
40 response.status().is_success()
41 }
42 Err(e) => {
43 error!("Internet connection check failed: {:?}", e);
44 false
45 }
46 }
47 } else {
48 false
49 }
50}
51
52pub async fn parse_error_response<T: DeserializeOwned>(
53 response: Response,
54) -> Result<T, ErrorResponse> {
55 let response_body = match response.text().await {
56 Ok(body) => body,
57 Err(e) => {
58 error!("Failed to get response body: {:?}", e);
59 return Err(ErrorResponse::Error {
60 error_code: ErrorCode::NetworkError,
61 message: ErrorCode::NetworkError.message(None).to_string(),
62 });
63 }
64 };
65
66 if LOG_RESPONSE_BODY {
67 println!();
68 println!("Parse Error >>>>");
69 println!("{:?}", serde_json::to_string_pretty(&response_body));
70 println!("Parse Error >>>>");
71 println!();
72 }
73
74 let e = match serde_json::from_str::<ErrorResponse>(&response_body) {
75 Ok(json) => json,
76 Err(e) => {
77 error!("Failed to parse error response: {:?}", e);
78 return Err(ErrorResponse::Error {
79 error_code: ErrorCode::ParseError,
80 message: ErrorCode::ParseError.message(None).to_string(),
81 });
82 }
83 };
84 error!("Error response: {:?}", e);
85 Err(e)
86}
87
88pub async fn request_login(builder: RequestBuilder) -> Result<AccountStatus, ErrorResponse> {
89 let response = builder.send().await;
90 let response = match response {
91 Ok(response) => response,
92 Err(e) => {
93 error!("Failed to get response: {:?}", e);
94 return Err(ErrorResponse::Error {
95 error_code: ErrorCode::NetworkError,
96 message: ErrorCode::NetworkError.message(None).to_string(),
97 });
98 }
99 };
100
101 let response = match response.status() {
102 reqwest::StatusCode::OK
103 | reqwest::StatusCode::NOT_FOUND
104 | reqwest::StatusCode::UNPROCESSABLE_ENTITY => response,
105 status => {
106 error!(
107 "Response are neither OK, NOT_FOUND, or UNPROCESSABLE_ENTITY: {:?}",
108 status
109 );
110 return parse_error_response(response).await;
111 }
112 };
113
114 if LOG_RESPONSE_BODY {
115 println!();
116 println!("Parse >>>>");
117 println!("{:?}", &response.status());
118 println!("Parse >>>>");
119 println!();
120 }
121
122 match (response.status(), response.headers().get("Authorization")) {
123 (StatusCode::OK, Some(token)) => {
124 let access_token = match token.to_str() {
126 Ok(token) => token.to_string(),
127 Err(_) => {
128 return Err(ErrorResponse::Error {
129 error_code: ErrorCode::NetworkError,
130 message: ErrorCode::NetworkError.message(None).to_string(),
131 });
132 }
133 };
134 Ok(AccountStatus::Ready { access_token })
135 }
136 (StatusCode::NOT_FOUND, _) => {
137 Ok(AccountStatus::NotFound)
139 }
140 (StatusCode::UNPROCESSABLE_ENTITY, _) => {
141 let result: SmbAuthorization = match response.json().await {
143 Ok(res) => res,
144 Err(_) => {
145 return Err(ErrorResponse::Error {
146 error_code: ErrorCode::NetworkError,
147 message: ErrorCode::NetworkError.message(None).to_string(),
148 });
149 }
150 };
151 let error_code = match result.error_code {
153 Some(code) => code,
154 None => {
155 return Err(ErrorResponse::Error {
156 error_code: ErrorCode::NetworkError,
157 message: ErrorCode::NetworkError.message(None).to_string(),
158 });
159 }
160 };
161 Ok(AccountStatus::Incomplete { status: error_code })
162 }
163 _ => Err(ErrorResponse::Error {
164 error_code: ErrorCode::NetworkError,
165 message: ErrorCode::NetworkError.message(None).to_string(),
166 }),
167 }
168}
169
170pub async fn request<R: DeserializeOwned>(builder: RequestBuilder) -> Result<R, ErrorResponse> {
171 if !check_internet_connection().await {
173 error!("No internet connection available");
174 return Err(ErrorResponse::Error {
175 error_code: ErrorCode::NetworkError,
176 message: "No internet connection. Please check your network settings and try again."
177 .to_string(),
178 });
179 }
180
181 let response = builder.send().await;
182 let response = match response {
183 Ok(response) => response,
184 Err(e) => {
185 error!("Failed to get response: {:?}", e);
186 return Err(ErrorResponse::Error {
187 error_code: ErrorCode::NetworkError,
188 message: ErrorCode::NetworkError.message(None).to_string(),
189 });
190 }
191 };
192 let response = match response.status() {
193 reqwest::StatusCode::OK | reqwest::StatusCode::CREATED => response,
194 status => {
195 error!("Failed to get response: {:?}", status);
196 return parse_error_response(response).await;
197 }
198 };
199
200 let response_body = match response.text().await {
201 Ok(body) => body,
202 Err(e) => {
203 error!("Failed to get response body: {:?}", e);
204 return Err(ErrorResponse::Error {
205 error_code: ErrorCode::NetworkError,
206 message: ErrorCode::NetworkError.message(None).to_string(),
207 });
208 }
209 };
210
211 if LOG_RESPONSE_BODY {
212 println!();
213 println!("Parse >>>>");
214 println!("{:?}", serde_json::to_string_pretty(&response_body));
215 println!("Parse >>>>");
216 println!();
217 }
218
219 let response = match serde_json::from_str::<R>(&response_body) {
220 Ok(response) => response,
221 Err(e) => {
222 error!("Failed to parse response: {:?}", e);
223 return Err(ErrorResponse::Error {
224 error_code: ErrorCode::ParseError,
225 message: e.to_string(),
226 });
227 }
228 };
229
230 Ok(response)
231}