Some basic rust code for new backend

This commit is contained in:
Mawoka
2024-07-12 11:54:32 +02:00
parent 0ad07eced6
commit 2a691817fa
12 changed files with 2588 additions and 0 deletions
+1
View File
@@ -12,3 +12,4 @@ node_modules/
survey.json
.coverage
export_deta.py
target/
+2337
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
+27
View File
@@ -0,0 +1,27 @@
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0
[workspace]
resolver = "2"
members = ["app", "live", "shared"]
[workspace.dependencies]
sqlx = { version = "0.7", features = [
"runtime-tokio",
"postgres",
"uuid",
"chrono",
"json",
"macros",
"migrate",
] }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["raw_value"] }
tokio = { version = "1.36", features = ["full"] }
chrono = { version = "0.4", features = ["clock", "serde"] }
dotenvy = "0.15"
uuid = { version = "1.7.0", features = ["serde", "v4", "fast-rng", "v7"] }
anyhow = "1"
+11
View File
@@ -0,0 +1,11 @@
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0
[package]
name = "app"
version = "0.1.0"
edition = "2021"
[dependencies]
+7
View File
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
//
// SPDX-License-Identifier: MPL-2.0
fn main() {
println!("Hello, world!");
}
+9
View File
@@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0
[package]
name = "live"
version = "0.1.0"
edition = "2021"
[dependencies]
+7
View File
@@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
//
// SPDX-License-Identifier: MPL-2.0
fn main() {
println!("Hello, world!");
}
+18
View File
@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
#
# SPDX-License-Identifier: MPL-2.0
[package]
name = "shared"
version = "0.1.0"
edition = "2021"
[dependencies]
strum = { version = "0.26", features = ["derive"] }
sqlx = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
uuid = { workspace = true }
chrono = { workspace = true }
validator = { version = "0.18", features = ["derive"] }
garde = { version = "0.20", features = ["full"] }
+6
View File
@@ -0,0 +1,6 @@
// SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
//
// SPDX-License-Identifier: MPL-2.0
pub mod models;
+154
View File
@@ -0,0 +1,154 @@
// SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
//
// SPDX-License-Identifier: MPL-2.0
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use garde::{Validate, Valid};
#[derive(strum::Display)]
#[strum(serialize_all = "UPPERCASE")]
pub enum UserAuthTypes {
Local,
Google,
Github,
Custom,
}
pub struct User {
pub id: Uuid,
pub email: String,
pub password: Option<String>,
pub verified: bool,
pub verify_key: Option<String>,
pub created_at: chrono::NaiveDateTime,
pub auth_type: UserAuthTypes,
pub google_uid: Option<String>,
pub avatar: Vec<u8>,
pub github_user_id: Option<i32>,
pub require_password: bool,
pub backup_code: String,
pub totp_secret: String,
pub storage_used: i64,
}
pub struct FidoCredentials {
pub pk: i32,
pub id: Vec<u8>,
pub public_key: Vec<u8>,
pub sign_count: i32,
pub user: Uuid,
}
pub struct ApiKey {
pub key: String,
pub user: Option<Uuid>,
}
pub struct UserSession {
pub id: Uuid,
pub user: Option<Uuid>,
pub session_key: String,
pub created_at: chrono::NaiveDateTime,
pub ip_address: String,
pub user_agent: String,
pub last_seen: chrono::NaiveDateTime,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ABCDQuizAnswer {
right: bool,
answer: String,
color: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RangeQuizAnswer {
min: i32,
max: i32,
min_correct: i32,
max_correct: i32,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct VotingQuizAnswer {
answer: String,
image: Option<String>,
color: Option<String>,
}
#[derive(strum::Display, Debug, Serialize, Deserialize, Clone, PartialEq)]
#[strum(serialize_all = "UPPERCASE")]
pub enum QuizQuestionType {
Abcd,
Range,
Voting,
Slide,
Text,
Order,
Check,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct TextQuizAnswer {
answer: String,
case_sensitive: bool,
}
#[derive(Debug, Serialize, Deserialize, Validate)]
pub struct QuizQuestion {
#[garde(skip)]
question: String,
#[garde(skip)]
time: i32,
#[serde(default = "default_type")]
#[serde(rename = "type")]
#[garde(skip)]
question_type: Option<QuizQuestionType>,
#[garde(custom(validate_answers))]
answers: QuizAnswers,
#[garde(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
image: Option<String>,
#[garde(skip)]
#[serde(skip_serializing_if = "Option::is_none")]
hide_results: Option<bool>,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum QuizAnswers {
ABCD(Vec<ABCDQuizAnswer>),
Range(RangeQuizAnswer),
Text(Vec<TextQuizAnswer>),
Voting(Vec<VotingQuizAnswer>),
Slide(String),
}
fn default_type() -> Option<QuizQuestionType> {
Some(QuizQuestionType::Abcd)
}
// impl Validate for QuizQuestion {
// fn validate(&self) -> Result<(), ValidationErrors> {
// match validate_answers(&self.answers, self) {
// Ok(_) => Ok(()),
// Err(e) => {
// let mut error = ValidationErrors::new();
// error.add("answers", e);
// Err(error)
// }
// }
// }
// }
fn validate_answers(answers: &QuizAnswers) -> garde::Result {
match (&context.question_type, answers) {
(Some(QuizQuestionType::Abcd), QuizAnswers::ABCD(_)) => Ok(()),
(Some(QuizQuestionType::Range), QuizAnswers::Range(_)) => Ok(()),
(Some(QuizQuestionType::Voting), QuizAnswers::Voting(_)) => Ok(()),
(Some(QuizQuestionType::Text), QuizAnswers::Text(_)) => Ok(()),
(Some(QuizQuestionType::Order), QuizAnswers::Voting(_)) => Ok(()),
(Some(QuizQuestionType::Slide), QuizAnswers::Slide(_)) => Ok(()),
(Some(QuizQuestionType::Check), QuizAnswers::ABCD(_)) => Ok(()),
_ => Err(garde::Error::new("invalid_answers")),
}
}
+8
View File
@@ -0,0 +1,8 @@
<!--
SPDX-FileCopyrightText: 2023 Marlon W (Mawoka)
SPDX-License-Identifier: MPL-2.0
-->
# Migration of the Backend to Rust (long term goal)