182 lines
5.1 KiB
Rust
182 lines
5.1 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use sqlx::FromRow;
|
|
|
|
use super::{prelude::*, util::PartyError};
|
|
|
|
api_routes!();
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
#[serde(crate = "rocket::serde")]
|
|
pub struct EventOutcome {
|
|
points: HashMap<i64, i64>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, FromRow)]
|
|
#[serde(crate = "rocket::serde")]
|
|
pub struct FreeForAllGame {}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, FromRow)]
|
|
#[serde(crate = "rocket::serde")]
|
|
pub struct TeamGame {}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, FromRow)]
|
|
#[serde(crate = "rocket::serde")]
|
|
pub struct Test {}
|
|
|
|
// # Event
|
|
//
|
|
// An event in which participants can win or lose points
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
#[serde(crate = "rocket::serde")]
|
|
pub enum Event {
|
|
FreeForAllGame(FreeForAllGame),
|
|
TeamGame(TeamGame),
|
|
Test(Test),
|
|
}
|
|
|
|
pub struct EventRecord {
|
|
id: i64,
|
|
name: String,
|
|
event_type: String,
|
|
event_id: i64,
|
|
}
|
|
|
|
macro_rules! dispatch {
|
|
($event:ident) => {
|
|
dispatch!($event,
|
|
free_for_all_game => FreeForAllGame,
|
|
team_game => TeamGame,
|
|
test => Test,
|
|
)
|
|
};
|
|
($event:ident, $($event_type:ident => $event_struct:ident),* $(,)?) => {
|
|
match $event.event_type.as_str() {
|
|
$(stringify!($event_type) => dispatch_run!($event_type, $event_struct),)*
|
|
_ => return Err(PartyError::Unknown("invalid event type".into())),
|
|
}
|
|
};
|
|
}
|
|
|
|
macro_rules! reverse_dispatch {
|
|
($event:ident) => {
|
|
reverse_dispatch!($event,
|
|
FreeForAllGame => free_for_all_game,
|
|
TeamGame => team_game,
|
|
Test => test,
|
|
)
|
|
};
|
|
($event:ident, $($event_struct:ident => $event_type:ident),* $(,)?) => {
|
|
match $event {
|
|
$(Event::$event_struct(e) => reverse_dispatch_run!($event_type, $event_struct, e),)*
|
|
}
|
|
};
|
|
}
|
|
|
|
impl EventRecord {
|
|
pub async fn get(db: &mut Connection<Db>, id: i64) -> Result<Self, PartyError> {
|
|
Ok(sqlx::query_as!(
|
|
EventRecord,
|
|
"SELECT id, name, event_type, event_id FROM events WHERE id = ?",
|
|
id
|
|
)
|
|
.fetch_one(&mut **db)
|
|
.await?)
|
|
}
|
|
|
|
pub async fn remove(&self, db: &mut Connection<Db>) -> Result<(), PartyError> {
|
|
macro_rules! dispatch_run {
|
|
($event_type:ident, $event_struct:ident) => {{
|
|
sqlx::query(&format!(
|
|
"DELETE FROM events_{} WHERE id = {}",
|
|
stringify!($event_type),
|
|
self.event_id
|
|
))
|
|
.fetch_one(&mut **db)
|
|
.await?;
|
|
}};
|
|
}
|
|
|
|
dispatch!(self);
|
|
|
|
sqlx::query!("DELETE FROM events WHERE id = ?", self.id)
|
|
.execute(&mut **db)
|
|
.await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Event {
|
|
pub async fn register(
|
|
&self,
|
|
db: &mut Connection<Db>,
|
|
name: String,
|
|
) -> Result<EventRecord, PartyError> {
|
|
let event_id = match self {
|
|
Self::FreeForAllGame(e) => {
|
|
unimplemented!()
|
|
/*
|
|
sqlx::query!("INSERT INTO events_free_for_all_game () VALUES ()")
|
|
.execute(&mut **db)
|
|
.await?
|
|
.last_insert_rowid()
|
|
*/
|
|
}
|
|
Self::TeamGame(e) => {
|
|
unimplemented!()
|
|
/*
|
|
sqlx::query!("INSERT INTO events_team_game () VALUES ()")
|
|
.execute(&mut **db)
|
|
.await?
|
|
.last_insert_rowid()
|
|
*/
|
|
}
|
|
Self::Test(e) => sqlx::query!("INSERT INTO events_test () VALUES ()")
|
|
.execute(&mut **db)
|
|
.await?
|
|
.last_insert_rowid(),
|
|
};
|
|
|
|
macro_rules! reverse_dispatch_run {
|
|
($event_type:ident, $event_struct:ident, $inner:ident) => {
|
|
sqlx::query!(
|
|
"INSERT INTO events (name, event_type, event_id) VALUES (?, ?, ?)",
|
|
stringify!($event_type),
|
|
name,
|
|
event_id
|
|
)
|
|
.execute(&mut **db)
|
|
.await?
|
|
};
|
|
}
|
|
|
|
let id = reverse_dispatch!(self).last_insert_rowid();
|
|
Ok(EventRecord::get(db, id).await?)
|
|
}
|
|
|
|
pub async fn get(db: &mut Connection<Db>, record: EventRecord) -> Result<Self, PartyError> {
|
|
macro_rules! dispatch_run {
|
|
($event_type:ident, $event_struct:ident) => {
|
|
Event::$event_struct(
|
|
sqlx::query_as::<_, $event_struct>(&format!(
|
|
"SELECT id, name, event_type, event_id FROM events_{} WHERE id = {}",
|
|
stringify!($event_type),
|
|
record.event_id
|
|
))
|
|
.fetch_one(&mut **db)
|
|
.await?,
|
|
)
|
|
};
|
|
}
|
|
|
|
Ok(dispatch!(record))
|
|
}
|
|
}
|
|
|
|
#[openapi(tag = "Event")]
|
|
#[post("/<id>/stop")]
|
|
pub fn stop_event(id: i64) -> Result<Json<EventOutcome>, PartyError> {
|
|
todo!()
|
|
}
|