enhance responses from API, integrates with frontend
This commit is contained in:
@@ -14,7 +14,30 @@ mod schema;
|
||||
pub type DbConnection = SqliteConnection;
|
||||
pub type Pool = r2d2::Pool<ConnectionManager<DbConnection>>;
|
||||
pub type QueryResult<T> = Result<T, diesel::result::Error>;
|
||||
pub type ActionResult = QueryResult<bool>;
|
||||
pub type ActionResult<R> = QueryResult<ActionStatus<R>>;
|
||||
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct ActionStatus<R: serde::Serialize> {
|
||||
/// Has the action made changes ?
|
||||
executed: bool,
|
||||
/// Response payload
|
||||
response: R,
|
||||
}
|
||||
|
||||
impl ActionStatus<()> {
|
||||
fn ok() -> ActionStatus<()> {
|
||||
Self {
|
||||
executed: true,
|
||||
response: (),
|
||||
}
|
||||
}
|
||||
fn nop() -> ActionStatus<()> {
|
||||
Self {
|
||||
executed: false,
|
||||
response: (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper providing an API over the database
|
||||
/// It offers a convenient way to deal with connection
|
||||
@@ -115,7 +138,8 @@ impl<'q> AsPlayer<'q> {
|
||||
/// Adds the value in gold to the player's wealth.
|
||||
///
|
||||
/// Value can be negative to substract wealth.
|
||||
pub fn update_wealth(self, value_in_gp: f32) -> ActionResult {
|
||||
pub fn update_wealth(self, value_in_gp: f32)
|
||||
-> ActionResult<Option<(i32, i32, i32, i32)>> {
|
||||
use schema::players::dsl::*;
|
||||
let current_wealth = players
|
||||
.find(self.id)
|
||||
@@ -126,30 +150,54 @@ impl<'q> AsPlayer<'q> {
|
||||
let update = models::WealthUpdate::from_gp(
|
||||
current_wealth.to_gp() + value_in_gp
|
||||
);
|
||||
// Difference in coins that is sent back
|
||||
let (old, new) =
|
||||
(current_wealth.as_tuple(), update.as_tuple());
|
||||
let diff = (
|
||||
new.0 - old.0,
|
||||
new.1 - old.1,
|
||||
new.2 - old.2,
|
||||
new.3 - old.3
|
||||
);
|
||||
diesel::update(players)
|
||||
.filter(id.eq(self.id))
|
||||
.set(&update)
|
||||
.execute(self.conn)
|
||||
// TODO: need to work out what this boolean REALLY means
|
||||
.map(|r| match r { 1 => true, _ => false })
|
||||
.map(|r| match r {
|
||||
1 => ActionStatus {
|
||||
executed: true,
|
||||
response: Some(diff),
|
||||
},
|
||||
_ => ActionStatus {
|
||||
executed: false,
|
||||
response: None,
|
||||
}, })
|
||||
}
|
||||
/// 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)?;
|
||||
if !exists {
|
||||
return Ok(ActionStatus::nop())
|
||||
};
|
||||
let request = models::NewClaim { player_id: self.id, loot_id: item };
|
||||
diesel::insert_into(schema::claims::table)
|
||||
.values(&request)
|
||||
.execute(self.conn)
|
||||
.map(|r| match r { 1 => true, _ => false })
|
||||
.map(|r| match r { 1 => ActionStatus::ok(), _ => ActionStatus::nop() })
|
||||
}
|
||||
/// Withdraw claim
|
||||
pub fn unclaim(self, item: i32) -> ActionResult {
|
||||
pub fn unclaim(self, item: i32) -> ActionResult<()> {
|
||||
use schema::claims::dsl::*;
|
||||
diesel::delete(
|
||||
claims
|
||||
.filter(loot_id.eq(item))
|
||||
.filter(player_id.eq(self.id)))
|
||||
.execute(self.conn)
|
||||
.map(|r| match r { 1 => true, _ => false })
|
||||
.map(|r| match r { 1 => ActionStatus::ok(), _ => ActionStatus::nop() })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,11 +206,25 @@ pub struct AsAdmin<'q>(&'q DbConnection);
|
||||
|
||||
impl<'q> AsAdmin<'q> {
|
||||
|
||||
pub fn add_player(self, name: String, start_wealth: f32) -> ActionResult {
|
||||
pub fn add_player(self, name: String, start_wealth: f32) -> ActionResult<()> {
|
||||
diesel::insert_into(schema::players::table)
|
||||
.values(&models::NewPlayer::create(&name, start_wealth))
|
||||
.execute(self.0)
|
||||
.map(|r| match r { 1 => true, _ => false })
|
||||
.map(|r| match r { 1 => ActionStatus::ok(), _ => ActionStatus::nop() })
|
||||
}
|
||||
|
||||
pub fn resolve_claims(self) -> ActionResult<()> {
|
||||
// Fetch all claims, grouped by items.
|
||||
let loot = models::Loot::owned_by(0).load(self.0)?;
|
||||
let claims = schema::claims::table
|
||||
.load::<models::Claim>(self.0)?
|
||||
.grouped_by(&loot);
|
||||
// For each claimed item
|
||||
let data = loot.into_iter().zip(claims).collect::<Vec<_>>();
|
||||
dbg!(data);
|
||||
// If mutiples claims -> find highest resolve, give to this player
|
||||
// If only one claim -> give to claiming
|
||||
Ok(ActionStatus::nop())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use diesel::prelude::*;
|
||||
use crate::schema::claims;
|
||||
use crate::models::item::Loot;
|
||||
|
||||
#[derive(Queryable, Serialize, Debug)]
|
||||
#[derive(Identifiable, Queryable, Associations, Serialize, Debug)]
|
||||
#[belongs_to(Loot)]
|
||||
pub struct Claim {
|
||||
id: i32,
|
||||
player_id: i32,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use diesel::prelude::*;
|
||||
use diesel::dsl::{Eq, Filter, Select};
|
||||
use diesel::dsl::{Eq, Filter, Select, exists, Find };
|
||||
use diesel::expression::exists::Exists;
|
||||
use crate::schema::{looted, items};
|
||||
use crate::DbConnection;
|
||||
|
||||
@@ -33,8 +34,9 @@ type WithOwner = Eq<looted::owner_id, i32>;
|
||||
type OwnedLoot = Filter<looted::table, WithOwner>;
|
||||
|
||||
/// Represents an item that has been looted
|
||||
#[derive(Debug, Queryable, Serialize)]
|
||||
struct Loot {
|
||||
#[derive(Identifiable, Debug, Queryable, Serialize)]
|
||||
#[table_name="looted"]
|
||||
pub(crate) struct Loot {
|
||||
id: i32,
|
||||
name: String,
|
||||
base_value: i32,
|
||||
@@ -43,10 +45,14 @@ struct Loot {
|
||||
|
||||
impl Loot {
|
||||
/// A filter on Loot that is owned by given player
|
||||
fn owned_by(id: i32) -> OwnedLoot {
|
||||
pub(crate) fn owned_by(id: i32) -> OwnedLoot {
|
||||
looted::table
|
||||
.filter(looted::owner_id.eq(id))
|
||||
}
|
||||
|
||||
pub(crate) fn exists(id: i32) -> Exists<Find<looted::table, i32>> {
|
||||
exists(looted::table.find(id))
|
||||
}
|
||||
}
|
||||
|
||||
type ItemDesc<'a> = (&'a str, i32);
|
||||
|
||||
@@ -3,5 +3,6 @@ mod player;
|
||||
mod claim;
|
||||
|
||||
pub use item::Item;
|
||||
pub(crate) use item::Loot;
|
||||
pub use player::{Player, NewPlayer, WealthUpdate};
|
||||
pub use claim::{NewClaim, Claim};
|
||||
|
||||
@@ -58,6 +58,10 @@ impl WealthUpdate{
|
||||
let f = ( self.sp * 10 + self.cp ) as f32 / 100.0;
|
||||
i as f32 + f
|
||||
}
|
||||
|
||||
pub fn as_tuple(&self) -> (i32, i32, i32, i32) {
|
||||
(self.cp, self.sp, self.gp, self.pp)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user