first commit
This commit is contained in:
commit
a4fe41985d
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
||||||
|
[package]
|
||||||
|
name = "axum-test"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
axum = "0.7.5"
|
||||||
|
derive_more = "0.99.17"
|
||||||
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
|
serde_json = "1.0.115"
|
||||||
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
|
sqlx = { version = "0.7.4", features = [
|
||||||
|
# "runtime-tokio-rustls",
|
||||||
|
"runtime-tokio",
|
||||||
|
"postgres",
|
||||||
|
"uuid",
|
||||||
|
"chrono",
|
||||||
|
"json",
|
||||||
|
] }
|
|
@ -0,0 +1,10 @@
|
||||||
|
use sqlx::postgres::PgPoolOptions;
|
||||||
|
|
||||||
|
pub async fn create_pool() -> Result<sqlx::PgPool, sqlx::Error> {
|
||||||
|
let pool = PgPoolOptions::new()
|
||||||
|
.max_connections(5)
|
||||||
|
.connect("postgres://peter:peter@192.168.188.249:5432/test")
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(pool)
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub enum ErrorType {
|
||||||
|
DbError,
|
||||||
|
Axum,
|
||||||
|
Tokio,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct AppError {
|
||||||
|
pub message: Option<String>,
|
||||||
|
pub cause: Option<String>,
|
||||||
|
pub error_type: ErrorType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppError {
|
||||||
|
pub fn message(&self) -> String {
|
||||||
|
match self {
|
||||||
|
AppError {
|
||||||
|
message: Some(message),
|
||||||
|
..
|
||||||
|
} => message.clone(),
|
||||||
|
AppError {
|
||||||
|
error_type: ErrorType::Tokio,
|
||||||
|
..
|
||||||
|
} => "Server Error".to_string(),
|
||||||
|
AppError {
|
||||||
|
error_type: ErrorType::DbError,
|
||||||
|
..
|
||||||
|
} => "The requested item was not found".to_string(),
|
||||||
|
_ => "An unexpected error has occurred".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl fmt::Display for AppError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
|
write!(f, "{}", self.message())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// impl From<std::io::Error> for AppError {
|
||||||
|
// fn from(error: std::io::Error) -> Self {
|
||||||
|
// AppError {
|
||||||
|
// message: None,
|
||||||
|
// cause: Some(error.to_string()),
|
||||||
|
// error_type: ErrorType::Standard,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
impl From<sqlx::Error> for AppError {
|
||||||
|
fn from(error: sqlx::Error) -> AppError {
|
||||||
|
AppError {
|
||||||
|
message: None,
|
||||||
|
cause: Some(error.to_string()),
|
||||||
|
error_type: ErrorType::DbError,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<axum::Error> for AppError {
|
||||||
|
fn from(error: axum::Error) -> Self {
|
||||||
|
AppError {
|
||||||
|
message: None,
|
||||||
|
cause: Some(error.to_string()),
|
||||||
|
error_type: ErrorType::Axum,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<tokio::io::Error> for AppError {
|
||||||
|
fn from(error: tokio::io::Error) -> Self {
|
||||||
|
AppError {
|
||||||
|
message: None,
|
||||||
|
cause: Some(error.to_string()),
|
||||||
|
error_type: ErrorType::Tokio,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
mod db_pool;
|
||||||
|
mod errors;
|
||||||
|
mod models;
|
||||||
|
mod routers;
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
routing::{get, post},
|
||||||
|
Router,
|
||||||
|
};
|
||||||
|
use errors::AppError;
|
||||||
|
|
||||||
|
use crate::routers::benutzer::erstelle_benutzer;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), AppError> {
|
||||||
|
let pool = db_pool::create_pool().await?;
|
||||||
|
|
||||||
|
// let row: (i64) = sqlx::query_as("SELECT $1")
|
||||||
|
// .bind(150_i64)
|
||||||
|
// .fetch_one(&pool)
|
||||||
|
// .await?;
|
||||||
|
// println!("Row: {:?}", row);
|
||||||
|
|
||||||
|
let app = Router::new()
|
||||||
|
.route("/", get(root))
|
||||||
|
.route("/benutzer", post(erstelle_benutzer));
|
||||||
|
|
||||||
|
let listener = tokio::net::TcpListener::bind("1127.0.0.1:3000").await?;
|
||||||
|
|
||||||
|
tracing::debug!("listening on {}", listener.local_addr()?);
|
||||||
|
axum::serve(listener, app).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn root() -> &'static str {
|
||||||
|
"Hello, World!"
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
use super::kategorien::Kategorie;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::io::Error;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Amtsbezeichnung {
|
||||||
|
pub id: u64,
|
||||||
|
pub name: String,
|
||||||
|
pub kategorie: Kategorie,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AmtsbezeichnungErstellen {
|
||||||
|
pub name: String,
|
||||||
|
pub kategorie_id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub struct AmtsbezeichnungAendern {
|
||||||
|
// pub id: u64,
|
||||||
|
// pub name: Option<String>,
|
||||||
|
// pub kategorie_id: Option<u64>,
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub trait Check {
|
||||||
|
fn check_id(&self) -> Result<(), Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Check for AmtsbezeichnungErstellen {
|
||||||
|
fn check_id(&self) -> Result<(), Error> {
|
||||||
|
if self.kategorie_id == 0 {
|
||||||
|
return Err(Error::new(std::io::ErrorKind::Other, "Kategorie-ID fehlt"));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
use super::amtsbezeichnungen::Amtsbezeichnung;
|
||||||
|
use super::dienststellen::Dienststelle;
|
||||||
|
use super::gruppen::Gruppe;
|
||||||
|
use super::rollen::Rolle;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct ErstelleBenutzer {
|
||||||
|
pub kennung: String,
|
||||||
|
pub vorname: String,
|
||||||
|
pub nachname: String,
|
||||||
|
pub telefon: String,
|
||||||
|
pub rollen: Option<Vec<Rolle>>,
|
||||||
|
pub gruppen: Option<Vec<Gruppe>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct UpdateBenutzer {
|
||||||
|
pub id: u64,
|
||||||
|
pub kennung: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Debug)]
|
||||||
|
pub struct Benutzer {
|
||||||
|
pub id: u64,
|
||||||
|
pub kennung: String,
|
||||||
|
pub vorname: String,
|
||||||
|
pub nachname: String,
|
||||||
|
pub telefon: String,
|
||||||
|
pub amtsbezeichnung: Amtsbezeichnung,
|
||||||
|
pub dienststelle: Dienststelle,
|
||||||
|
pub abweichende_dienststelle: Option<Dienststelle>,
|
||||||
|
pub rollen: Option<Vec<Rolle>>,
|
||||||
|
pub gruppen: Option<Vec<Gruppe>>,
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Dienststelle {
|
||||||
|
pub id: u64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Gruppe {
|
||||||
|
pub id: u64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Kategorie {
|
||||||
|
pub id: u64,
|
||||||
|
pub name: String,
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
pub mod amtsbezeichnungen;
|
||||||
|
pub mod benutzer;
|
||||||
|
pub mod dienststellen;
|
||||||
|
pub mod gruppen;
|
||||||
|
pub mod kategorien;
|
||||||
|
pub mod rollen;
|
|
@ -0,0 +1,9 @@
|
||||||
|
use super::gruppen::Gruppe;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Rolle {
|
||||||
|
pub id: u64,
|
||||||
|
pub name: String,
|
||||||
|
pub gruppen: Vec<Gruppe>,
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
use axum::{http::StatusCode, response::IntoResponse, Json};
|
||||||
|
|
||||||
|
use crate::models::amtsbezeichnungen::Amtsbezeichnung;
|
||||||
|
use crate::models::benutzer::{Benutzer, ErstelleBenutzer};
|
||||||
|
use crate::models::dienststellen::Dienststelle;
|
||||||
|
use crate::models::kategorien::Kategorie;
|
||||||
|
|
||||||
|
pub async fn erstelle_benutzer(Json(payload): Json<ErstelleBenutzer>) -> impl IntoResponse {
|
||||||
|
let kat = Kategorie {
|
||||||
|
id: 1337,
|
||||||
|
name: String::from("Kategorie"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let ab = Amtsbezeichnung {
|
||||||
|
id: 1337,
|
||||||
|
name: String::from("Dienstgrad"),
|
||||||
|
kategorie: kat,
|
||||||
|
};
|
||||||
|
|
||||||
|
let dst = Dienststelle {
|
||||||
|
id: 1,
|
||||||
|
name: String::from("test"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let user = Benutzer {
|
||||||
|
id: 1337,
|
||||||
|
kennung: payload.kennung,
|
||||||
|
nachname: payload.nachname,
|
||||||
|
vorname: payload.vorname,
|
||||||
|
amtsbezeichnung: ab,
|
||||||
|
dienststelle: dst,
|
||||||
|
telefon: payload.telefon,
|
||||||
|
abweichende_dienststelle: None,
|
||||||
|
gruppen: None,
|
||||||
|
rollen: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
tracing::debug!("Benutzer: {:?}", user);
|
||||||
|
(StatusCode::CREATED, Json(user))
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod benutzer;
|
Loading…
Reference in New Issue