2022-08-29 17:17:31 +02:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
use futures::TryStreamExt;
|
|
|
|
use rocket::serde::json::json;
|
|
|
|
use rocket_db_pools::mongodb::{bson::to_bson, options::InsertOneOptions};
|
|
|
|
use serde_json::Value;
|
2022-08-29 17:17:31 +02:00
|
|
|
|
|
|
|
use super::{prelude::*, util::PartyError};
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
api_routes!(
|
|
|
|
create_event,
|
|
|
|
stop_event,
|
|
|
|
get_event,
|
|
|
|
update_event,
|
|
|
|
get_all_events,
|
|
|
|
event_outcome,
|
|
|
|
);
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)]
|
2022-08-29 17:17:31 +02:00
|
|
|
#[serde(crate = "rocket::serde")]
|
|
|
|
pub struct EventOutcome {
|
2022-08-29 20:08:16 +02:00
|
|
|
points: HashMap<String, i64>,
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Event
|
|
|
|
///
|
|
|
|
/// An event in which participants can win or lose points
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
2022-08-29 17:17:31 +02:00
|
|
|
#[serde(crate = "rocket::serde")]
|
2022-08-29 20:08:16 +02:00
|
|
|
pub struct Event {
|
|
|
|
/// Unique identifier of the event. This will be randomly generated and cannot be modified.
|
|
|
|
#[serde(default = "uuid")]
|
|
|
|
id: String,
|
|
|
|
/// Has this event concluded?
|
|
|
|
concluded: bool,
|
|
|
|
/// Event type
|
|
|
|
event_type: EventType,
|
|
|
|
}
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
impl Event {
|
|
|
|
pub fn outcome(&self) -> EventOutcome {
|
|
|
|
match self.event_type {
|
|
|
|
_ => EventOutcome::default(),
|
|
|
|
}
|
|
|
|
}
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
pub fn conclude(&self) {}
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
fn uuid() -> String {
|
|
|
|
uuid::Uuid::new_v4().to_string()
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # EventType
|
|
|
|
///
|
|
|
|
/// Enumeration of all different types of events
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
|
|
|
#[serde(crate = "rocket::serde")]
|
|
|
|
pub enum EventType {
|
|
|
|
FreeForAllGame {},
|
|
|
|
TeamGame {},
|
|
|
|
Test {},
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Create event
|
|
|
|
///
|
|
|
|
/// If an `id` is supplied, it will be replaced by a randomly generated
|
|
|
|
/// one.
|
|
|
|
///
|
|
|
|
/// Returns the created event. #[openapi(tag = "Event")]
|
|
|
|
#[openapi(tag = "Event")]
|
|
|
|
#[post("/", data = "<event>")]
|
|
|
|
pub async fn create_event(
|
|
|
|
_api_key: ApiKey,
|
|
|
|
db: Connection<Db>,
|
|
|
|
mut event: Json<Event>,
|
|
|
|
) -> Result<Json<Event>, PartyError> {
|
|
|
|
event.id = uuid();
|
|
|
|
event.concluded = false;
|
|
|
|
db.events().insert_one(&*event, None).await?;
|
|
|
|
Ok(event)
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Update event
|
|
|
|
///
|
|
|
|
/// Update the supplied values in the event with the given id. The `id` of an event cannot be
|
|
|
|
/// changed and `concluded` will always be false.
|
|
|
|
#[openapi(tag = "Event")]
|
|
|
|
#[post("/<id>", data = "<event>")]
|
|
|
|
pub async fn update_event(
|
|
|
|
_api_key: ApiKey,
|
|
|
|
db: Connection<Db>,
|
|
|
|
id: String,
|
|
|
|
mut event: Json<Value>, // Use serde_json::Value to allow a partial struct
|
|
|
|
) -> Result<Status, PartyError> {
|
|
|
|
if let Some(i) = event.get_mut("id") {
|
|
|
|
*i = json! { &id };
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
2022-08-29 20:08:16 +02:00
|
|
|
if let Some(i) = event.get_mut("concluded") {
|
|
|
|
*i = json! { false };
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
2022-08-29 20:08:16 +02:00
|
|
|
db.users()
|
|
|
|
.update_one(doc! { "id": &id }, doc! { "$set": to_bson(&*event)? }, None)
|
|
|
|
.await?;
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
Ok(Status::Ok)
|
|
|
|
}
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Get event
|
|
|
|
///
|
|
|
|
/// Returns the event with the given id
|
|
|
|
#[openapi(tag = "Event")]
|
|
|
|
#[get("/<id>")]
|
|
|
|
pub async fn get_event(
|
|
|
|
_api_key: ApiKey,
|
|
|
|
db: Connection<Db>,
|
|
|
|
id: String,
|
|
|
|
) -> Result<Json<Event>, PartyError> {
|
|
|
|
Ok(Json(
|
|
|
|
db.events()
|
|
|
|
.find_one(doc! { "id": &id }, None)
|
|
|
|
.await?
|
|
|
|
.ok_or(PartyError::EventNotFound(id))?,
|
|
|
|
))
|
|
|
|
}
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Get events
|
|
|
|
///
|
|
|
|
/// Returns the event with the given id
|
|
|
|
#[openapi(tag = "Event")]
|
|
|
|
#[get("/")]
|
|
|
|
pub async fn get_all_events(
|
|
|
|
_api_key: ApiKey,
|
|
|
|
db: Connection<Db>,
|
|
|
|
) -> Result<Json<Vec<Event>>, PartyError> {
|
|
|
|
Ok(Json(
|
|
|
|
db.events().find(doc! {}, None).await?.try_collect().await?,
|
|
|
|
))
|
|
|
|
}
|
2022-08-29 17:17:31 +02:00
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Get outcome
|
|
|
|
///
|
|
|
|
/// Returns the outcome of a concluded event.
|
|
|
|
#[openapi(tag = "Event")]
|
|
|
|
#[get("/<id>/outcome")]
|
|
|
|
pub async fn event_outcome(
|
|
|
|
_api_key: ApiKey,
|
|
|
|
db: Connection<Db>,
|
|
|
|
id: String,
|
|
|
|
) -> Result<Json<EventOutcome>, PartyError> {
|
|
|
|
let event = db
|
|
|
|
.events()
|
|
|
|
.find_one(doc! { "id": &id }, None)
|
|
|
|
.await?
|
|
|
|
.ok_or(PartyError::EventNotFound(id.clone()))?;
|
|
|
|
Ok(Json(event.outcome()))
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 20:08:16 +02:00
|
|
|
/// # Stop event
|
2022-08-29 17:17:31 +02:00
|
|
|
#[openapi(tag = "Event")]
|
|
|
|
#[post("/<id>/stop")]
|
2022-08-29 20:08:16 +02:00
|
|
|
pub async fn stop_event(
|
|
|
|
_api_key: ApiKey,
|
|
|
|
db: Connection<Db>,
|
|
|
|
id: String,
|
|
|
|
) -> Result<Json<EventOutcome>, PartyError> {
|
|
|
|
let event = db
|
|
|
|
.events()
|
|
|
|
.find_one(doc! { "id": &id }, None)
|
|
|
|
.await?
|
|
|
|
.ok_or(PartyError::EventNotFound(id.clone()))?;
|
|
|
|
event.conclude();
|
|
|
|
db.users()
|
|
|
|
.update_one(doc! { "id": &id }, doc! { "concluded": true }, None)
|
|
|
|
.await?;
|
|
|
|
Ok(Json(event.outcome()))
|
2022-08-29 17:17:31 +02:00
|
|
|
}
|