Skip to content

Commit

Permalink
chore: cargo fmt + clippy front
Browse files Browse the repository at this point in the history
  • Loading branch information
PetoMPP committed Oct 2, 2023
1 parent c49839b commit c5c3da8
Show file tree
Hide file tree
Showing 30 changed files with 213 additions and 189 deletions.
88 changes: 48 additions & 40 deletions front/src/api/client.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,56 @@
use super::error::Error;
use super::error::ApiError;
use crate::models::{credentials::Credentials, resource_data::ResourceData, user::User};
use reqwasm::http::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_json::Value;
use std::{collections::HashMap, fmt::Display};

#[derive(Debug, PartialEq)]
pub enum ApiError {
Endpoint(u16, Error),
pub enum RequestError {
Endpoint(u16, ApiError),
Parse(String),
Network(String),
}

impl Display for ApiError {
impl Display for RequestError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}", self))
}
}

impl std::error::Error for ApiError {}
impl std::error::Error for RequestError {}

pub enum Response<T> {
Success(T),
Error(u16, Error),
Error(u16, ApiError),
}

impl<T: DeserializeOwned> Response<T> {
async fn from_response(value: reqwasm::http::Response) -> Result<Self, ApiError> {
async fn from_response(value: reqwasm::http::Response) -> Result<Self, RequestError> {
let status_code = value.status();
let body = value
.json::<Value>()
.await
.map_err(|e| ApiError::Parse(e.to_string()))?;
.map_err(|e| RequestError::Parse(e.to_string()))?;
let status = body
.get("status")
.ok_or(ApiError::Parse("Missing status".to_string()))?
.ok_or(RequestError::Parse("Missing status".to_string()))?
.as_str()
.ok_or(ApiError::Parse("Invalid status format".to_string()))?;
.ok_or(RequestError::Parse("Invalid status format".to_string()))?;
let data = body
.get("data")
.ok_or(ApiError::Parse("Missing data".to_string()))?;
.ok_or(RequestError::Parse("Missing data".to_string()))?;
match status {
"success" => Ok(Response::Success(
serde_json::from_value(data.clone())
.map_err(|e| ApiError::Parse(format!("Invalid data format, {}", e)))?,
.map_err(|e| RequestError::Parse(format!("Invalid data format, {}", e)))?,
)),
"error" => Ok(Response::Error(
status_code,
serde_json::from_value(data.clone())
.map_err(|e| ApiError::Parse(format!("Invalid data format, {}", e)))?,
.map_err(|e| RequestError::Parse(format!("Invalid data format, {}", e)))?,
)),
_ => Err(ApiError::Parse("Invalid status".to_string())),
_ => Err(RequestError::Parse("Invalid status".to_string())),
}
}
}
Expand Down Expand Up @@ -83,38 +83,38 @@ impl Client {
path: &str,
token: Option<&str>,
body: Option<&impl Serialize>,
) -> Result<R, ApiError> {
) -> Result<R, RequestError> {
let mut request = Request::new(Self::get_api_url(path).as_str()).method(method);
if let Some(token) = token {
request = request.header("Authorization", format!("Bearer {}", token).as_str());
}
if let Some(body) = body {
request = request
.body(serde_json::to_string(body).map_err(|e| ApiError::Parse(e.to_string()))?);
.body(serde_json::to_string(body).map_err(|e| RequestError::Parse(e.to_string()))?);
}

let response = request
.send()
.await
.map_err(|e| ApiError::Network(e.to_string()))?;
.map_err(|e| RequestError::Network(e.to_string()))?;

match Response::from_response(response).await? {
Response::Success(data) => Ok(data),
Response::Error(s, e) => Err(ApiError::Endpoint(s, e)),
Response::Error(s, e) => Err(RequestError::Endpoint(s, e)),
}
}

pub async fn login(credentials: Credentials) -> Result<LoginResponse, ApiError> {
pub async fn login(credentials: Credentials) -> Result<LoginResponse, RequestError> {
Self::send_json(Method::POST, "api/v1/users/login", None, Some(&credentials)).await
}

pub async fn register(credentials: Credentials) -> Result<(), ApiError> {
pub async fn register(credentials: Credentials) -> Result<(), RequestError> {
Self::send_json::<User>(Method::POST, "api/v1/users", None, Some(&credentials))
.await
.map(|_| ())
}

pub async fn get_users(token: &str) -> Result<Vec<User>, ApiError> {
pub async fn get_users(token: &str) -> Result<Vec<User>, RequestError> {
Self::send_json(
Method::GET,
"api/v1/users/all?range=all",
Expand All @@ -125,7 +125,7 @@ impl Client {
.map(|u: Vec<Vec<User>>| u[0].clone())
}

pub async fn activate_user(token: &str, id: i32) -> Result<(), ApiError> {
pub async fn activate_user(token: &str, id: i32) -> Result<(), RequestError> {
Self::send_json::<User>(
Method::POST,
format!("api/v1/users/{}/activate", id).as_str(),
Expand All @@ -136,7 +136,7 @@ impl Client {
.map(|_| ())
}

pub async fn delete_user(token: &str, id: i32) -> Result<(), ApiError> {
pub async fn delete_user(token: &str, id: i32) -> Result<(), RequestError> {
Self::send_json::<User>(
Method::DELETE,
format!("api/v1/users/{}", id).as_str(),
Expand All @@ -147,7 +147,7 @@ impl Client {
.map(|_| ())
}

pub async fn get_resource(key: &str, lang: &str) -> Result<String, ApiError> {
pub async fn get_resource(key: &str, lang: &str) -> Result<String, RequestError> {
Self::send_json(
Method::GET,
format!("api/v1/res/{}?lang={}", key, lang).as_str(),
Expand All @@ -157,7 +157,7 @@ impl Client {
.await
}

pub async fn get_resource_keys(token: &str) -> Result<Vec<String>, ApiError> {
pub async fn get_resource_keys(token: &str) -> Result<Vec<String>, RequestError> {
Self::send_json(
Method::GET,
"api/v1/res/keys",
Expand All @@ -172,7 +172,7 @@ impl Client {
key: &str,
lang: &str,
value: &str,
) -> Result<(), ApiError> {
) -> Result<(), RequestError> {
let resource = ResourceData::new_from_lang(key, lang, value)?;
Self::send_json(
Method::POST,
Expand All @@ -184,32 +184,40 @@ impl Client {
.map(|_: ResourceData| ())
}

pub async fn get_locale(lang: &str) -> Result<HashMap<String, String>, ApiError> {
pub async fn get_locale(lang: &str) -> Result<HashMap<String, String>, RequestError> {
let resp = Request::new(format!("/locales/{}.yml", lang).as_str())
.method(Method::GET)
.send()
.await
.map_err(|e| ApiError::Network(e.to_string()))?;
.map_err(|e| RequestError::Network(e.to_string()))?;
let body = resp
.binary()
.await
.map_err(|e| ApiError::Network(e.to_string()))?;
.map_err(|e| RequestError::Network(e.to_string()))?;

serde_yaml::from_slice::<HashMap<String, String>>(&body)
.map_err(|e| ApiError::Parse(e.to_string()))
.map_err(|e| RequestError::Parse(e.to_string()))
}

pub async fn upload_img(token: &str, img: web_sys::File, folder: &str) -> Result<String, ApiError> {
let resp = Request::new(Self::get_api_url(format!("api/v1/img/?folder={}", folder).as_str()).as_str())
.method(Method::PUT)
.header("Authorization", format!("Bearer {}", token).as_str())
.body(img)
.send()
.await
.map_err(|e| ApiError::Network(e.to_string()))?;
pub async fn upload_img(
token: &str,
img: web_sys::File,
folder: &str,
) -> Result<String, RequestError> {
let resp = Request::new(
Self::get_api_url(format!("api/v1/img/?folder={}", folder).as_str()).as_str(),
)
.method(Method::PUT)
.header("Authorization", format!("Bearer {}", token).as_str())
.body(img)
.send()
.await
.map_err(|e| RequestError::Network(e.to_string()))?;
match Response::<String>::from_response(resp).await? {
Response::Success(filename) => Ok(format!("{}{}/{}", *AZURE_STORAGE_URL, folder, filename)),
Response::Error(s, e) => Err(ApiError::Endpoint(s, e)),
Response::Success(filename) => {
Ok(format!("{}{}/{}", *AZURE_STORAGE_URL, folder, filename))
}
Response::Error(s, e) => Err(RequestError::Endpoint(s, e)),
}
}
}
Loading

0 comments on commit c5c3da8

Please sign in to comment.