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)); } }