Files
lootalot/lootalot_db/src/models/player.rs
2019-07-03 14:11:26 +02:00

110 lines
2.4 KiB
Rust

use diesel::prelude::*;
use crate::schema::players;
use crate::DbConnection;
/// Representation of a player in database
#[derive(Debug, Queryable, Serialize)]
pub struct Player {
id: i32,
name: String,
debt: i32,
cp: i32,
sp: i32,
gp: i32,
pp: i32,
}
/// Unpack a floating value in gold pieces to integer
/// values of copper, silver, gold and platinum pieces
///
/// # Note
///
/// The conversion is slightly different than standard rules :
/// ``` 1pp = 100gp = 1000sp = 10000 cp ```
///
fn unpack_gold_value(gold: f32) -> (i32, i32, i32, i32) {
let rest = (gold.fract() * 100.0).round() as i32;
let gold = gold.trunc() as i32;
let pp = gold / 100;
let gp = gold % 100;
let sp = rest / 10;
let cp = rest % 10;
(cp, sp, gp, pp)
}
/// Represent an update on a player's wealth
///
/// The values held here are the amount of pieces to add or
/// substract to player wealth.
#[derive(Queryable, AsChangeset, Debug)]
#[table_name="players"]
pub struct WealthUpdate {
cp: i32,
sp: i32,
gp: i32,
pp: i32
}
impl WealthUpdate{
/// Unpack individual pieces counts from gold value
pub fn from_gp(gp: f32) -> Self {
let (cp, sp, gp, pp) = unpack_gold_value(gp);
Self { cp, sp, gp, pp }
}
pub fn to_gp(&self) -> f32 {
let i = self.pp * 100 + self.gp;
let f = ( self.sp * 10 + self.cp ) as f32 / 100.0;
i as f32 + f
}
}
/// Representation of a new player record
#[derive(Insertable)]
#[table_name = "players"]
pub struct NewPlayer<'a> {
name: &'a str,
cp: i32,
sp: i32,
gp: i32,
pp: i32,
}
impl<'a> NewPlayer<'a> {
pub fn create(name: &'a str, wealth: f32) -> Self {
let wealth = WealthUpdate::from_gp(wealth);
Self {
name,
cp: wealth.cp,
sp: wealth.sp,
gp: wealth.gp,
pp: wealth.pp,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::tests;
#[test]
fn new_player_only_with_name() {
let n = NewPlayer::new("Féfi", None);
assert_eq!(n.name, "Féfi");
assert_eq!(n.cp, 0);
assert_eq!(n.sp, 0);
assert_eq!(n.gp, 0);
assert_eq!(n.pp, 0);
}
#[test]
fn new_player_with_wealth() {
let initial_wealth = (1, 2, 3, 4);
let n = NewPlayer::new("Féfi", Some(initial_wealth));
assert_eq!(initial_wealth, (n.cp, n.sp, n.gp, n.pp));
}
}