thoughts on new api structure, formats code
This commit is contained in:
@@ -4,8 +4,10 @@
|
||||
//! This module wraps all needed database operations.
|
||||
//! It exports a public API for integration with various clients (REST Api, CLI, ...)
|
||||
extern crate dotenv;
|
||||
#[macro_use] extern crate diesel;
|
||||
#[macro_use] extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate diesel;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
use diesel::prelude::*;
|
||||
use diesel::query_dsl::RunQueryDsl;
|
||||
@@ -16,8 +18,8 @@ pub mod models;
|
||||
mod schema;
|
||||
|
||||
pub use models::{
|
||||
item::{Item, LootManager},
|
||||
claim::{Claim, Claims},
|
||||
item::{Item, LootManager},
|
||||
player::{Player, Players},
|
||||
};
|
||||
|
||||
@@ -30,6 +32,33 @@ pub type QueryResult<T> = Result<T, diesel::result::Error>;
|
||||
/// The result of an action provided by DbApi
|
||||
pub type ActionResult<R> = Result<R, diesel::result::Error>;
|
||||
|
||||
pub enum ApiError {
|
||||
DieselError(diesel::result::Error),
|
||||
InvalidAction(String),
|
||||
}
|
||||
|
||||
pub type ApiResult<R> = Result<R, ApiError>;
|
||||
|
||||
pub enum ApiActions<'a> {
|
||||
FetchPlayers,
|
||||
FetchInventory,
|
||||
// Player actions
|
||||
FetchLoot(i32),
|
||||
UpdateWealth(i32, f32),
|
||||
BuyItems(i32, &'a Vec<(i32, Option<f32>)>),
|
||||
SellItems(i32, &'a Vec<(i32, Option<f32>)>),
|
||||
ClaimItem(i32, i32),
|
||||
UnclaimItem(i32, i32),
|
||||
// Group actions
|
||||
AddLoot(&'a Vec<Item>),
|
||||
}
|
||||
|
||||
pub enum AdminActions {
|
||||
AddPlayer(String, f32),
|
||||
//AddInventoryItem(pub String, pub i32),
|
||||
ResolveClaims,
|
||||
//SetClaimsTimeout(pub i32),
|
||||
}
|
||||
|
||||
/// A wrapper providing an API over the database
|
||||
/// It offers a convenient way to deal with connection.
|
||||
@@ -138,18 +167,20 @@ impl<'q> AsPlayer<'q> {
|
||||
///
|
||||
/// # Returns
|
||||
/// Result containing the difference in coins after operation
|
||||
pub fn buy<'a>(self, params: &Vec<(i32, Option<f32>)>) -> ActionResult<(Vec<models::Item>, (i32, i32, i32, i32))> {
|
||||
pub fn buy<'a>(
|
||||
self,
|
||||
params: &Vec<(i32, Option<f32>)>,
|
||||
) -> ActionResult<(Vec<models::Item>, (i32, i32, i32, i32))> {
|
||||
let mut cumulated_diff: Vec<(i32, i32, i32, i32)> = Vec::with_capacity(params.len());
|
||||
let mut added_items: Vec<models::Item> = Vec::with_capacity(params.len());
|
||||
for (item_id, price_mod) in params.into_iter() {
|
||||
if let Ok((item, diff)) = self.conn.transaction(|| {
|
||||
// Find item in inventory
|
||||
let item = models::item::Inventory(self.conn).find(*item_id)?;
|
||||
let new_item = models::item::LootManager(self.conn, self.id)
|
||||
.add_from(&item)?;
|
||||
let new_item = models::item::LootManager(self.conn, self.id).add_from(&item)?;
|
||||
let sell_price = match price_mod {
|
||||
Some(modifier) => item.base_price as f32 * modifier,
|
||||
None => item.base_price as f32
|
||||
None => item.base_price as f32,
|
||||
};
|
||||
models::player::AsPlayer(self.conn, self.id)
|
||||
.update_wealth(-sell_price)
|
||||
@@ -159,8 +190,13 @@ impl<'q> AsPlayer<'q> {
|
||||
added_items.push(item);
|
||||
}
|
||||
}
|
||||
let all_diff = cumulated_diff.into_iter().fold((0,0,0,0), |sum, diff| {
|
||||
(sum.0 + diff.0, sum.1 + diff.1, sum.2 + diff.2, sum.3 + diff.3)
|
||||
let all_diff = cumulated_diff.into_iter().fold((0, 0, 0, 0), |sum, diff| {
|
||||
(
|
||||
sum.0 + diff.0,
|
||||
sum.1 + diff.1,
|
||||
sum.2 + diff.2,
|
||||
sum.3 + diff.3,
|
||||
)
|
||||
});
|
||||
Ok((added_items, all_diff))
|
||||
}
|
||||
@@ -168,10 +204,7 @@ impl<'q> AsPlayer<'q> {
|
||||
///
|
||||
/// # Returns
|
||||
/// Result containing the difference in coins after operation
|
||||
pub fn sell(
|
||||
self,
|
||||
params: &Vec<(i32, Option<f32>)>,
|
||||
) -> ActionResult<(i32, i32, i32, i32)> {
|
||||
pub fn sell(self, params: &Vec<(i32, Option<f32>)>) -> ActionResult<(i32, i32, i32, i32)> {
|
||||
let mut all_results: Vec<(i32, i32, i32, i32)> = Vec::with_capacity(params.len());
|
||||
for (loot_id, price_mod) in params.into_iter() {
|
||||
let res = self.conn.transaction(|| {
|
||||
@@ -186,13 +219,17 @@ impl<'q> AsPlayer<'q> {
|
||||
all_results.push(diff.as_tuple())
|
||||
} else {
|
||||
// TODO: need to find a better way to deal with errors
|
||||
return Err(diesel::result::Error::NotFound)
|
||||
return Err(diesel::result::Error::NotFound);
|
||||
}
|
||||
}
|
||||
Ok(all_results.into_iter().fold((0,0,0,0), |sum, diff| {
|
||||
(sum.0 + diff.0, sum.1 + diff.1, sum.2 + diff.2, sum.3 + diff.3)
|
||||
Ok(all_results.into_iter().fold((0, 0, 0, 0), |sum, diff| {
|
||||
(
|
||||
sum.0 + diff.0,
|
||||
sum.1 + diff.1,
|
||||
sum.2 + diff.2,
|
||||
sum.3 + diff.3,
|
||||
)
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
/// Adds the value in gold to the player's wealth.
|
||||
@@ -202,7 +239,6 @@ impl<'q> AsPlayer<'q> {
|
||||
models::player::AsPlayer(self.conn, self.id)
|
||||
.update_wealth(value_in_gp)
|
||||
.map(|w| w.as_tuple())
|
||||
|
||||
}
|
||||
/// Put a claim on a specific item
|
||||
pub fn claim(self, item: i32) -> ActionResult<()> {
|
||||
@@ -232,8 +268,7 @@ impl<'q> AsAdmin<'q> {
|
||||
///
|
||||
/// Takes the player name and starting wealth (in gold value).
|
||||
pub fn add_player(self, name: &str, start_wealth: f32) -> ActionResult<()> {
|
||||
models::player::Players(self.0)
|
||||
.add(name, start_wealth)?;
|
||||
models::player::Players(self.0).add(name, start_wealth)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -260,10 +295,9 @@ impl<'q> AsAdmin<'q> {
|
||||
self.0.transaction(|| {
|
||||
claim.resolve_claim(self.0)?;
|
||||
//models::item::LootManager(self.0, 0).set_owner(claim.loot_id, claim.player_id)?;
|
||||
models::player::AsPlayer(self.0, player_id)
|
||||
.update_debt(item.sell_value())
|
||||
models::player::AsPlayer(self.0, player_id).update_debt(item.sell_value())
|
||||
})?;
|
||||
},
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
@@ -355,13 +389,22 @@ mod tests_old {
|
||||
assert_eq!(claims.len(), 0);
|
||||
|
||||
// Add items
|
||||
assert_eq!(DbApi::with_conn(&conn).as_admin().add_loot(vec![
|
||||
("Épée", 40),
|
||||
("Arc", 40),
|
||||
]).is_ok(), true);
|
||||
assert_eq!(
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
.add_loot(vec![("Épée", 40), ("Arc", 40),])
|
||||
.is_ok(),
|
||||
true
|
||||
);
|
||||
// Add players
|
||||
DbApi::with_conn(&conn).as_admin().add_player("Player1", 0.0).unwrap();
|
||||
DbApi::with_conn(&conn).as_admin().add_player("Player2", 0.0).unwrap();
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
.add_player("Player1", 0.0)
|
||||
.unwrap();
|
||||
DbApi::with_conn(&conn)
|
||||
.as_admin()
|
||||
.add_player("Player2", 0.0)
|
||||
.unwrap();
|
||||
// Put claims on one different item each
|
||||
DbApi::with_conn(&conn).as_player(1).claim(1).unwrap();
|
||||
DbApi::with_conn(&conn).as_player(2).claim(2).unwrap();
|
||||
@@ -370,7 +413,10 @@ mod tests_old {
|
||||
// Check that both players received an item
|
||||
let players = DbApi::with_conn(&conn).fetch_players().unwrap();
|
||||
for &i in [1, 2].into_iter() {
|
||||
assert_eq!(DbApi::with_conn(&conn).as_player(i).loot().unwrap().len(), 1);
|
||||
assert_eq!(
|
||||
DbApi::with_conn(&conn).as_player(i).loot().unwrap().len(),
|
||||
1
|
||||
);
|
||||
let player = players.get(i as usize).unwrap();
|
||||
assert_eq!(player.debt, 20);
|
||||
}
|
||||
@@ -448,9 +494,7 @@ mod tests_old {
|
||||
.add_player("Player", 1000.0)
|
||||
.unwrap();
|
||||
// Buy an item
|
||||
let bought = DbApi::with_conn(&conn)
|
||||
.as_player(1)
|
||||
.buy(&vec![(1, None)]);
|
||||
let bought = DbApi::with_conn(&conn).as_player(1).buy(&vec![(1, None)]);
|
||||
assert_eq!(bought.ok(), Some((0, 0, 0, -8))); // Returns diff of player wealth ?
|
||||
let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap();
|
||||
assert_eq!(chest.len(), 1);
|
||||
@@ -461,10 +505,14 @@ mod tests_old {
|
||||
let player = players.get(1).unwrap();
|
||||
assert_eq!(player.pp, 2);
|
||||
// A player cannot sell loot from an other's chest
|
||||
let result = DbApi::with_conn(&conn).as_player(0).sell(&vec![(loot.id, None)]);
|
||||
let result = DbApi::with_conn(&conn)
|
||||
.as_player(0)
|
||||
.sell(&vec![(loot.id, None)]);
|
||||
assert_eq!(result.is_ok(), false);
|
||||
// Sell back
|
||||
let sold = DbApi::with_conn(&conn).as_player(1).sell(&vec![(loot.id, None)]);
|
||||
let sold = DbApi::with_conn(&conn)
|
||||
.as_player(1)
|
||||
.sell(&vec![(loot.id, None)]);
|
||||
assert_eq!(sold.ok(), Some((0, 0, 0, 4)));
|
||||
let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap();
|
||||
assert_eq!(chest.len(), 0);
|
||||
|
||||
Reference in New Issue
Block a user