Add pre-commit config

This commit is contained in:
2023-09-24 22:49:42 +02:00
parent 2b26503cf1
commit 6d4765dc75
12 changed files with 189 additions and 271 deletions

7
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,7 @@
repos:
- repo: https://github.com/doublify/pre-commit-rust
rev: v1.0
hooks:
- id: fmt
- id: cargo-check
- id: clippy

View File

@@ -9,15 +9,13 @@ pub struct Config {
pub postgres_port: u32,
pub postgres_db: String,
pub sentry_dsn: String
pub sentry_dsn: String,
}
fn get_env(env: &'static str) -> String {
std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {} env variable", env))
}
impl Config {
pub fn load() -> Config {
Config {
@@ -29,12 +27,9 @@ impl Config {
postgres_port: get_env("POSTGRES_PORT").parse().unwrap(),
postgres_db: get_env("POSTGRES_DB"),
sentry_dsn: get_env("SENTRY_DSN")
sentry_dsn: get_env("SENTRY_DSN"),
}
}
}
pub static CONFIG: Lazy<Config> = Lazy::new(|| {
Config::load()
});
pub static CONFIG: Lazy<Config> = Lazy::new(Config::load);

View File

@@ -1,5 +1,4 @@
use crate::{prisma::PrismaClient, config::CONFIG};
use crate::{config::CONFIG, prisma::PrismaClient};
pub async fn get_prisma_client() -> PrismaClient {
let database_url: String = format!(

View File

@@ -1,14 +1,13 @@
pub mod config;
pub mod db;
pub mod prisma;
pub mod views;
pub mod db;
use sentry::{ClientOptions, types::Dsn, integrations::debug_images::DebugImagesIntegration};
use sentry::{integrations::debug_images::DebugImagesIntegration, types::Dsn, ClientOptions};
use tracing::info;
use std::{net::SocketAddr, str::FromStr};
async fn start_app() {
let app = views::get_router().await;

View File

@@ -1,7 +1,8 @@
// Code generated by Prisma Client Rust. DO NOT EDIT
pub static DATAMODEL_STR: &str =
include_str!("../prisma/schema.prisma");
#![allow(clippy::all)]
pub static DATAMODEL_STR: &str = include_str!("../prisma/schema.prisma");
static DATABASE_STR: &str = "postgresql";
pub async fn new_client() -> Result<PrismaClient, ::prisma_client_rust::NewClientError> {
PrismaClient::_builder().build().await
@@ -21,9 +22,7 @@ pub mod user_settings {
pub mod id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -92,9 +91,7 @@ pub mod user_settings {
pub mod user_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "user_id";
pub struct Set(pub i64);
impl From<Set> for SetParam {
@@ -167,9 +164,7 @@ pub mod user_settings {
pub mod last_name {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "last_name";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -234,9 +229,7 @@ pub mod user_settings {
pub mod first_name {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "first_name";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -301,9 +294,7 @@ pub mod user_settings {
pub mod username {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "username";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -368,9 +359,7 @@ pub mod user_settings {
pub mod source {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "source";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -435,9 +424,7 @@ pub mod user_settings {
pub mod user_activity {
use super::super::*;
use super::{
SetParam, WhereParam, WithParam,
};
use super::{SetParam, WhereParam, WithParam};
pub const NAME: &str = "user_activity";
pub struct Fetch(pub user_activity::UniqueArgs);
impl Fetch {
@@ -523,9 +510,7 @@ pub mod user_settings {
pub mod languages {
use super::super::*;
use super::{
SetParam, WhereParam, WithParam,
};
use super::{SetParam, WhereParam, WithParam};
pub const NAME: &str = "languages";
pub struct Fetch(pub language_to_user::ManyArgs);
impl Fetch {
@@ -1385,9 +1370,7 @@ pub mod chat_donate_notifications {
pub mod id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "id";
pub struct Set(pub i64);
impl From<Set> for SetParam {
@@ -1456,9 +1439,7 @@ pub mod chat_donate_notifications {
pub mod chat_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "chat_id";
pub struct Set(pub i64);
impl From<Set> for SetParam {
@@ -1531,9 +1512,7 @@ pub mod chat_donate_notifications {
pub mod sended {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "sended";
pub struct Set(
pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>,
@@ -2068,9 +2047,7 @@ pub mod language {
pub mod id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -2139,9 +2116,7 @@ pub mod language {
pub mod label {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "label";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -2206,9 +2181,7 @@ pub mod language {
pub mod code {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "code";
pub struct Set(pub String);
impl From<Set> for SetParam {
@@ -2269,9 +2242,7 @@ pub mod language {
pub mod users {
use super::super::*;
use super::{
SetParam, WhereParam, WithParam,
};
use super::{SetParam, WhereParam, WithParam};
pub const NAME: &str = "users";
pub struct Fetch(pub language_to_user::ManyArgs);
impl Fetch {
@@ -2891,9 +2862,7 @@ pub mod user_activity {
pub mod id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -2962,9 +2931,7 @@ pub mod user_activity {
pub mod user_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "user_id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -3033,9 +3000,7 @@ pub mod user_activity {
pub mod updated {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "updated";
pub struct Set(
pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>,
@@ -3138,9 +3103,7 @@ pub mod user_activity {
pub mod user {
use super::super::*;
use super::{
SetParam, WhereParam, WithParam,
};
use super::{SetParam, WhereParam, WithParam};
pub const NAME: &str = "user";
pub struct Fetch(pub user_settings::UniqueArgs);
impl Fetch {
@@ -3725,9 +3688,7 @@ pub mod language_to_user {
pub mod id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
pub const NAME: &str = "id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -3796,9 +3757,7 @@ pub mod language_to_user {
pub mod language_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "language_id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -3871,9 +3830,7 @@ pub mod language_to_user {
pub mod user_id {
use super::super::*;
use super::{
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
pub const NAME: &str = "user_id";
pub struct Set(pub i32);
impl From<Set> for SetParam {
@@ -3942,9 +3899,7 @@ pub mod language_to_user {
pub mod language {
use super::super::*;
use super::{
SetParam, WhereParam, WithParam,
};
use super::{SetParam, WhereParam, WithParam};
pub const NAME: &str = "language";
pub struct Fetch(pub language::UniqueArgs);
impl Fetch {
@@ -4048,9 +4003,7 @@ pub mod language_to_user {
pub mod user {
use super::super::*;
use super::{
SetParam, WhereParam, WithParam,
};
use super::{SetParam, WhereParam, WithParam};
pub const NAME: &str = "user";
pub struct Fetch(pub user_settings::UniqueArgs);
impl Fetch {

View File

@@ -1,18 +1,21 @@
use axum::{Router, response::IntoResponse, routing::{get, post}, extract::Path, Json, http::StatusCode};
use axum::{
extract::Path,
http::StatusCode,
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use chrono::Duration;
use crate::prisma::chat_donate_notifications;
use super::Database;
async fn is_need_send(
Path(chat_id): Path<i64>,
db: Database
) -> impl IntoResponse {
async fn is_need_send(Path(chat_id): Path<i64>, db: Database) -> impl IntoResponse {
const NOTIFICATION_DELTA_DAYS: i64 = 60;
let notification = db.chat_donate_notifications()
let notification = db
.chat_donate_notifications()
.find_unique(chat_donate_notifications::chat_id::equals(chat_id))
.exec()
.await
@@ -20,31 +23,24 @@ async fn is_need_send(
match notification {
Some(notification) => {
let result = notification.sended.naive_local() + Duration::days(NOTIFICATION_DELTA_DAYS) <= chrono::offset::Local::now().naive_local();
let result = notification.sended.naive_local()
+ Duration::days(NOTIFICATION_DELTA_DAYS)
<= chrono::offset::Local::now().naive_local();
Json(result).into_response()
},
}
None => Json(true).into_response(),
}
}
async fn mark_sent(
Path(chat_id): Path<i64>,
db: Database
) -> impl IntoResponse {
let _ = db.chat_donate_notifications()
async fn mark_sent(Path(chat_id): Path<i64>, db: Database) -> impl IntoResponse {
let _ = db
.chat_donate_notifications()
.upsert(
chat_donate_notifications::chat_id::equals(chat_id),
chat_donate_notifications::create(
chat_id,
chat_donate_notifications::create(chat_id, chrono::offset::Local::now().into(), vec![]),
vec![chat_donate_notifications::sended::set(
chrono::offset::Local::now().into(),
vec![]
),
vec![
chat_donate_notifications::sended::set(
chrono::offset::Local::now().into()
)
]
)],
)
.exec()
.await;
@@ -52,7 +48,6 @@ async fn mark_sent(
StatusCode::OK
}
pub fn get_router() -> Router {
Router::new()
.route("/:chat_id/is_need_send", get(is_need_send))

View File

@@ -1,9 +1,8 @@
use axum::{Router, response::IntoResponse, routing::get, Json, extract::Path, http::StatusCode};
use axum::{extract::Path, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
use serde::Serialize;
use crate::prisma::language;
use super::Database;
use crate::prisma::language;
#[derive(Serialize)]
pub struct LanguageDetail {
@@ -12,24 +11,19 @@ pub struct LanguageDetail {
pub code: String,
}
impl From<language::Data> for LanguageDetail {
fn from(value: language::Data) -> Self {
let language::Data { id, label, code, .. } = value;
let language::Data {
id, label, code, ..
} = value;
Self {
id,
label,
code
}
Self { id, label, code }
}
}
async fn get_languages(
db: Database
) -> impl IntoResponse {
let languages: Vec<LanguageDetail> = db.language()
async fn get_languages(db: Database) -> impl IntoResponse {
let languages: Vec<LanguageDetail> = db
.language()
.find_many(vec![])
.exec()
.await
@@ -41,12 +35,9 @@ async fn get_languages(
Json(languages).into_response()
}
async fn get_language_by_code(
Path(code): Path<String>,
db: Database
) -> impl IntoResponse {
let language = db.language()
async fn get_language_by_code(Path(code): Path<String>, db: Database) -> impl IntoResponse {
let language = db
.language()
.find_unique(language::code::equals(code))
.exec()
.await
@@ -58,7 +49,6 @@ async fn get_language_by_code(
}
}
pub fn get_router() -> Router {
Router::new()
.route("/", get(get_languages))

View File

@@ -1,22 +1,27 @@
use axum::{Router, response::Response, http::{StatusCode, self, Request}, middleware::{Next, self}, Extension, routing::get};
use axum::{
http::{self, Request, StatusCode},
middleware::{self, Next},
response::Response,
routing::get,
Extension, Router,
};
use axum_prometheus::PrometheusMetricLayer;
use tower_http::trace::{TraceLayer, self};
use tracing::Level;
use std::sync::Arc;
use tower_http::trace::{self, TraceLayer};
use tracing::Level;
use crate::{config::CONFIG, db::get_prisma_client, prisma::PrismaClient};
pub mod users;
pub mod pagination;
pub mod languages;
pub mod donate_notifications;
pub mod languages;
pub mod pagination;
pub mod users;
pub type Database = Extension<Arc<PrismaClient>>;
async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> {
let auth_header = req.headers()
let auth_header = req
.headers()
.get(http::header::AUTHORIZATION)
.and_then(|header| header.to_str().ok());
@@ -33,7 +38,6 @@ async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode>
Ok(next.run(req).await)
}
pub async fn get_router() -> Router {
let client = Arc::new(get_prisma_client().await);
@@ -47,17 +51,15 @@ pub async fn get_router() -> Router {
.layer(Extension(client))
.layer(prometheus_layer);
let metric_router = Router::new()
.route("/metrics", get(|| async move { metric_handle.render() }));
let metric_router =
Router::new().route("/metrics", get(|| async move { metric_handle.render() }));
Router::new()
.nest("/", app_router)
.nest("/", metric_router)
.layer(
TraceLayer::new_for_http()
.make_span_with(trace::DefaultMakeSpan::new()
.level(Level::INFO))
.on_response(trace::DefaultOnResponse::new()
.level(Level::INFO)),
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
)
}

View File

@@ -1,16 +1,19 @@
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
pub struct Pagination {
#[serde(default = "default_page")]
pub page: usize,
#[serde(default = "default_size")]
pub size: usize
pub size: usize,
}
fn default_page() -> usize { 1 }
fn default_size() -> usize { 50 }
fn default_page() -> usize {
1
}
fn default_size() -> usize {
50
}
impl Pagination {
pub fn skip(&self) -> i64 {
@@ -22,28 +25,29 @@ impl Pagination {
}
}
#[derive(Serialize)]
pub struct Page<T> where T: Serialize {
pub struct Page<T>
where
T: Serialize,
{
pub items: Vec<T>,
pub total: usize,
pub page: usize,
pub size: usize,
pub pages: usize
pub pages: usize,
}
impl<T> Page<T> where T: Serialize {
pub fn create(
items: Vec<T>,
items_count: i64,
pagination: Pagination
) -> Self {
impl<T> Page<T>
where
T: Serialize,
{
pub fn create(items: Vec<T>, items_count: i64, pagination: Pagination) -> Self {
Self {
items,
total: items_count.try_into().unwrap(),
page: pagination.page,
size: pagination.size,
pages: (items_count as f64 / pagination.size as f64).ceil() as usize
pages: (items_count as f64 / pagination.size as f64).ceil() as usize,
}
}
}

View File

@@ -1,34 +1,34 @@
pub mod serializers;
pub mod utils;
use axum::{Router, response::IntoResponse, routing::{get, post}, extract::{Query, Path}, Json, http::StatusCode};
use crate::prisma::{user_settings, language_to_user, user_activity};
use crate::prisma::{language_to_user, user_activity, user_settings};
use axum::{
extract::{Path, Query},
http::StatusCode,
response::IntoResponse,
routing::{get, post},
Json, Router,
};
use self::{serializers::{UserDetail, CreateOrUpdateUserData}, utils::update_languages};
use self::{
serializers::{CreateOrUpdateUserData, UserDetail},
utils::update_languages,
};
use super::{pagination::{Pagination, Page}, Database};
use super::{
pagination::{Page, Pagination},
Database,
};
async fn get_users(
pagination: Query<Pagination>,
db: Database
) -> impl IntoResponse {
async fn get_users(pagination: Query<Pagination>, db: Database) -> impl IntoResponse {
let pagination: Pagination = pagination.0;
let users_count = db.user_settings()
.count(vec![])
.exec()
.await
.unwrap();
let users_count = db.user_settings().count(vec![]).exec().await.unwrap();
let users: Vec<UserDetail> = db.user_settings()
let users: Vec<UserDetail> = db
.user_settings()
.find_many(vec![])
.with(
user_settings::languages::fetch(vec![])
.with(
language_to_user::language::fetch()
)
)
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
.order_by(user_settings::id::order(prisma_client_rust::Direction::Asc))
.skip(pagination.skip())
.take(pagination.take())
@@ -39,26 +39,14 @@ async fn get_users(
.map(|item| item.into())
.collect();
Json(Page::create(
users,
users_count,
pagination
)).into_response()
Json(Page::create(users, users_count, pagination)).into_response()
}
async fn get_user(
Path(user_id): Path<i64>,
db: Database
) -> impl IntoResponse {
let user = db.user_settings()
async fn get_user(Path(user_id): Path<i64>, db: Database) -> impl IntoResponse {
let user = db
.user_settings()
.find_unique(user_settings::user_id::equals(user_id))
.with(
user_settings::languages::fetch(vec![])
.with(
language_to_user::language::fetch()
)
)
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
.exec()
.await
.unwrap();
@@ -70,12 +58,12 @@ async fn get_user(
Json::<UserDetail>(user.unwrap().into()).into_response()
}
async fn create_or_update_user(
db: Database,
Json(data): Json<CreateOrUpdateUserData>,
) -> impl IntoResponse {
let user = db.user_settings()
let user = db
.user_settings()
.upsert(
user_settings::user_id::equals(data.user_id),
user_settings::create(
@@ -84,21 +72,16 @@ async fn create_or_update_user(
data.first_name.clone(),
data.username.clone(),
data.source.clone(),
vec![]
vec![],
),
vec![
user_settings::last_name::set(data.last_name),
user_settings::first_name::set(data.first_name),
user_settings::username::set(data.username),
user_settings::source::set(data.source)
]
)
.with(
user_settings::languages::fetch(vec![])
.with(
language_to_user::language::fetch()
)
user_settings::source::set(data.source),
],
)
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
.exec()
.await
.unwrap();
@@ -106,14 +89,10 @@ async fn create_or_update_user(
let user_id = user.id;
update_languages(user, data.allowed_langs, db.clone()).await;
let user = db.user_settings()
let user = db
.user_settings()
.find_unique(user_settings::id::equals(user_id))
.with(
user_settings::languages::fetch(vec![])
.with(
language_to_user::language::fetch()
)
)
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
.exec()
.await
.unwrap()
@@ -122,12 +101,9 @@ async fn create_or_update_user(
Json::<UserDetail>(user.into()).into_response()
}
async fn update_activity(
Path(user_id): Path<i64>,
db: Database
) -> impl IntoResponse {
let user = db.user_settings()
async fn update_activity(Path(user_id): Path<i64>, db: Database) -> impl IntoResponse {
let user = db
.user_settings()
.find_unique(user_settings::user_id::equals(user_id))
.exec()
.await
@@ -138,17 +114,18 @@ async fn update_activity(
None => return StatusCode::NOT_FOUND.into_response(),
};
let _ = db.user_activity()
let _ = db
.user_activity()
.upsert(
user_activity::user_id::equals(user.id),
user_activity::create(
chrono::offset::Local::now().into(),
user_settings::id::equals(user.id),
vec![]
vec![],
),
vec![
user_activity::updated::set(chrono::offset::Local::now().into())
]
vec![user_activity::updated::set(
chrono::offset::Local::now().into(),
)],
)
.exec()
.await;
@@ -156,7 +133,6 @@ async fn update_activity(
StatusCode::OK.into_response()
}
pub fn get_router() -> Router {
Router::new()
.route("/", get(get_users))

View File

@@ -1,7 +1,6 @@
use serde::{Serialize, Deserialize};
use crate::prisma::{user_settings, language};
use serde::{Deserialize, Serialize};
use crate::prisma::{language, user_settings};
#[derive(Serialize)]
pub struct UserLanguage {
@@ -10,18 +9,16 @@ pub struct UserLanguage {
pub code: String,
}
impl From<language::Data> for UserLanguage {
fn from(value: language::Data) -> Self {
Self {
id: value.id,
label: value.label,
code: value.code
code: value.code,
}
}
}
#[derive(Serialize)]
pub struct UserDetail {
pub id: i32,
@@ -30,14 +27,14 @@ pub struct UserDetail {
pub first_name: String,
pub username: String,
pub source: String,
pub allowed_langs: Vec<UserLanguage>
pub allowed_langs: Vec<UserLanguage>,
}
impl From<user_settings::Data> for UserDetail {
fn from(value: user_settings::Data) -> Self {
let allowed_langs: Vec<UserLanguage> = value
.languages.unwrap()
.languages
.unwrap()
.into_iter()
.map(|item| *item.language.unwrap())
.map(|item| item.into())
@@ -50,7 +47,7 @@ impl From<user_settings::Data> for UserDetail {
first_name: value.first_name,
username: value.username,
source: value.source,
allowed_langs
allowed_langs,
}
}
}
@@ -62,5 +59,5 @@ pub struct CreateOrUpdateUserData {
pub first_name: String,
pub username: String,
pub source: String,
pub allowed_langs: Vec<String>
pub allowed_langs: Vec<String>,
}

View File

@@ -1,36 +1,36 @@
use std::collections::HashMap;
use crate::{prisma::{user_settings, language, language_to_user}, views::Database};
use crate::{
prisma::{language, language_to_user, user_settings},
views::Database,
};
pub async fn update_languages(
user: user_settings::Data,
new_langs: Vec<String>,
db: Database
) {
pub async fn update_languages(user: user_settings::Data, new_langs: Vec<String>, db: Database) {
// Delete
{
let need_delete: Vec<_> = user.languages().unwrap()
let need_delete: Vec<_> = user
.languages()
.unwrap()
.iter()
.map(|item| {
let language::Data{ id, code, .. } = *item.clone().language.unwrap();
let language::Data { id, code, .. } = *item.clone().language.unwrap();
(id, code)
})
.filter(|(_, code)| !new_langs.contains(code))
.map(|(id, _)| id)
.collect();
let _ = db.language_to_user()
.delete_many(
vec![language_to_user::id::in_vec(need_delete)]
)
let _ = db
.language_to_user()
.delete_many(vec![language_to_user::id::in_vec(need_delete)])
.exec()
.await;
}
// Create
{
let languages: HashMap<_, _> = db.language()
let languages: HashMap<_, _> = db
.language()
.find_many(vec![])
.exec()
.await
@@ -39,7 +39,9 @@ pub async fn update_languages(
.map(|l| (l.code, l.id))
.collect();
let current_langs: Vec<_> = user.languages().unwrap()
let current_langs: Vec<_> = user
.languages()
.unwrap()
.iter()
.map(|item| item.clone().language.unwrap().code)
.collect();
@@ -50,18 +52,17 @@ pub async fn update_languages(
.map(|code| *languages.get(&code).unwrap())
.collect();
let _ = db.language_to_user()
.create_many(
need_create
.iter()
.map(|language_id| language_to_user::create_unchecked(
*language_id,
user.id,
vec![]
))
.collect()
)
.exec()
.await;
let _ = db
.language_to_user()
.create_many(
need_create
.iter()
.map(|language_id| {
language_to_user::create_unchecked(*language_id, user.id, vec![])
})
.collect(),
)
.exec()
.await;
}
}