DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

388ed83bc15216d9b63712cf70482727c0e1a445 — Jonni Liljamo 1 year, 9 months ago 8db41b3
chore(client, server, api, shared): fix clippy lints
M api/src/actions/game/info.rs => api/src/actions/game/info.rs +1 -1
@@ 9,6 9,6 @@
use diesel::PgConnection;
use laurelin_shared::error::api::APIError;

pub(crate) fn info(conn: &mut PgConnection) -> Result<(), APIError> {
pub(crate) fn info(_conn: &mut PgConnection) -> Result<(), APIError> {
    Err(APIError::Undefined)
}

M api/src/actions/game/join.rs => api/src/actions/game/join.rs +1 -1
@@ 9,6 9,6 @@
use diesel::PgConnection;
use laurelin_shared::error::api::APIError;

pub(crate) fn join(conn: &mut PgConnection) -> Result<(), APIError> {
pub(crate) fn join(_conn: &mut PgConnection) -> Result<(), APIError> {
    Err(APIError::Undefined)
}

M api/src/actions/user/create.rs => api/src/actions/user/create.rs +2 -2
@@ 50,8 50,8 @@ pub(crate) fn create(conn: &mut PgConnection, user: &InsertableUser) -> Result<U
    match user {
        Err(_) => {
            // TODO: we certainly could handle Diesel errors here...
            return Err(APIError::UserCreationFailed);
            Err(APIError::UserCreationFailed)
        }
        Ok(u) => return Ok(u),
        Ok(u) => Ok(u),
    }
}

M api/src/handlers/game/mod.rs => api/src/handlers/game/mod.rs +18 -16
@@ 28,9 28,7 @@ async fn create(session: Session, pool: web::Data<PgPool>) -> impl Responder {
            })
            .await;
            match game_create {
                Err(_err) => {
                    return HttpResponse::InternalServerError().json(APIError::Undefined);
                }
                Err(_err) => 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),


@@ 41,27 39,35 @@ async fn create(session: Session, pool: web::Data<PgPool>) -> impl Responder {
}

#[get("/api/game/{id}")]
async fn info(session: Session, pool: web::Data<PgPool>, id: web::Path<String>) -> impl Responder {
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) => {
        Ok(_user_id) => {
            //
            return HttpResponse::Ok().body("INFO");
            HttpResponse::Ok().body("INFO")
        }
    }
}

#[post("/api/game/{id}/join")]
async fn join(session: Session, pool: web::Data<PgPool>, id: web::Path<String>) -> impl Responder {
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) => {
        Ok(_user_id) => {
            //
            return HttpResponse::Ok().body("JOIN");
            HttpResponse::Ok().body("JOIN")
        }
    }
}


