From 15a0cdfe722e1cb5a06eef2bfee7fa69de4dca66 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Tue, 14 Mar 2023 21:25:41 +0200 Subject: [PATCH] feat(api): stubs for most game endpoints, complete create --- api/src/actions/game/all_forming.rs | 14 +++++ api/src/actions/game/create.rs | 53 ++++++++++++++++++ api/src/actions/game/info.rs | 14 +++++ api/src/actions/game/join.rs | 14 +++++ api/src/actions/game/mod.rs | 22 ++++++++ api/src/actions/game/my_games.rs | 14 +++++ api/src/actions/mod.rs | 2 + api/src/handlers/game/mod.rs | 86 +++++++++++++++++++++++++++++ api/src/main.rs | 8 +++ 9 files changed, 227 insertions(+) create mode 100644 api/src/actions/game/all_forming.rs create mode 100644 api/src/actions/game/create.rs create mode 100644 api/src/actions/game/info.rs create mode 100644 api/src/actions/game/join.rs create mode 100644 api/src/actions/game/mod.rs create mode 100644 api/src/actions/game/my_games.rs diff --git a/api/src/actions/game/all_forming.rs b/api/src/actions/game/all_forming.rs new file mode 100644 index 0000000..c2a046b --- /dev/null +++ b/api/src/actions/game/all_forming.rs @@ -0,0 +1,14 @@ +/* + * This file is part of laurelin/api + * Copyright (C) 2023 Jonni Liljamo + * + * 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) +} diff --git a/api/src/actions/game/create.rs b/api/src/actions/game/create.rs new file mode 100644 index 0000000..d6cf85c --- /dev/null +++ b/api/src/actions/game/create.rs @@ -0,0 +1,53 @@ +/* + * This file is part of laurelin/api + * Copyright (C) 2023 Jonni Liljamo + * + * 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 { + 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::(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::(conn) + { + Err(_) => return Err(APIError::Undefined), // TODO: new error variant + Ok(game) => game, + }; + + Ok(game) +} diff --git a/api/src/actions/game/info.rs b/api/src/actions/game/info.rs new file mode 100644 index 0000000..6c3e0be --- /dev/null +++ b/api/src/actions/game/info.rs @@ -0,0 +1,14 @@ +/* + * This file is part of laurelin/api + * Copyright (C) 2023 Jonni Liljamo + * + * 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) +} diff --git a/api/src/actions/game/join.rs b/api/src/actions/game/join.rs new file mode 100644 index 0000000..c05a7b4 --- /dev/null +++ b/api/src/actions/game/join.rs @@ -0,0 +1,14 @@ +/* + * This file is part of laurelin/api + * Copyright (C) 2023 Jonni Liljamo + * + * 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) +} diff --git a/api/src/actions/game/mod.rs b/api/src/actions/game/mod.rs new file mode 100644 index 0000000..db2c3ac --- /dev/null +++ b/api/src/actions/game/mod.rs @@ -0,0 +1,22 @@ +/* + * This file is part of laurelin/api + * Copyright (C) 2023 Jonni Liljamo + * + * 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; diff --git a/api/src/actions/game/my_games.rs b/api/src/actions/game/my_games.rs new file mode 100644 index 0000000..6183558 --- /dev/null +++ b/api/src/actions/game/my_games.rs @@ -0,0 +1,14 @@ +/* + * This file is part of laurelin/api + * Copyright (C) 2023 Jonni Liljamo + * + * 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) +} diff --git a/api/src/actions/mod.rs b/api/src/actions/mod.rs index ccf97ae..59716b6 100644 --- a/api/src/actions/mod.rs +++ b/api/src/actions/mod.rs @@ -7,3 +7,5 @@ */ pub(crate) mod user; + +pub(crate) mod game; diff --git a/api/src/handlers/game/mod.rs b/api/src/handlers/game/mod.rs index 4bcd7a7..6033691 100644 --- a/api/src/handlers/game/mod.rs +++ b/api/src/handlers/game/mod.rs @@ -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) -> 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, id: web::Path) -> 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, id: web::Path) -> 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) -> 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) -> impl Responder { + let session_validation = session::validate_session(&session); + + match session_validation { + Err(err) => err, + Ok(user_id) => { + // + return HttpResponse::Ok().body("MY_GAMES"); + } + } +} diff --git a/api/src/main.rs b/api/src/main.rs index ba503f6..46f73f5 100644 --- a/api/src/main.rs +++ b/api/src/main.rs @@ -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() -- 2.44.1