formats code

This commit is contained in:
2019-07-20 15:00:28 +02:00
parent 0636829fdd
commit 51a3d00d03
5 changed files with 106 additions and 62 deletions

View File

@@ -49,7 +49,6 @@ impl ActionStatus<()> {
} }
} }
impl<T: Default + serde::Serialize> ActionStatus<T> { impl<T: Default + serde::Serialize> ActionStatus<T> {
fn nop() -> ActionStatus<T> { fn nop() -> ActionStatus<T> {
Self { Self {
@@ -168,7 +167,7 @@ impl<'q> AsPlayer<'q> {
.execute(self.conn) .execute(self.conn)
.and_then(|r| match r { .and_then(|r| match r {
1 => Ok(self.update_wealth(-(price as f32)).unwrap()), 1 => Ok(self.update_wealth(-(price as f32)).unwrap()),
_ => Ok(ActionStatus::nop()) _ => Ok(ActionStatus::nop()),
}) })
} }
/// Sell an item from this player chest /// Sell an item from this player chest
@@ -177,15 +176,22 @@ impl<'q> AsPlayer<'q> {
/// ///
/// This currently panics if player wealth fails to be updated, as this is /// This currently panics if player wealth fails to be updated, as this is
/// a serious error. TODO: handle restoring of sold item in case of wealth update failure. /// a serious error. TODO: handle restoring of sold item in case of wealth update failure.
pub fn sell(self, loot_id: i32, _price_mod: Option<f32>) -> ActionResult<Option<(i32, i32, i32, i32)>> { pub fn sell(
self,
loot_id: i32,
_price_mod: Option<f32>,
) -> ActionResult<Option<(i32, i32, i32, i32)>> {
// Check that the item belongs to player // Check that the item belongs to player
let exists_and_owned: bool = diesel::select(models::Loot::owns(self.id, loot_id)) let exists_and_owned: bool =
.get_result(self.conn)?; diesel::select(models::Loot::owns(self.id, loot_id)).get_result(self.conn)?;
if !exists_and_owned { if !exists_and_owned {
return Ok(ActionStatus::nop()); return Ok(ActionStatus::nop());
} }
use schema::looted::dsl::*; use schema::looted::dsl::*;
let loot_value = looted.find(loot_id).select(base_price).first::<i32>(self.conn)?; let loot_value = looted
.find(loot_id)
.select(base_price)
.first::<i32>(self.conn)?;
let sell_value = (loot_value / 2) as f32; let sell_value = (loot_value / 2) as f32;
diesel::delete(looted.find(loot_id)) diesel::delete(looted.find(loot_id))
.execute(self.conn) .execute(self.conn)
@@ -193,9 +199,9 @@ impl<'q> AsPlayer<'q> {
// On deletion, update this player wealth // On deletion, update this player wealth
1 => Ok(self.update_wealth(sell_value).unwrap()), 1 => Ok(self.update_wealth(sell_value).unwrap()),
_ => Ok(ActionStatus { _ => Ok(ActionStatus {
executed: false, executed: false,
response: None, response: None,
}), }),
}) })
} }
@@ -208,7 +214,7 @@ impl<'q> AsPlayer<'q> {
.find(self.id) .find(self.id)
.select((cp, sp, gp, pp)) .select((cp, sp, gp, pp))
.first::<models::Wealth>(self.conn)?; .first::<models::Wealth>(self.conn)?;
// TODO: improve this // TODO: improve thisdiesel dependant transaction
// should be move inside a WealthUpdate method // should be move inside a WealthUpdate method
let updated_wealth = models::Wealth::from_gp(current_wealth.to_gp() + value_in_gp); let updated_wealth = models::Wealth::from_gp(current_wealth.to_gp() + value_in_gp);
// Difference in coins that is sent back // Difference in coins that is sent back
@@ -228,9 +234,7 @@ impl<'q> AsPlayer<'q> {
} }
/// Put a claim on a specific item /// Put a claim on a specific item
pub fn claim(self, item: i32) -> ActionResult<()> { pub fn claim(self, item: i32) -> ActionResult<()> {
// TODO: check that looted item exists let exists: bool = diesel::select(models::Loot::exists(item)).get_result(self.conn)?;
let exists: bool = diesel::select(models::Loot::exists(item))
.get_result(self.conn)?;
if !exists { if !exists {
return Ok(ActionStatus::nop()); return Ok(ActionStatus::nop());
}; };
@@ -244,11 +248,12 @@ impl<'q> AsPlayer<'q> {
pub fn unclaim(self, item: i32) -> ActionResult<()> { pub fn unclaim(self, item: i32) -> ActionResult<()> {
use schema::claims::dsl::*; use schema::claims::dsl::*;
diesel::delete( diesel::delete(
claims.filter(loot_id.eq(item)) claims
.filter(player_id.eq(self.id)), .filter(loot_id.eq(item))
) .filter(player_id.eq(self.id)),
.execute(self.conn) )
.map(ActionStatus::was_updated) .execute(self.conn)
.map(ActionStatus::was_updated)
} }
} }
@@ -335,12 +340,16 @@ mod tests {
#[test] #[test]
fn test_player_updates_wealth() { fn test_player_updates_wealth() {
let conn = test_connection(); let conn = test_connection();
DbApi::with_conn(&conn).as_admin() DbApi::with_conn(&conn)
.as_admin()
.add_player("PlayerName".to_string(), 403.21) .add_player("PlayerName".to_string(), 403.21)
.unwrap(); .unwrap();
let diff = DbApi::with_conn(&conn).as_player(1) let diff = DbApi::with_conn(&conn)
.update_wealth(-401.21).unwrap() .as_player(1)
.response.unwrap(); .update_wealth(-401.21)
.unwrap()
.response
.unwrap();
// Check the returned diff // Check the returned diff
assert_eq!(diff, (-1, -2, -1, -4)); assert_eq!(diff, (-1, -2, -1, -4));
let players = DbApi::with_conn(&conn).fetch_players().unwrap(); let players = DbApi::with_conn(&conn).fetch_players().unwrap();
@@ -355,7 +364,8 @@ mod tests {
#[test] #[test]
fn test_admin_add_player() { fn test_admin_add_player() {
let conn = test_connection(); let conn = test_connection();
let result = DbApi::with_conn(&conn).as_admin() let result = DbApi::with_conn(&conn)
.as_admin()
.add_player("PlayerName".to_string(), 403.21) .add_player("PlayerName".to_string(), 403.21)
.unwrap(); .unwrap();
assert_eq!(result.executed, true); assert_eq!(result.executed, true);
@@ -363,21 +373,31 @@ mod tests {
assert_eq!(players.len(), 2); assert_eq!(players.len(), 2);
let new_player = players.get(1).unwrap(); let new_player = players.get(1).unwrap();
assert_eq!(new_player.name, "PlayerName"); assert_eq!(new_player.name, "PlayerName");
assert_eq!((new_player.cp, new_player.sp, new_player.gp, new_player.pp), (1, 2, 3, 4)); assert_eq!(
(new_player.cp, new_player.sp, new_player.gp, new_player.pp),
(1, 2, 3, 4)
);
} }
#[test] #[test]
fn test_admin_resolve_claims() { fn test_admin_resolve_claims() {
let conn = test_connection();
let claims = DbApi::with_conn(&conn).fetch_claims().unwrap();
assert_eq!(claims.len(), 0);
assert_eq!(true, false); // Failing as test is not complete
} }
#[test] #[test]
fn test_player_claim_item() { fn test_player_claim_item() {
let conn = test_connection(); let conn = test_connection();
DbApi::with_conn(&conn).as_admin() DbApi::with_conn(&conn)
.add_player("Player".to_string(), 0.0).unwrap(); .as_admin()
DbApi::with_conn(&conn).as_admin() .add_player("Player".to_string(), 0.0)
.add_loot(vec![("Épée", 25),]).unwrap(); .unwrap();
DbApi::with_conn(&conn)
.as_admin()
.add_loot(vec![("Épée", 25)])
.unwrap();
// Claim an existing item // Claim an existing item
let result = DbApi::with_conn(&conn).as_player(1).claim(1).unwrap(); let result = DbApi::with_conn(&conn).as_player(1).claim(1).unwrap();
assert_eq!(result.executed, true); assert_eq!(result.executed, true);
@@ -394,10 +414,14 @@ mod tests {
#[test] #[test]
fn test_player_unclaim_item() { fn test_player_unclaim_item() {
let conn = test_connection(); let conn = test_connection();
DbApi::with_conn(&conn).as_admin() DbApi::with_conn(&conn)
.add_player("Player".to_string(), 0.0).unwrap(); .as_admin()
DbApi::with_conn(&conn).as_admin() .add_player("Player".to_string(), 0.0)
.add_loot(vec![("Épée", 25),]).unwrap(); .unwrap();
DbApi::with_conn(&conn)
.as_admin()
.add_loot(vec![("Épée", 25)])
.unwrap();
// Claim an existing item // Claim an existing item
let result = DbApi::with_conn(&conn).as_player(1).claim(1).unwrap(); let result = DbApi::with_conn(&conn).as_player(1).claim(1).unwrap();
assert_eq!(result.executed, true); assert_eq!(result.executed, true);
@@ -408,8 +432,6 @@ mod tests {
assert_eq!(result.executed, false); assert_eq!(result.executed, false);
let claims = DbApi::with_conn(&conn).fetch_claims().unwrap(); let claims = DbApi::with_conn(&conn).fetch_claims().unwrap();
assert_eq!(claims.len(), 0); assert_eq!(claims.len(), 0);
} }
/// All-in-one checks one a simple buy/sell procedure /// All-in-one checks one a simple buy/sell procedure
@@ -419,11 +441,17 @@ mod tests {
#[test] #[test]
fn test_buy_sell_simple() { fn test_buy_sell_simple() {
let conn = test_connection(); let conn = test_connection();
DbApi::with_conn(&conn).as_admin().add_player("Player".to_string(), 1000.0).unwrap(); DbApi::with_conn(&conn)
.as_admin()
.add_player("Player".to_string(), 1000.0)
.unwrap();
// Buy an item // Buy an item
let bought = DbApi::with_conn(&conn).as_player(1).buy("Sword", 800).unwrap(); let bought = DbApi::with_conn(&conn)
.as_player(1)
.buy("Sword", 800)
.unwrap();
assert_eq!(bought.executed, true); // Was updated ? assert_eq!(bought.executed, true); // Was updated ?
assert_eq!(bought.response, Some((0,0,0,-8))); // Returns diff of player wealth ? assert_eq!(bought.response, Some((0, 0, 0, -8))); // Returns diff of player wealth ?
let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap(); let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap();
assert_eq!(chest.len(), 1); assert_eq!(chest.len(), 1);
let loot = chest.get(0).unwrap(); let loot = chest.get(0).unwrap();
@@ -433,9 +461,12 @@ mod tests {
let player = players.get(1).unwrap(); let player = players.get(1).unwrap();
assert_eq!(player.pp, 2); assert_eq!(player.pp, 2);
// Sell back // Sell back
let sold = DbApi::with_conn(&conn).as_player(1).sell(loot.id, None).unwrap(); let sold = DbApi::with_conn(&conn)
.as_player(1)
.sell(loot.id, None)
.unwrap();
assert_eq!(sold.executed, true); assert_eq!(sold.executed, true);
assert_eq!(sold.response, Some((0,0,0,4))); assert_eq!(sold.response, Some((0, 0, 0, 4)));
let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap(); let chest = DbApi::with_conn(&conn).as_player(1).loot().unwrap();
assert_eq!(chest.len(), 0); assert_eq!(chest.len(), 0);
let players = DbApi::with_conn(&conn).fetch_players().unwrap(); let players = DbApi::with_conn(&conn).fetch_players().unwrap();
@@ -446,12 +477,15 @@ mod tests {
#[test] #[test]
fn test_admin_add_loot() { fn test_admin_add_loot() {
let conn = test_connection(); let conn = test_connection();
assert_eq!(0, DbApi::with_conn(&conn).as_player(0).loot().unwrap().len()); assert_eq!(
let loot_to_add = vec![ 0,
("Cape d'invisibilité", 8000), DbApi::with_conn(&conn).as_player(0).loot().unwrap().len()
("Arc long", 25), );
]; let loot_to_add = vec![("Cape d'invisibilité", 8000), ("Arc long", 25)];
let result = DbApi::with_conn(&conn).as_admin().add_loot(loot_to_add.clone()).unwrap(); let result = DbApi::with_conn(&conn)
.as_admin()
.add_loot(loot_to_add.clone())
.unwrap();
assert_eq!(result.executed, true); assert_eq!(result.executed, true);
let looted = DbApi::with_conn(&conn).as_player(0).loot().unwrap(); let looted = DbApi::with_conn(&conn).as_player(0).loot().unwrap();
assert_eq!(looted.len(), 2); assert_eq!(looted.len(), 2);
@@ -463,5 +497,3 @@ mod tests {
} }
} }
} }

View File

@@ -24,9 +24,6 @@ pub(crate) struct NewClaim {
impl NewClaim { impl NewClaim {
pub(crate) fn new(player_id: i32, loot_id: i32) -> Self { pub(crate) fn new(player_id: i32, loot_id: i32) -> Self {
Self { Self { player_id, loot_id }
player_id,
loot_id
}
} }
} }

View File

@@ -1,4 +1,4 @@
use crate::schema::{looted}; use crate::schema::looted;
use diesel::dsl::{exists, Eq, Filter, Find, Select}; use diesel::dsl::{exists, Eq, Filter, Find, Select};
use diesel::expression::exists::Exists; use diesel::expression::exists::Exists;
use diesel::prelude::*; use diesel::prelude::*;

View File

@@ -99,7 +99,10 @@ impl<'a> NewPlayer<'a> {
let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple(); let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple();
Self { Self {
name, name,
cp, sp, gp, pp, cp,
sp,
gp,
pp,
} }
} }
} }

View File

@@ -65,8 +65,18 @@ pub(crate) fn serve() -> std::io::Result<()> {
) )
.service( .service(
web::scope("/api") web::scope("/api")
.route("/players", web::get().to_async(move |pool: AppPool| db_call(pool, move |api| api.fetch_players()))) .route(
.route("/claims", web::get().to_async(move |pool: AppPool| db_call(pool, move |api| api.fetch_claims()))) "/players",
web::get().to_async(move |pool: AppPool| {
db_call(pool, move |api| api.fetch_players())
}),
)
.route(
"/claims",
web::get().to_async(move |pool: AppPool| {
db_call(pool, move |api| api.fetch_claims())
}),
)
.route( .route(
"/{player_id}/update-wealth/{amount}", "/{player_id}/update-wealth/{amount}",
web::get().to_async(move |pool: AppPool, data: web::Path<(i32, f32)>| { web::get().to_async(move |pool: AppPool, data: web::Path<(i32, f32)>| {
@@ -99,12 +109,14 @@ pub(crate) fn serve() -> std::io::Result<()> {
) )
.route( .route(
"/admin/add-player/{name}/{wealth}", "/admin/add-player/{name}/{wealth}",
web::get().to_async(move |pool: AppPool, data: web::Path<(String, f32)>| { web::get().to_async(
db_call(pool, move |api| { move |pool: AppPool, data: web::Path<(String, f32)>| {
api.as_admin().add_player(data.0.clone(), data.1) db_call(pool, move |api| {
}) api.as_admin().add_player(data.0.clone(), data.1)
}), })
) },
),
),
) )
.service(fs::Files::new("/", www_root.clone()).index_file("index.html")) .service(fs::Files::new("/", www_root.clone()).index_file("index.html"))
}) })