try out a generic ApiResponse

This commit is contained in:
2019-10-15 16:22:46 +02:00
parent 6101aaa9e9
commit 8af7790d17

View File

@@ -4,11 +4,30 @@ use actix_web::{web, App, Error, HttpResponse, HttpServer};
use futures::Future; use futures::Future;
use lootalot_db::{DbApi, Pool, QueryResult}; use lootalot_db::{DbApi, Pool, QueryResult};
use lootalot_db::{Item, LootManager}; use lootalot_db::{Item, LootManager};
use lootalot_db as db;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::env; use std::env;
use std::default;
type AppPool = web::Data<Pool>; type AppPool = web::Data<Pool>;
#[derive(Serialize, Deserialize, Debug)]
enum Update {
NoUpdate,
Wealth,
ItemAdded,
ItemRemoved,
ClaimAdded,
ClaimRemoved,
}
#[derive(Serialize, Deserialize, Debug, Default)]
struct ApiResponse<T> {
value: Option<T>, // The value requested, if any
notify: Option<String>, // A text to notify user, if relevant
updates: Option<Vec<Update>>, // A list of updates, if any
errors: Option<String>, // A text describing errors, if any
}
/// Wraps call to the DbApi and process its result as a async HttpResponse /// 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, /// Provides a convenient way to call the api inside a route definition. Given a connection pool,
@@ -33,7 +52,7 @@ type AppPool = web::Data<Pool>;
pub fn db_call<J, Q>(pool: AppPool, query: Q) -> impl Future<Item = HttpResponse, Error = Error> pub fn db_call<J, Q>(pool: AppPool, query: Q) -> impl Future<Item = HttpResponse, Error = Error>
where where
J: serde::ser::Serialize + Send + 'static, J: serde::ser::Serialize + Send + 'static,
Q: Fn(DbConnection) -> QueryResult<J> + Send + 'static, Q: Fn(DbConnection) -> ApiResponse<J> + Send + 'static,
{ {
let conn = pool.get().unwrap(); let conn = pool.get().unwrap();
web::block(move || query(conn)).then(|res| match res { web::block(move || query(conn)).then(|res| match res {
@@ -74,23 +93,54 @@ mod endpoints {
} }
pub fn players_list(pool: AppPool) -> impl Future<Item = HttpResponse, Error = Error> { pub fn players_list(pool: AppPool) -> impl Future<Item = HttpResponse, Error = Error> {
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( pub fn player_loot(
pool: AppPool, pool: AppPool,
player_id: web::Path<i32>, player_id: web::Path<i32>,
) -> impl Future<Item = HttpResponse, Error = Error> { ) -> impl Future<Item = HttpResponse, Error = Error> {
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( pub fn update_wealth(
pool: AppPool, pool: AppPool,
data: web::Json<WealthUpdate>, (player, data): (web::Path<i32>, web::Json<WealthUpdate>),
) -> impl Future<Item = HttpResponse, Error = Error> { ) -> impl Future<Item = HttpResponse, Error = Error> {
db_call(pool, move |api| { db_call(pool, move |conn| {
api.as_player(data.player_id) let (updates, errors) =
.update_wealth(data.value_in_gp) 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()
}
}) })
} }