diff --git a/src/server.rs b/src/server.rs index fe6709a..b08d727 100644 --- a/src/server.rs +++ b/src/server.rs @@ -4,11 +4,30 @@ use actix_web::{web, App, Error, HttpResponse, HttpServer}; use futures::Future; use lootalot_db::{DbApi, Pool, QueryResult}; use lootalot_db::{Item, LootManager}; +use lootalot_db as db; use serde::{Deserialize, Serialize}; use std::env; +use std::default; type AppPool = web::Data; +#[derive(Serialize, Deserialize, Debug)] +enum Update { + NoUpdate, + Wealth, + ItemAdded, + ItemRemoved, + ClaimAdded, + ClaimRemoved, +} + +#[derive(Serialize, Deserialize, Debug, Default)] +struct ApiResponse { + value: Option, // The value requested, if any + notify: Option, // A text to notify user, if relevant + updates: Option>, // A list of updates, if any + errors: Option, // A text describing errors, if any +} /// Wraps call to the DbApi and process its result as a async HttpResponse /// /// Provides a convenient way to call the api inside a route definition. Given a connection pool, @@ -33,7 +52,7 @@ type AppPool = web::Data; pub fn db_call(pool: AppPool, query: Q) -> impl Future where J: serde::ser::Serialize + Send + 'static, - Q: Fn(DbConnection) -> QueryResult + Send + 'static, + Q: Fn(DbConnection) -> ApiResponse + Send + 'static, { let conn = pool.get().unwrap(); web::block(move || query(conn)).then(|res| match res { @@ -74,23 +93,54 @@ mod endpoints { } pub fn players_list(pool: AppPool) -> impl Future { - db_call(pool, move |api| api.fetch_players()) + db_call(pool, move |conn| { + let (value, errors) = match db::Players(conn).all() { + Ok(v) => (Some(v), None), + Err(e) => (None, Some(e.to_string())), + }; + ApiResponse { + value, + errors, + ..Default::default() + } + }) } pub fn player_loot( pool: AppPool, player_id: web::Path, ) -> impl Future { - db_call(pool, move |conn| LootManager(&conn, *player_id).all()) + db_call(pool, move |conn| { + let (value, errors) = { + match db::LootManager(&conn, *player_id).all() { + Ok(v) => (Some(v), None), + Err(e) => (None, Some(e.to_string())), + } + }; + ApiResponse { + value, + errors, + ..Default::default() + } + }) } pub fn update_wealth( pool: AppPool, - data: web::Json, + (player, data): (web::Path, web::Json), ) -> impl Future { - db_call(pool, move |api| { - api.as_player(data.player_id) - .update_wealth(data.value_in_gp) + db_call(pool, move |conn| { + let (updates, errors) = + match db::AsPlayer(conn, player) + .update_wealth(data.value_in_gp) { + Ok(w) => (Some(vec![w.as_tuple(),]), None), + Err(e) => (None, Some(e.to_string())), + }; + ApiResponse { + updates, + errors, + ..Default::default() + } }) }