@@ 72,7 78,7 @@ async fn all_forming(session: Session, pool: web::Data<PgPool>) -> impl Responde

    match session_validation {
        Err(err) => err,
        Ok(user_id) => {
        Ok(_user_id) => {
            let all_forming = web::block(move || {
                let mut conn = match pool.get() {
                    Err(_) => return Err(APIError::DatabasePoolGetFailed),


@@ 82,9 88,7 @@ async fn all_forming(session: Session, pool: web::Data<PgPool>) -> impl Responde
            })
            .await;
            match all_forming {
                Err(_err) => {
                    return HttpResponse::InternalServerError().json(APIError::Undefined);
                }
                Err(_err) => HttpResponse::InternalServerError().json(APIError::Undefined),
                Ok(games_res) => match games_res {
                    Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
                    Ok(games) => HttpResponse::Ok().json(games),


@@ 110,9 114,7 @@ async fn my_games(session: Session, pool: web::Data<PgPool>) -> impl Responder {
            })
            .await;
            match my_games {
                Err(_err) => {
                    return HttpResponse::InternalServerError().json(APIError::Undefined);
                }
                Err(_err) => HttpResponse::InternalServerError().json(APIError::Undefined),
                Ok(games_res) => match games_res {
                    Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
                    Ok(games) => HttpResponse::Ok().json(games),

M api/src/handlers/user/create.rs => api/src/handlers/user/create.rs +2 -4
@@ 44,12 44,10 @@ pub(crate) async fn create(
    match user_create {
        Err(_err) => {
            // TODO: handle?
            return HttpResponse::InternalServerError().json(APIError::Undefined);
            HttpResponse::InternalServerError().json(APIError::Undefined)
        }
        Ok(user_res) => match user_res {
            Err(err) => {
                return HttpResponse::InternalServerError().json(err);
            }
            Err(err) => HttpResponse::InternalServerError().json(err),
            Ok(user) => match session.insert("user_id", user.id) {
                Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
                Ok(_) => HttpResponse::Ok().json(user),

M api/src/handlers/user/info.rs => api/src/handlers/user/info.rs +1 -3
@@ 32,9 32,7 @@ pub(crate) async fn info(
            })
            .await;
            match user_details {
                Err(_err) => {
                    return HttpResponse::InternalServerError().json(APIError::Undefined);
                }
                Err(_err) => HttpResponse::InternalServerError().json(APIError::Undefined),
                Ok(user_details_res) => match user_details_res {
                    Err(err) => HttpResponse::InternalServerError().body(err.to_string()),
                    Ok(user_details) => HttpResponse::Ok().json(user_details),

M client/src/main.rs => client/src/main.rs +2 -0
@@ 6,6 6,8 @@
 * See LICENSE for licensing information.
 */

#![allow(clippy::too_many_arguments)]

use bevy::{
    app::AppExit,
    prelude::*,

M client/src/plugins/menu/ui/play/ui.rs => client/src/plugins/menu/ui/play/ui.rs +134 -89
@@ 8,7 8,10 @@

use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts};
use laurelin_shared::types::game::{GAMESTATE_FINISHED, GAMESTATE_INPROGRESS};
use laurelin_shared::types::{
    game::{GAMESTATE_FINISHED, GAMESTATE_INPROGRESS},
    user::UserPub,
};

use crate::{
    cfg::CfgUser,


@@ 17,6 20,7 @@ use crate::{
        networking::send::game::{GameAllFormingEvent, GameCreateEvent, GameMyGamesEvent},
    },
    util::egui::menuwindow,
    Global,
};

use super::{PlayScreenBrowseState, PlayScreenData, PlayScreenState};


@@ 26,6 30,7 @@ pub fn ui(
    mut egui_contexts: EguiContexts,
    mut data: ResMut<PlayScreenData>,
    cfg_user: Res<CfgUser>,
    global: Res<Global>,
    mut creategame_ev_w: EventWriter<GameCreateEvent>,
    mut allforming_ev_w: EventWriter<GameAllFormingEvent>,
    mut mygames_ev_w: EventWriter<GameMyGamesEvent>,


@@ 100,15 105,15 @@ pub fn ui(
                    });

                ui.vertical_centered(|ui| {
                    egui::ScrollArea::vertical().show(ui, |mut ui| match data.browse_state {
                    egui::ScrollArea::vertical().show(ui, |ui| match data.browse_state {
                        PlayScreenBrowseState::Forming => {
                            browse_forming(&mut ui, &mut data, &cfg_user);
                            browse_forming(ui, &mut data, &cfg_user, &global);
                        }
                        PlayScreenBrowseState::InProgress => {
                            browse_inprogress(&mut ui, &mut data);
                            browse_inprogress(ui, &mut data, &global);
                        }
                        PlayScreenBrowseState::Finished => {
                            browse_finished(&mut ui, &mut data);
                            browse_finished(ui, &mut data, &global);
                        }
                    });
                });


@@ 150,123 155,163 @@ pub fn ui(
    );
}

fn browse_forming(ui: &mut egui::Ui, data: &mut PlayScreenData, cfg_user: &CfgUser) {
fn browse_forming(
    ui: &mut egui::Ui,
    data: &mut PlayScreenData,
    cfg_user: &CfgUser,
    global: &Global,
) {
    if data.waiting_for_all_forming {
        ui.horizontal(|ui| {
            ui.spinner();
            ui.label("loading...");
        });
        return;
    }

    if data.all_forming.is_empty() {
        ui.label("No forming games found.");
    } else {
        if data.all_forming.is_empty() {
            ui.label("No forming games found.");
        } else {
            for game in data.all_forming.clone() {
                egui::Frame::none()
                    .fill(egui::Color32::BLACK)
                    .rounding(4.)
                    .outer_margin(4.)
                    .inner_margin(4.)
                    .show(ui, |ui| {
                        ui.horizontal(|ui| {
                            //ui.label(format!("Host: {}", game.host.username));
                            ui.label("Host: host-username-here");
                            ui.with_layout(
                                egui::Layout::right_to_left(egui::Align::Center),
                                |ui| {
                                    if game.guest_id.clone().unwrap_or_default().to_string()
                                        == cfg_user.id
                                    {
                                        ui.add_enabled(false, egui::Button::new("Joined"));
                                        if ui.button("Inspect").clicked() {
                                            data.cur_game = Some(game.clone());
                                            data.state = PlayScreenState::InLobbyGuest;
                                        }
                                    } else if game.host_id.to_string() == cfg_user.id {
                                        ui.add_enabled(false, egui::Button::new("Host"));
                                        if ui.button("Inspect").clicked() {
                                            data.cur_game = Some(game.clone());
                                            data.state = PlayScreenState::InLobbyHost;
                                        }
                                    } else {
                                        if ui.button("Join").clicked() {
                                            //data.cur_game = Some(game.clone());
                                            //joingame_ev_w.send(JoinGameEvent);
                                        }
                                    }
                                },
                            );
        for game in data.all_forming.clone() {
            egui::Frame::none()
                .fill(egui::Color32::BLACK)
                .rounding(4.)
                .outer_margin(4.)
                .inner_margin(4.)
                .show(ui, |ui| {
                    ui.horizontal(|ui| {
                        ui.label(format!(
                            "Host: {}",
                            global
                                .users_cache
                                .iter()
                                .filter(|u| u.id == game.host_id)
                                .cloned()
                                .collect::<Vec<UserPub>>()
                                .first()
                                .unwrap_or(&UserPub {
                                    id: "".to_string(),
                                    created_at: "".to_string(),
                                    username: "".to_string()
                                })
                                .username
                        ));
                        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                            if game.guest_id.clone().unwrap_or_default() == cfg_user.id {
                                ui.add_enabled(false, egui::Button::new("Joined"));
                                if ui.button("Inspect").clicked() {
                                    data.cur_game = Some(game.clone());
                                    data.state = PlayScreenState::InLobbyGuest;
                                }
                            } else if game.host_id == cfg_user.id {
                                ui.add_enabled(false, egui::Button::new("Host"));
                                if ui.button("Inspect").clicked() {
                                    data.cur_game = Some(game.clone());
                                    data.state = PlayScreenState::InLobbyHost;
                                }
                            } else if ui.button("Join").clicked() {
                                //data.cur_game = Some(game.clone());
                                //joingame_ev_w.send(JoinGameEvent);
                            }
                        });
                    });
            }
                });
        }
    }
}

fn browse_inprogress(ui: &mut egui::Ui, data: &mut PlayScreenData) {
fn browse_inprogress(ui: &mut egui::Ui, data: &mut PlayScreenData, global: &Global) {
    if data.waiting_for_my_games {
        ui.horizontal(|ui| {
            ui.spinner();
            ui.label("loading...");
        });
        return;
    }

    if data.my_games.is_empty() {
        ui.label("No games found.");
    } else {
        if data.my_games.is_empty() {
            ui.label("No games found.");
        } else {
            let mut games = data.my_games.clone();
            games.retain(|g| g.state == GAMESTATE_INPROGRESS);
        let mut games = data.my_games.clone();
        games.retain(|g| g.state == GAMESTATE_INPROGRESS);

            for game in games {
                egui::Frame::none()
                    .fill(egui::Color32::BLACK)
                    .rounding(4.)
                    .outer_margin(4.)
                    .inner_margin(4.)
                    .show(ui, |ui| {
                        ui.horizontal(|ui| {
                            //ui.label(format!("Host: {}", game.host.username));
                            ui.label("Host: host-username-here");
                            ui.with_layout(
                                egui::Layout::right_to_left(egui::Align::Center),
                                |ui| {
                                    if ui.button("Resume").clicked() {
                                        data.cur_game = Some(game.clone());
                                        //resumegame_ev_w.send(ResumeGameEvent);
                                    }
                                },
                            );
        for game in games {
            egui::Frame::none()
                .fill(egui::Color32::BLACK)
                .rounding(4.)
                .outer_margin(4.)
                .inner_margin(4.)
                .show(ui, |ui| {
                    ui.horizontal(|ui| {
                        ui.label(format!(
                            "Host: {}",
                            global
                                .users_cache
                                .iter()
                                .filter(|u| u.id == game.host_id)
                                .cloned()
                                .collect::<Vec<UserPub>>()
                                .first()
                                .unwrap_or(&UserPub {
                                    id: "".to_string(),
                                    created_at: "".to_string(),
                                    username: "".to_string()
                                })
                                .username
                        ));
                        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
                            if ui.button("Resume").clicked() {
                                data.cur_game = Some(game.clone());
                                //resumegame_ev_w.send(ResumeGameEvent);
                            }
                        });
                    });
            }
                });
        }
    }
}

fn browse_finished(ui: &mut egui::Ui, data: &mut PlayScreenData) {
fn browse_finished(ui: &mut egui::Ui, data: &mut PlayScreenData, global: &Global) {
    if data.waiting_for_my_games {
        ui.horizontal(|ui| {
            ui.spinner();
            ui.label("loading...");
        });
        return;
    }

    if data.my_games.is_empty() {
        ui.label("No games found.");
    } else {
        if data.my_games.is_empty() {
            ui.label("No games found.");
        } else {
            let mut games = data.my_games.clone();
            games.retain(|g| g.state == GAMESTATE_FINISHED);
        let mut games = data.my_games.clone();
        games.retain(|g| g.state == GAMESTATE_FINISHED);

            for game in games {
                egui::Frame::none()
                    .fill(egui::Color32::BLACK)
                    .rounding(4.)
                    .outer_margin(4.)
                    .inner_margin(4.)
                    .show(ui, |ui| {
                        ui.horizontal(|ui| {
                            ui.label("Host: host-username-here");
                            //ui.label(format!("Host: {}", game.host.username));
                        });
        for game in games {
            egui::Frame::none()
                .fill(egui::Color32::BLACK)
                .rounding(4.)
                .outer_margin(4.)
                .inner_margin(4.)
                .show(ui, |ui| {
                    ui.horizontal(|ui| {
                        ui.label(format!(
                            "Host: {}",
                            global
                                .users_cache
                                .iter()
                                .filter(|u| u.id == game.host_id)
                                .cloned()
                                .collect::<Vec<UserPub>>()
                                .first()
                                .unwrap_or(&UserPub {
                                    id: "".to_string(),
                                    created_at: "".to_string(),
                                    username: "".to_string()
                                })
                                .username
                        ));
                    });
            }
                });
        }
    }
}

M client/src/util/sl.rs => client/src/util/sl.rs +6 -4
@@ 17,10 17,12 @@ pub fn load<T: Default + for<'a> serde::Deserialize<'a>>(target_dir: &str, file_
        true => {
            info!("sl::load found '{}'", file_path);
            let json: Vec<u8> = std::fs::read(file_path.clone()).unwrap();
            serde_json::from_str(std::str::from_utf8(&json).unwrap()).expect(&format!(
                "sl::load couldn't deserialize the config at '{}'",
                file_path
            ))
            serde_json::from_str(std::str::from_utf8(&json).unwrap()).unwrap_or_else(|_| {
                panic!(
                    "sl::load couldn't deserialize the config at '{}'",
                    file_path
                )
            })
        }
        false => {
            warn!("sl::load couldn't find '{}', using defaults", file_path);

M server/src/systems/event/message/mod.rs => server/src/systems/event/message/mod.rs +3 -3
@@ 41,7 41,7 @@ pub(crate) fn message_events(
                DataRequestType::GameCreate => {
                    // TODO: handle
                    let cookie = global.user_to_session_map.get(&user_key).unwrap();
                    let wrapped = create(&config.api_address, &cookie);
                    let wrapped = create(&config.api_address, cookie);
                    let game = match wrapped.response {
                        ResponseCreateGame::Error(_err) => None, // TODO: handle
                        ResponseCreateGame::Valid(result) => Some(result),


@@ 67,7 67,7 @@ pub(crate) fn message_events(
                DataRequestType::GameAllForming => {
                    // TODO: handle
                    let cookie = global.user_to_session_map.get(&user_key).unwrap();
                    let wrapped = all_forming(&config.api_address, &cookie);
                    let wrapped = all_forming(&config.api_address, cookie);
                    let games = match wrapped.response {
                        ResponseAllForming::Error(_err) => vec![], // TODO: handle
                        ResponseAllForming::Valid(result) => result,


@@ 93,7 93,7 @@ pub(crate) fn message_events(
                DataRequestType::GameMyGames => {
                    // TODO: handle
                    let cookie = global.user_to_session_map.get(&user_key).unwrap();
                    let wrapped = my_games(&config.api_address, &cookie);
                    let wrapped = my_games(&config.api_address, cookie);
                    let games = match wrapped.response {
                        ResponseMyGames::Error(_err) => vec![], // TODO: handle
                        ResponseMyGames::Valid(result) => result,

M server/src/systems/event/mod.rs => server/src/systems/event/mod.rs +2 -2
@@ 84,7 84,7 @@ pub(crate) fn connect_events(
        // TODO: handle
        let aa_details = temp.afterauth_details.get(user_key).unwrap();
        server.send_message::<AfterAuthChannel, AfterAuth>(
            &user_key,
            user_key,
            &AfterAuth {
                id: aa_details.0.id.to_string().clone(),
                username: aa_details.0.username.clone(),


@@ 96,7 96,7 @@ pub(crate) fn connect_events(
            .user_to_session_map
            .insert(*user_key, aa_details.1.clone());

        temp.afterauth_details.remove(&user_key);
        temp.afterauth_details.remove(user_key);
    }
}


M shared/src/api/mod.rs => shared/src/api/mod.rs +1 -1
@@ 23,7 23,7 @@ pub struct APIInfo {
pub fn info(api_address: String) -> Result<APIInfo, String> {
    let client = reqwest::blocking::Client::new();

    let resp = client.get(&format!("{}/info", api_address)).send();
    let resp = client.get(format!("{}/info", api_address)).send();
    match resp {
        Ok(r) => Ok(r.json().unwrap()),
        Err(_) => Err("Could not reach API".to_string()),

M shared/src/types/game.rs => shared/src/types/game.rs +2 -14
@@ 53,21 53,9 @@ impl GamePub {
            created_at: game.created_at.to_string(),
            updated_at: game.updated_at.to_string(),
            host_id: game.host_id.to_string(),
            guest_id: {
                if let Some(guest_id) = game.guest_id {
                    Some(guest_id.to_string())
                } else {
                    None
                }
            },
            guest_id: { game.guest_id.map(|guest_id| guest_id.to_string()) },
            state: game.state,
            ended_at: {
                if let Some(ended_at) = game.ended_at {
                    Some(ended_at.to_string())
                } else {
                    None
                }
            },
            ended_at: { game.ended_at.map(|ended_at| ended_at.to_string()) },
            game_data_id: game.game_data_id.to_string(),
        }
    }