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_port: u32,
pub postgres_db: String, pub postgres_db: String,
pub sentry_dsn: String pub sentry_dsn: String,
} }
fn get_env(env: &'static str) -> String { fn get_env(env: &'static str) -> String {
std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {} env variable", env)) std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {} env variable", env))
} }
impl Config { impl Config {
pub fn load() -> Config { pub fn load() -> Config {
Config { Config {
@@ -29,12 +27,9 @@ impl Config {
postgres_port: get_env("POSTGRES_PORT").parse().unwrap(), postgres_port: get_env("POSTGRES_PORT").parse().unwrap(),
postgres_db: get_env("POSTGRES_DB"), 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 { pub async fn get_prisma_client() -> PrismaClient {
let database_url: String = format!( let database_url: String = format!(

View File

@@ -1,14 +1,13 @@
pub mod config; pub mod config;
pub mod db;
pub mod prisma; pub mod prisma;
pub mod views; 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 tracing::info;
use std::{net::SocketAddr, str::FromStr}; use std::{net::SocketAddr, str::FromStr};
async fn start_app() { async fn start_app() {
let app = views::get_router().await; let app = views::get_router().await;

View File

@@ -1,7 +1,8 @@
// Code generated by Prisma Client Rust. DO NOT EDIT // Code generated by Prisma Client Rust. DO NOT EDIT
pub static DATAMODEL_STR: &str = #![allow(clippy::all)]
include_str!("../prisma/schema.prisma");
pub static DATAMODEL_STR: &str = include_str!("../prisma/schema.prisma");
static DATABASE_STR: &str = "postgresql"; static DATABASE_STR: &str = "postgresql";
pub async fn new_client() -> Result<PrismaClient, ::prisma_client_rust::NewClientError> { pub async fn new_client() -> Result<PrismaClient, ::prisma_client_rust::NewClientError> {
PrismaClient::_builder().build().await PrismaClient::_builder().build().await
@@ -21,9 +22,7 @@ pub mod user_settings {
pub mod id { pub mod id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "id"; pub const NAME: &str = "id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -92,9 +91,7 @@ pub mod user_settings {
pub mod user_id { pub mod user_id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "user_id"; pub const NAME: &str = "user_id";
pub struct Set(pub i64); pub struct Set(pub i64);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -167,9 +164,7 @@ pub mod user_settings {
pub mod last_name { pub mod last_name {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "last_name"; pub const NAME: &str = "last_name";
pub struct Set(pub String); pub struct Set(pub String);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -234,9 +229,7 @@ pub mod user_settings {
pub mod first_name { pub mod first_name {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "first_name"; pub const NAME: &str = "first_name";
pub struct Set(pub String); pub struct Set(pub String);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -301,9 +294,7 @@ pub mod user_settings {
pub mod username { pub mod username {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "username"; pub const NAME: &str = "username";
pub struct Set(pub String); pub struct Set(pub String);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -368,9 +359,7 @@ pub mod user_settings {
pub mod source { pub mod source {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "source"; pub const NAME: &str = "source";
pub struct Set(pub String); pub struct Set(pub String);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -435,9 +424,7 @@ pub mod user_settings {
pub mod user_activity { pub mod user_activity {
use super::super::*; use super::super::*;
use super::{ use super::{SetParam, WhereParam, WithParam};
SetParam, WhereParam, WithParam,
};
pub const NAME: &str = "user_activity"; pub const NAME: &str = "user_activity";
pub struct Fetch(pub user_activity::UniqueArgs); pub struct Fetch(pub user_activity::UniqueArgs);
impl Fetch { impl Fetch {
@@ -523,9 +510,7 @@ pub mod user_settings {
pub mod languages { pub mod languages {
use super::super::*; use super::super::*;
use super::{ use super::{SetParam, WhereParam, WithParam};
SetParam, WhereParam, WithParam,
};
pub const NAME: &str = "languages"; pub const NAME: &str = "languages";
pub struct Fetch(pub language_to_user::ManyArgs); pub struct Fetch(pub language_to_user::ManyArgs);
impl Fetch { impl Fetch {
@@ -1385,9 +1370,7 @@ pub mod chat_donate_notifications {
pub mod id { pub mod id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "id"; pub const NAME: &str = "id";
pub struct Set(pub i64); pub struct Set(pub i64);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -1456,9 +1439,7 @@ pub mod chat_donate_notifications {
pub mod chat_id { pub mod chat_id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "chat_id"; pub const NAME: &str = "chat_id";
pub struct Set(pub i64); pub struct Set(pub i64);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -1531,9 +1512,7 @@ pub mod chat_donate_notifications {
pub mod sended { pub mod sended {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "sended"; pub const NAME: &str = "sended";
pub struct Set( pub struct Set(
pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>, pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>,
@@ -2068,9 +2047,7 @@ pub mod language {
pub mod id { pub mod id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "id"; pub const NAME: &str = "id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -2139,9 +2116,7 @@ pub mod language {
pub mod label { pub mod label {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "label"; pub const NAME: &str = "label";
pub struct Set(pub String); pub struct Set(pub String);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -2206,9 +2181,7 @@ pub mod language {
pub mod code { pub mod code {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "code"; pub const NAME: &str = "code";
pub struct Set(pub String); pub struct Set(pub String);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -2269,9 +2242,7 @@ pub mod language {
pub mod users { pub mod users {
use super::super::*; use super::super::*;
use super::{ use super::{SetParam, WhereParam, WithParam};
SetParam, WhereParam, WithParam,
};
pub const NAME: &str = "users"; pub const NAME: &str = "users";
pub struct Fetch(pub language_to_user::ManyArgs); pub struct Fetch(pub language_to_user::ManyArgs);
impl Fetch { impl Fetch {
@@ -2891,9 +2862,7 @@ pub mod user_activity {
pub mod id { pub mod id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "id"; pub const NAME: &str = "id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -2962,9 +2931,7 @@ pub mod user_activity {
pub mod user_id { pub mod user_id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "user_id"; pub const NAME: &str = "user_id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -3033,9 +3000,7 @@ pub mod user_activity {
pub mod updated { pub mod updated {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "updated"; pub const NAME: &str = "updated";
pub struct Set( pub struct Set(
pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>, pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>,
@@ -3138,9 +3103,7 @@ pub mod user_activity {
pub mod user { pub mod user {
use super::super::*; use super::super::*;
use super::{ use super::{SetParam, WhereParam, WithParam};
SetParam, WhereParam, WithParam,
};
pub const NAME: &str = "user"; pub const NAME: &str = "user";
pub struct Fetch(pub user_settings::UniqueArgs); pub struct Fetch(pub user_settings::UniqueArgs);
impl Fetch { impl Fetch {
@@ -3725,9 +3688,7 @@ pub mod language_to_user {
pub mod id { pub mod id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
};
pub const NAME: &str = "id"; pub const NAME: &str = "id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -3796,9 +3757,7 @@ pub mod language_to_user {
pub mod language_id { pub mod language_id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "language_id"; pub const NAME: &str = "language_id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -3871,9 +3830,7 @@ pub mod language_to_user {
pub mod user_id { pub mod user_id {
use super::super::*; use super::super::*;
use super::{ use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
};
pub const NAME: &str = "user_id"; pub const NAME: &str = "user_id";
pub struct Set(pub i32); pub struct Set(pub i32);
impl From<Set> for SetParam { impl From<Set> for SetParam {
@@ -3942,9 +3899,7 @@ pub mod language_to_user {
pub mod language { pub mod language {
use super::super::*; use super::super::*;
use super::{ use super::{SetParam, WhereParam, WithParam};
SetParam, WhereParam, WithParam,
};
pub const NAME: &str = "language"; pub const NAME: &str = "language";
pub struct Fetch(pub language::UniqueArgs); pub struct Fetch(pub language::UniqueArgs);
impl Fetch { impl Fetch {
@@ -4048,9 +4003,7 @@ pub mod language_to_user {
pub mod user { pub mod user {
use super::super::*; use super::super::*;
use super::{ use super::{SetParam, WhereParam, WithParam};
SetParam, WhereParam, WithParam,
};
pub const NAME: &str = "user"; pub const NAME: &str = "user";
pub struct Fetch(pub user_settings::UniqueArgs); pub struct Fetch(pub user_settings::UniqueArgs);
impl Fetch { 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 chrono::Duration;
use crate::prisma::chat_donate_notifications; use crate::prisma::chat_donate_notifications;
use super::Database; 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; 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)) .find_unique(chat_donate_notifications::chat_id::equals(chat_id))
.exec() .exec()
.await .await
@@ -20,31 +23,24 @@ async fn is_need_send(
match notification { match notification {
Some(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() Json(result).into_response()
}, }
None => Json(true).into_response(), None => Json(true).into_response(),
} }
} }
async fn mark_sent(Path(chat_id): Path<i64>, db: Database) -> impl IntoResponse {
async fn mark_sent( let _ = db
Path(chat_id): Path<i64>, .chat_donate_notifications()
db: Database
) -> impl IntoResponse {
let _ = db.chat_donate_notifications()
.upsert( .upsert(
chat_donate_notifications::chat_id::equals(chat_id), chat_donate_notifications::chat_id::equals(chat_id),
chat_donate_notifications::create( chat_donate_notifications::create(chat_id, chrono::offset::Local::now().into(), vec![]),
chat_id, vec![chat_donate_notifications::sended::set(
chrono::offset::Local::now().into(), chrono::offset::Local::now().into(),
vec![] )],
),
vec![
chat_donate_notifications::sended::set(
chrono::offset::Local::now().into()
)
]
) )
.exec() .exec()
.await; .await;
@@ -52,7 +48,6 @@ async fn mark_sent(
StatusCode::OK StatusCode::OK
} }
pub fn get_router() -> Router { pub fn get_router() -> Router {
Router::new() Router::new()
.route("/:chat_id/is_need_send", get(is_need_send)) .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 serde::Serialize;
use crate::prisma::language;
use super::Database; use super::Database;
use crate::prisma::language;
#[derive(Serialize)] #[derive(Serialize)]
pub struct LanguageDetail { pub struct LanguageDetail {
@@ -12,24 +11,19 @@ pub struct LanguageDetail {
pub code: String, pub code: String,
} }
impl From<language::Data> for LanguageDetail { impl From<language::Data> for LanguageDetail {
fn from(value: language::Data) -> Self { fn from(value: language::Data) -> Self {
let language::Data { id, label, code, .. } = value; let language::Data {
id, label, code, ..
} = value;
Self { Self { id, label, code }
id,
label,
code
}
} }
} }
async fn get_languages(db: Database) -> impl IntoResponse {
async fn get_languages( let languages: Vec<LanguageDetail> = db
db: Database .language()
) -> impl IntoResponse {
let languages: Vec<LanguageDetail> = db.language()
.find_many(vec![]) .find_many(vec![])
.exec() .exec()
.await .await
@@ -41,12 +35,9 @@ async fn get_languages(
Json(languages).into_response() Json(languages).into_response()
} }
async fn get_language_by_code(Path(code): Path<String>, db: Database) -> impl IntoResponse {
async fn get_language_by_code( let language = db
Path(code): Path<String>, .language()
db: Database
) -> impl IntoResponse {
let language = db.language()
.find_unique(language::code::equals(code)) .find_unique(language::code::equals(code))
.exec() .exec()
.await .await
@@ -58,7 +49,6 @@ async fn get_language_by_code(
} }
} }
pub fn get_router() -> Router { pub fn get_router() -> Router {
Router::new() Router::new()
.route("/", get(get_languages)) .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 axum_prometheus::PrometheusMetricLayer;
use tower_http::trace::{TraceLayer, self};
use tracing::Level;
use std::sync::Arc; use std::sync::Arc;
use tower_http::trace::{self, TraceLayer};
use tracing::Level;
use crate::{config::CONFIG, db::get_prisma_client, prisma::PrismaClient}; 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 donate_notifications;
pub mod languages;
pub mod pagination;
pub mod users;
pub type Database = Extension<Arc<PrismaClient>>; pub type Database = Extension<Arc<PrismaClient>>;
async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> { 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) .get(http::header::AUTHORIZATION)
.and_then(|header| header.to_str().ok()); .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) Ok(next.run(req).await)
} }
pub async fn get_router() -> Router { pub async fn get_router() -> Router {
let client = Arc::new(get_prisma_client().await); let client = Arc::new(get_prisma_client().await);
@@ -47,17 +51,15 @@ pub async fn get_router() -> Router {
.layer(Extension(client)) .layer(Extension(client))
.layer(prometheus_layer); .layer(prometheus_layer);
let metric_router = Router::new() let metric_router =
.route("/metrics", get(|| async move { metric_handle.render() })); Router::new().route("/metrics", get(|| async move { metric_handle.render() }));
Router::new() Router::new()
.nest("/", app_router) .nest("/", app_router)
.nest("/", metric_router) .nest("/", metric_router)
.layer( .layer(
TraceLayer::new_for_http() TraceLayer::new_for_http()
.make_span_with(trace::DefaultMakeSpan::new() .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
.level(Level::INFO)) .on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
.on_response(trace::DefaultOnResponse::new()
.level(Level::INFO)),
) )
} }

View File

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

View File

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

View File

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