A api/src/actions/game/all_forming.rs => api/src/actions/game/all_forming.rs +14 -0
@@ 0,0 1,14 @@
+/*
+ * This file is part of laurelin/api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use diesel::PgConnection;
+use laurelin_shared::error::api::APIError;
+
+pub(crate) fn all_forming(conn: &mut PgConnection) -> Result<(), APIError> {
+ Err(APIError::Undefined)
+}
A api/src/actions/game/create.rs => api/src/actions/game/create.rs +53 -0
@@ 0,0 1,53 @@
+/*
+ * This file is part of laurelin/api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl};
+use laurelin_shared::error::api::APIError;
+use uuid::Uuid;
+
+use crate::{
+ models::{Game, GameData, InsertableGame, InsertableGameData},
+ schema::{gamedata, games},
+};
+
+pub(crate) fn create(conn: &mut PgConnection, user_id: &str) -> Result<Game, APIError> {
+ let new_gamedata = InsertableGameData {
+ turn: 0,
+ host_hand: None,
+ host_deck: None,
+ guest_hand: None,
+ guest_deck: None,
+ };
+
+ let gamedata: GameData = match diesel::insert_into(gamedata::table)
+ .values(&new_gamedata)
+ .get_result::<GameData>(conn)
+ {
+ Err(_) => return Err(APIError::Undefined), // TODO: new error variant
+ Ok(gamedata) => gamedata,
+ };
+
+ let new_game = InsertableGame {
+ // TODO: handle unwrap
+ host_id: Uuid::parse_str(user_id).unwrap(),
+ guest_id: None,
+ state: 0,
+ ended_at: None,
+ game_data_id: gamedata.id,
+ };
+
+ let game: Game = match diesel::insert_into(games::table)
+ .values(&new_game)
+ .get_result::<Game>(conn)
+ {
+ Err(_) => return Err(APIError::Undefined), // TODO: new error variant
+ Ok(game) => game,
+ };
+
+ Ok(game)
+}
A api/src/actions/game/info.rs => api/src/actions/game/info.rs +14 -0
@@ 0,0 1,14 @@
+/*
+ * This file is part of laurelin/api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use diesel::PgConnection;
+use laurelin_shared::error::api::APIError;
+
+pub(crate) fn info(conn: &mut PgConnection) -> Result<(), APIError> {
+ Err(APIError::Undefined)
+}
A api/src/actions/game/join.rs => api/src/actions/game/join.rs +14 -0
@@ 0,0 1,14 @@
+/*
+ * This file is part of laurelin/api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use diesel::PgConnection;
+use laurelin_shared::error::api::APIError;
+
+pub(crate) fn join(conn: &mut PgConnection) -> Result<(), APIError> {
+ Err(APIError::Undefined)
+}
A api/src/actions/game/mod.rs => api/src/actions/game/mod.rs +22 -0
@@ 0,0 1,22 @@
+/*
+ * This file is part of laurelin/api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+mod create;
+pub(crate) use create::create;
+
+mod all_forming;
+pub(crate) use all_forming::all_forming;
+
+mod my_games;
+pub(crate) use my_games::my_games;
+
+mod info;
+pub(crate) use info::info;
+
+mod join;
+pub(crate) use join::join;
A api/src/actions/game/my_games.rs => api/src/actions/game/my_games.rs +14 -0
@@ 0,0 1,14 @@
+/*
+ * This file is part of laurelin/api
+ * Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
+ *
+ * Licensed under GPL-3.0-only.
+ * See LICENSE for licensing information.
+ */
+
+use diesel::PgConnection;
+use laurelin_shared::error::api::APIError;
+
+pub(crate) fn my_games(conn: &mut PgConnection) -> Result<(), APIError> {
+ Err(APIError::Undefined)
+}
M api/src/actions/mod.rs => api/src/actions/mod.rs +2 -0
@@ 7,3 7,5 @@
*/
pub(crate) mod user;
+
+pub(crate) mod game;
M api/src/handlers/game/mod.rs => api/src/handlers/game/mod.rs +86 -0
@@ 5,3 5,89 @@
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
*/
+
+use actix_session::Session;
+use actix_web::{get, post, web, HttpResponse, Responder};
+use laurelin_shared::error::api::APIError;
+
+use crate::{actions, session, PgPool};
+
+#[post("/api/game")]
+async fn create(session: Session, pool: web::Data<PgPool>) -> impl Responder {
+ let session_validation = session::validate_session(&session);
+
+ match session_validation {
+ Err(err) => err,
+ Ok(user_id) => {
+ let game_create = web::block(move || {
+ let mut conn = match pool.get() {
+ Err(_) => return Err(APIError::DatabasePoolGetFailed),
+ Ok(conn) => conn,
+ };
+ actions::game::create(&mut conn, &user_id)
+ })
+ .await;
+ match game_create {
+ Err(_err) => {
+ return HttpResponse::InternalServerError().json(APIError::Undefined);
+ }
+ Ok(game_res) => match game_res {
+ Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
+ Ok(game) => HttpResponse::Ok().json(game),
+ },
+ }
+ }
+ }
+}
+
+#[get("/api/game/{id}")]
+async fn info(session: Session, pool: web::Data<PgPool>, id: web::Path<String>) -> impl Responder {
+ let session_validation = session::validate_session(&session);
+
+ match session_validation {
+ Err(err) => err,
+ Ok(user_id) => {
+ //
+ return HttpResponse::Ok().body("INFO");
+ }
+ }
+}
+
+#[post("/api/game/{id}/join")]
+async fn join(session: Session, pool: web::Data<PgPool>, id: web::Path<String>) -> impl Responder {
+ let session_validation = session::validate_session(&session);
+
+ match session_validation {
+ Err(err) => err,
+ Ok(user_id) => {
+ //
+ return HttpResponse::Ok().body("JOIN");
+ }
+ }
+}
+
+#[get("/api/game/all_forming")]
+async fn all_forming(session: Session, pool: web::Data<PgPool>) -> impl Responder {
+ let session_validation = session::validate_session(&session);
+
+ match session_validation {
+ Err(err) => err,
+ Ok(user_id) => {
+ //
+ return HttpResponse::Ok().body("ALL_FORMING");
+ }
+ }
+}
+
+#[get("/api/game/my_games")]
+async fn my_games(session: Session, pool: web::Data<PgPool>) -> impl Responder {
+ let session_validation = session::validate_session(&session);
+
+ match session_validation {
+ Err(err) => err,
+ Ok(user_id) => {
+ //
+ return HttpResponse::Ok().body("MY_GAMES");
+ }
+ }
+}
M api/src/main.rs => api/src/main.rs +8 -0
@@ 102,6 102,14 @@ async fn main() -> std::io::Result<()> {
.service(handlers::user::create)
.service(handlers::user::login)
.service(handlers::user::logout)
+ .service(handlers::game::create)
+ .service(handlers::game::all_forming)
+ .service(handlers::game::my_games)
+ // NOTE: these have to be registered last!
+ // otherwise the positional {id} will catch
+ // things like "all_forming"
+ .service(handlers::game::info)
+ .service(handlers::game::join)
})
.bind(("0.0.0.0", 8080))?
.run()