fixes errors

This commit is contained in:
2020-01-09 15:12:51 +01:00
parent f9cd09431d
commit d152a999c9
5 changed files with 128 additions and 386 deletions

View File

@@ -40,7 +40,7 @@ pub struct ApiResponse {
}
impl ApiResponse {
fn push_updates(&mut self, updates: Vec<db::Update>) {
fn push_updates(&mut self, mut updates: Vec<db::Update>) {
if let Some(v) = self.updates.as_mut() {
v.append(&mut updates);
} else {
@@ -48,6 +48,10 @@ impl ApiResponse {
}
}
fn push_update(&mut self, update: db::Update) {
self.push_updates(vec!(update))
}
fn push_error<S: Into<String>>(&mut self, error: S) {
if let Some(errors) = self.errors.as_mut() {
*errors = format!("{}\n{}", errors, error.into());
@@ -70,35 +74,7 @@ pub enum ApiError {
InvalidAction(String),
}
/// Every allowed queries on the database
pub enum ApiActions {
// Application level
FetchPlayers,
FetchInventory,
FetchShopInventory,
FetchClaims,
CheckItemList(Vec<String>),
// Player level
FetchPlayer(i32),
FetchPlayerClaims(i32),
FetchNotifications(i32),
FetchLoot(i32),
UpdateWealth(i32, f64),
BuyItems(i32, BuySellParams),
SellItems(i32, BuySellParams),
ClaimItems(i32, IdList),
UndoLastAction(i32),
// Group level
AddLoot(NewGroupLoot),
// Admin level
RefreshShopInventory(ItemList),
AddPlayer(NewPlayer),
//AddInventoryItem(pub String, pub i32),
//ResolveClaims,
//SetClaimsTimeout(pub i32),
}
pub enum ApiEndpoints {
pub enum ApiEndpoint {
InventoryList,
InventoryCheck(Vec<String>),
InventoryAdd(String, i32), // db::Inventory(conn)::add(new_item)
@@ -124,65 +100,69 @@ pub enum ApiEndpoints {
ResolveClaims, // db::Group(conn)::resolve_claims()
}
static ErrorMsg : &str = "Une erreur est survenue";
static ERROR_MSG : &str = "Une erreur est survenue";
pub fn execute(
conn: &DbConnection,
query: ApiEndpoints,
query: ApiEndpoint,
) -> Result<ApiResponse, diesel::result::Error> {
let mut response = ApiResponse::default();
// Return an Option<String> that describes what happened.
// If there is some value, store the actions in db so that it can be reversed.
let action_text: Option<(i32, &str)> = match query {
// Inventory
ApiEndpoints::FetchInventory => {
ApiEndpoint::InventoryList => {
match db::Inventory(conn).all() {
Ok(items) => response.set_value(Value::ItemList(items)),
Err(_) => response.set_error(ErrorMsg),
Err(_) => response.push_error(ERROR_MSG),
}
None
}
ApiEnpoints::InventoryCheck(names) => {
ApiEndpoint::InventoryCheck(names) => {
match db::Inventory(conn).check_list(names) {
Ok((items, errors)) => {
response.set_value(Value::ItemList(items));
response.push_error(errors);
}
Err(_) => response.set_error(ErrorMsg),
Err(_) => response.push_error(ERROR_MSG),
}
None
}
ApiEndpoints::InventoryAdd((name, value)) => {
response.set_error("Not implemented");
ApiEndpoint::InventoryAdd(name, value) => {
response.push_error("Not implemented");
None
}
//Shop
ApiEnpoints::ShopList => {
ApiEndpoint::ShopList => {
match db::Shop(conn).all() {
Ok(items) => response.set_value(Value::ItemList(items)),
Err(_) => response.set_error(ErrorMsg),
Err(_) => response.push_error(ERROR_MSG),
}
None
}
ApiEndpoints::BuyItems(buyer, params) => {
match db::Shop(conn).buy(params, buyer) {
ApiEndpoint::BuyItems(buyer, params) => {
match db::Shop(conn).buy(params.items, buyer) {
Ok(updates) => {
response.notifiy("Objets achetés !");
response.notify("Objets achetés !");
response.push_updates(updates);
Some((id, "Achat d'objets"))
Some((buyer, "Achat d'objets"))
},
Err(_) => {
response.set_error(ErrorMsg);
response.push_error(ERROR_MSG);
None
}
}
}
// Players
ApiEndpoints::PlayerList => {
ApiEndpoint::PlayerList => {
response.set_value(Value::PlayerList(db::Players(conn).all_except_group()?));
None
}
ApiEndpoint::ClaimList => {
ApiEndpoint::PlayerFetch(id) => {
response.set_value(Value::Player(db::Players(conn).find(id)?));
None
}
ApiEndpoint::ClaimsList => {
response.set_value(Value::ClaimList(db::Claims(conn).all()?));
None
}
@@ -209,16 +189,20 @@ pub fn execute(
// Group sells item like players then split the total amount among players.
ApiEndpoint::SellItems(id, params) => {
conn.transaction(|| -> Result<Option<(i32, &str)>, diesel::result::Error> {
let sold = LootManager(conn, id).sell(params.items)?;
let mut updates = db::LootManager(conn, id).sell(params.items)?;
let total_amount: i32 = updates.iter()
.filter_map(|u| match u {
Update::Wealth(diff) => Some(diff.to_gp() as i32),
_ => None
}).sum();
match id {
0 => {
let players = params.players.unwrap_or_default();
updates.push(
db::split_and_share(conn, total_amount.to_gp() as i32, players)?
updates.append(
&mut db::split_and_share(conn, total_amount, players)?
);
response.notify("Les objets ont été vendus");
response.push_updates(updates);
};
}
_ => {
response.notify("Objets vendus !");
@@ -239,11 +223,11 @@ pub fn execute(
let new_claims: HashSet<i32> = items.into_iter().collect();
// Claims to delete
for item in current_claims.difference(&new_claims) {
response.push_update(db::Claims(conn).remove(id, *item)?);
response.push_updates(db::Claims(conn).remove(id, *item)?);
}
// Claims to add
for item in new_claims.difference(&current_claims) {
response.push_update(db::Claims(conn).add(id, *item)?);
response.push_updates(db::Claims(conn).add(id, *item)?);
}
Ok(None)
})?
@@ -251,9 +235,7 @@ pub fn execute(
ApiEndpoint::UndoLastAction(id) => {
if let Ok(event) = db::models::history::get_last_of_player(conn, id) {
let name = String::from(event.name());
for undone in event.undo(conn)?.into_inner().into_iter() {
response.push_update(undone);
}
event.undo(conn)?;
response.notify(format!("'{}' annulé(e)", name));
} else {
response.push_error("Aucune action trouvée")
@@ -265,7 +247,7 @@ pub fn execute(
let mut added_items = 0;
for item in data.items.into_iter() {
if let Ok(added) = db::LootManager(conn, 0).add_from(&item) {
response.push_update(added);
response.push_updates(added);
added_items += 1;
} else {
response.push_error(format!("Error adding {:?}", item));
@@ -280,17 +262,17 @@ pub fn execute(
};
Some((0, "Nouveau loot"))
}
ApiEndpoints::ResolveClaims => {
ApiEndpoint::ResolveClaims => {
response.push_error("Not implemented!");
None
}
// Admin actions
ApiEndpoints::RefreshShop(items) => {
ApiEndpoint::RefreshShop(items) => {
db::Shop(conn).replace_list(items)?;
response.notify("Inventaire du marchand renouvelé !");
None
}
ApiEnpoints::AddPlayer(data) => {
ApiEndpoint::PlayerAdd(data) => {
db::Players(conn).add(&data.name, data.wealth)?;
response.notify("Joueur ajouté !");
None

View File

@@ -30,7 +30,7 @@ type MaybeForbidden =
/// Wraps call to the database query and convert its result as a async HttpResponse
fn db_call(
pool: AppPool,
query: api::ApiActions,
query: api::ApiEndpoint,
) -> impl Future<Item = HttpResponse, Error = Error> {
let conn = pool.get().unwrap();
web::block(move || api::execute(&conn, query)).then(|res| match res {
@@ -42,7 +42,7 @@ fn db_call(
})
}
fn restricted_to_group(id: i32, params: (AppPool, api::ApiActions)) -> MaybeForbidden {
fn restricted_to_group(id: i32, params: (AppPool, api::ApiEndpoint)) -> MaybeForbidden {
if id != 0 {
actix_web::Either::B(HttpResponse::Forbidden().finish())
} else {
@@ -101,7 +101,7 @@ where
}
fn configure_api(config: &mut web::ServiceConfig) {
use api::ApiActions as Q;
use api::ApiEndpoint as Q;
config.service(
web::scope("/api")
.wrap(RestrictedAccess)
@@ -109,31 +109,31 @@ fn configure_api(config: &mut web::ServiceConfig) {
web::scope("/players")
.service(
web::resource("/")
.route(web::get().to_async(|pool| db_call(pool, Q::FetchPlayers)))
.route(web::get().to_async(|pool| db_call(pool, Q::PlayerList)))
.route(web::post().to_async(
|pool, player: web::Json<api::NewPlayer>| {
db_call(pool, Q::AddPlayer(player.into_inner()))
db_call(pool, Q::PlayerAdd(player.into_inner()))
},
)),
) // List of players
.service(
web::scope("/{player_id}")
.route(
/*.route(
"/",
web::get().to_async(|pool, player: PlayerId| {
db_call(pool, Q::FetchPlayer(*player))
}),
)
)*/
.route(
"/notifications",
web::get().to_async(|pool, player: PlayerId| {
db_call(pool, Q::FetchNotifications(*player))
db_call(pool, Q::PlayerNotifications(*player))
}),
)
.service(
web::resource("/claims")
.route(web::get().to_async(|pool, player: PlayerId| {
db_call(pool, Q::FetchPlayerClaims(*player))
db_call(pool, Q::PlayerClaims(*player))
}))
.route(web::post().to_async(
|pool, (player, data): (PlayerId, IdList)| {
@@ -146,14 +146,14 @@ fn configure_api(config: &mut web::ServiceConfig) {
//.route(web::get().to_async(...))
.route(web::put().to_async(
|pool, (player, data): (PlayerId, web::Json<f64>)| {
db_call(pool, Q::UpdateWealth(*player, *data))
db_call(pool, Q::PlayerUpdateWealth(*player, *data))
},
)),
)
.service(
web::resource("/loot")
.route(web::get().to_async(|pool, player: PlayerId| {
db_call(pool, Q::FetchLoot(*player))
db_call(pool, Q::PlayerLoot(*player))
}))
.route(web::put().to_async(
move |pool, (player, data): (PlayerId, BuySellParams)| {
@@ -184,25 +184,25 @@ fn configure_api(config: &mut web::ServiceConfig) {
)
.route(
"/claims",
web::get().to_async(|pool| db_call(pool, Q::FetchClaims)),
web::get().to_async(|pool| db_call(pool, Q::ClaimsList)),
)
.service(
web::resource("/shop")
.route(web::get().to_async(|pool| db_call(pool, Q::FetchShopInventory)))
.route(web::get().to_async(|pool| db_call(pool, Q::ShopList)))
.route(
web::post().to_async(|pool, items: web::Json<api::ItemList>| {
db_call(pool, Q::RefreshShopInventory(items.into_inner()))
db_call(pool, Q::RefreshShop(items.into_inner()))
}),
),
)
.service(
web::resource("/items")
.route(
web::get().to_async(move |pool: AppPool| db_call(pool, Q::FetchInventory)),
web::get().to_async(move |pool: AppPool| db_call(pool, Q::InventoryList)),
)
.route(web::post().to_async(
move |pool: AppPool, items: web::Json<Vec<String>>| {
db_call(pool, Q::CheckItemList(items.into_inner()))
db_call(pool, Q::InventoryCheck(items.into_inner()))
},
)),
),
@@ -277,8 +277,8 @@ fn enter_session(id: Identity, pool: AppPool) -> impl Future<Item = HttpResponse
api::execute(
&conn,
match logged {
SessionKind::Player(id) => api::ApiActions::FetchPlayer(id),
SessionKind::Admin => api::ApiActions::FetchPlayers,
SessionKind::Player(id) => api::ApiEndpoint::PlayerFetch(id),
SessionKind::Admin => api::ApiEndpoint::PlayerList,
},
)
})