feat: add logic for journey->train identifier resolving, add recording of journeys, build api bearer auth
This commit is contained in:
43
src/model/app.rs
Normal file
43
src/model/app.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use sqlx::{PgPool};
|
||||
use sqlx::pool::PoolOptions;
|
||||
use tokio::sync::Mutex;
|
||||
use crate::config::IceBingoConfig;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AppState
|
||||
{
|
||||
pub state: Arc<Mutex<HashMap<String, String>>>,
|
||||
pub db: Arc<PgPool>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
pub(crate) async fn new(config: IceBingoConfig) -> Result<Self, sqlx::Error> {
|
||||
let kv_store: HashMap<String, String> = HashMap::new();
|
||||
let state_mutex = Arc::new(Mutex::new(kv_store));
|
||||
let db_url = get_db_url(&config);
|
||||
let pool_options = PoolOptions::new()
|
||||
.max_connections(20)
|
||||
.min_connections(5);
|
||||
let pool = pool_options.connect(db_url.as_str()).await?;
|
||||
Ok(Self {
|
||||
state: state_mutex,
|
||||
db: Arc::new(pool)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn get_db_url(config: &IceBingoConfig) -> String {
|
||||
match config.database.db_type.as_str() {
|
||||
"postgresql" => format!(
|
||||
"postgresql://{}:{}@{}/{}",
|
||||
config.database.user,
|
||||
config.database.password,
|
||||
config.database.host,
|
||||
config.database.database
|
||||
),
|
||||
_ => "".to_string()
|
||||
}
|
||||
}
|
||||
|
6
src/model/bingo_card.rs
Normal file
6
src/model/bingo_card.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use crate::model::train::Train;
|
||||
|
||||
struct BingoCard {
|
||||
id: uuid::Uuid,
|
||||
fields: [Train; 24],
|
||||
}
|
14
src/model/database.rs
Normal file
14
src/model/database.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone)]
|
||||
pub struct User {
|
||||
pub uuid: Uuid,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(sqlx::FromRow, Debug, Clone)]
|
||||
pub struct Train {
|
||||
pub uuid: Uuid,
|
||||
pub tz_id: i32,
|
||||
pub name: Option<String>,
|
||||
}
|
26
src/model/db_vendo_navigator_api.rs
Normal file
26
src/model/db_vendo_navigator_api.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use serde::Deserialize;
|
||||
use crate::model::travelynx::TrainType;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TrainOrdering {
|
||||
#[serde(rename = "fahrzeuggruppen")]
|
||||
pub train_sets: Vec<TrainSet>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TrainSet {
|
||||
#[serde(rename = "bezeichnung")]
|
||||
pub identifier: String,
|
||||
#[serde(rename = "fahrtreferenz")]
|
||||
pub journey: Journey,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Journey {
|
||||
#[serde(rename = "typ")]
|
||||
pub category: String,
|
||||
#[serde(rename = "gattung")]
|
||||
pub train_type: TrainType,
|
||||
#[serde(rename = "fahrtnummer")]
|
||||
pub trip_number: usize,
|
||||
}
|
8
src/model/mod.rs
Normal file
8
src/model/mod.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
pub mod uic;
|
||||
pub mod db_vendo_navigator_api;
|
||||
pub(crate) mod travelynx;
|
||||
pub(crate) mod traewelling;
|
||||
mod bingo_card;
|
||||
mod train;
|
||||
pub(crate) mod app;
|
||||
pub(crate) mod database;
|
6
src/model/traewelling.rs
Normal file
6
src/model/traewelling.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub(crate) struct CheckIn {
|
||||
|
||||
}
|
4
src/model/train.rs
Normal file
4
src/model/train.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
use crate::model::uic::UIC;
|
||||
pub(crate) struct Train {
|
||||
uic: UIC,
|
||||
}
|
92
src/model/travelynx.rs
Normal file
92
src/model/travelynx.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use serde::{de, Deserialize};
|
||||
use strum_macros::{Display, EnumString};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub(crate) struct CheckIn {
|
||||
#[serde(deserialize_with = "reason_to_enum")]
|
||||
pub reason: CheckInReason,
|
||||
pub status: CheckInStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, EnumString)]
|
||||
#[strum(ascii_case_insensitive)]
|
||||
pub enum CheckInReason {
|
||||
PING,
|
||||
CHECKIN,
|
||||
UPDATE,
|
||||
UNDO,
|
||||
}
|
||||
|
||||
fn reason_to_enum<'de, D>(deserializer: D) -> Result<CheckInReason, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
let s: &str = de::Deserialize::deserialize(deserializer)?;
|
||||
CheckInReason::try_from(s).map_err(de::Error::custom)
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CheckInStatus {
|
||||
action_time: usize,
|
||||
backend: Backend,
|
||||
checked_in: bool,
|
||||
comment: Option<String>,
|
||||
deprecated: bool,
|
||||
pub from_station: Station,
|
||||
//pub to_station: Station,
|
||||
pub train: Train
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, EnumString)]
|
||||
#[strum(ascii_case_insensitive)]
|
||||
enum BackendType {
|
||||
DBRIS,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Backend {
|
||||
id: u8,
|
||||
name: String,
|
||||
#[serde(rename = "type")]
|
||||
backend_type: BackendType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Station {
|
||||
ds100: Option<String>,
|
||||
latitude: Option<f64>,
|
||||
longitude: Option<f64>,
|
||||
platform: Option<String>,
|
||||
real_time: Option<usize>,
|
||||
pub scheduled_time: Option<usize>,
|
||||
pub uic: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Train {
|
||||
hafas_id: Option<String>,
|
||||
id: String,
|
||||
line: Option<String>,
|
||||
#[serde(rename = "no")]
|
||||
pub number: Option<String>,
|
||||
#[serde(rename = "type")]
|
||||
pub train_type: Option<TrainType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, Deserialize, EnumString, Copy, Clone)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum TrainType {
|
||||
ICE,
|
||||
IC,
|
||||
ECE,
|
||||
EC,
|
||||
RE,
|
||||
RB,
|
||||
MEX,
|
||||
S,
|
||||
U,
|
||||
BUS,
|
||||
}
|
98
src/model/uic.rs
Normal file
98
src/model/uic.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub(crate) struct UIC {
|
||||
type_code: TypeCode,
|
||||
country_code: CountryCode,
|
||||
national_block: NationalBlock,
|
||||
check: char,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
enum TypeCode {
|
||||
Miscellaneous = 90,
|
||||
ElectricLocomotive = 91,
|
||||
DieselLocomotive = 92,
|
||||
ElectricMultipleUnitHighSpeed = 93,
|
||||
ElectricMultipleUnitLowSpeed = 94,
|
||||
DieselMultipleUnit = 95,
|
||||
SpecialisedTrailer = 96,
|
||||
ElectricShunter = 97,
|
||||
DieselShunter = 98,
|
||||
SpecialVehicle = 99,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
enum CountryCode {
|
||||
Finland = 10,
|
||||
Russia = 20,
|
||||
Belarus = 21,
|
||||
Ukraine = 22,
|
||||
Moldova = 23,
|
||||
Lithuania = 24,
|
||||
Latvia = 25,
|
||||
Estonia = 26,
|
||||
Kazakhstan = 27,
|
||||
Georgia = 28,
|
||||
Uzbekistan = 29,
|
||||
NorthKorea = 30,
|
||||
Mongolia = 31,
|
||||
Vietnam = 32,
|
||||
China = 33,
|
||||
Laos = 34,
|
||||
Cuba = 40,
|
||||
Albania = 41,
|
||||
Japan = 42,
|
||||
SerbRepublicOfBosniaHerzegovina = 44,
|
||||
BosniaHerzegovina = 49,
|
||||
MuslimCroatFederationOfBosniaHerzegovina = 50,
|
||||
Poland = 51,
|
||||
Bulgaria = 52,
|
||||
Romania = 53,
|
||||
CzechRepublic = 54,
|
||||
Hungary = 55,
|
||||
Slovakia = 56,
|
||||
Azerbaijan = 57,
|
||||
Armenia = 58,
|
||||
Kyrgyzstan = 59,
|
||||
Ireland = 60,
|
||||
SouthKorea = 61,
|
||||
Montenegro = 62,
|
||||
NorthMacedonia = 65,
|
||||
Tajikistan = 66,
|
||||
Turkmenistan = 67,
|
||||
Afghanistan = 68,
|
||||
UnitedKingdom = 70,
|
||||
Spain = 71,
|
||||
Serbia = 72,
|
||||
GreeceKingdom = 73,
|
||||
Sweden = 74,
|
||||
Turkey = 75,
|
||||
Norway = 76,
|
||||
Croatia = 78,
|
||||
Slovenia = 79,
|
||||
Germany = 80,
|
||||
Austria = 81,
|
||||
Luxembourg = 82,
|
||||
Italian = 83,
|
||||
Netherlands = 84,
|
||||
Switzerland = 85,
|
||||
Denmark = 86,
|
||||
France = 87,
|
||||
Belgium = 88,
|
||||
Tanzania = 89,
|
||||
Egypt = 90,
|
||||
Tunesia = 91,
|
||||
Algeria = 92,
|
||||
Marocco = 93,
|
||||
Portugal = 94,
|
||||
Israel = 95,
|
||||
Iran = 96,
|
||||
Syriac = 97,
|
||||
Lebanon = 98,
|
||||
Iraq = 99,
|
||||
}
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
struct NationalBlock {
|
||||
digits: [char; 7],
|
||||
}
|
Reference in New Issue
Block a user