diff --git a/lootalot_db/src/models/claim.rs b/lootalot_db/src/models/claim.rs index f9a4eed..11bfe6d 100644 --- a/lootalot_db/src/models/claim.rs +++ b/lootalot_db/src/models/claim.rs @@ -124,16 +124,8 @@ mod tests { let manager = models::player::Players(&conn); manager.add("Player1", 0.0)?; manager.add("Player2", 0.0)?; - crate::LootManager(&conn, 0).add_from(&crate::Item { - id: 0, - name: "Epee".to_string(), - base_price: 30, - })?; - crate::LootManager(&conn, 1).add_from(&crate::Item { - id: 0, - name: "Arc".to_string(), - base_price: 20, - })?; + crate::LootManager(&conn, 0).add("Epee", 30)?; + crate::LootManager(&conn, 1).add("Arc", 20)?; Ok(conn) } diff --git a/lootalot_db/src/models/item.rs b/lootalot_db/src/models/item.rs index 95d1ef0..49e2290 100644 --- a/lootalot_db/src/models/item.rs +++ b/lootalot_db/src/models/item.rs @@ -124,6 +124,14 @@ impl<'q> LootManager<'q> { .first(self.0)?) } + pub(crate) fn add>(self, name: S, base_price: i32) -> QueryResult { + self.add_from(&Item { + id: 0, + name: name.into(), + base_price, + }) + } + /// Adds a copy of the given item inside player chest pub fn add_from(self, item: &Item) -> QueryResult { let new_item = NewLoot { diff --git a/lootalot_db/src/models/player/mod.rs b/lootalot_db/src/models/player/mod.rs new file mode 100644 index 0000000..2567017 --- /dev/null +++ b/lootalot_db/src/models/player/mod.rs @@ -0,0 +1,111 @@ +use crate::schema::players; +use crate::{DbConnection, QueryResult}; +use diesel::prelude::*; + +pub mod wealth; +pub use wealth::Wealth; + +/// Representation of a player in database +#[derive(Identifiable, Queryable, Serialize, Deserialize, Debug)] +pub struct Player { + /// DB Identitier + pub id: i32, + /// Full name of the character + pub name: String, + /// Amount of gold coins owed to the group. + /// Taking a looted items will increase the debt by it's sell value + pub debt: i32, + /// Count of copper pieces + pub cp: i32, + /// Count of silver pieces + pub sp: i32, + /// Count of gold pieces + pub gp: i32, + /// Count of platinum pieces + pub pp: i32, +} + +/// Manager for players +pub struct Players<'q>(pub &'q DbConnection); + +impl<'q> Players<'q> { + /// Get all players from database + pub fn all(&self) -> QueryResult> { + players::table.load(self.0) + } + + /// Find a player by id + pub fn find(&self, id: i32) -> QueryResult { + players::table.find(id).first(self.0) + } + + /// Add a new player with name and starting wealth + pub fn add(&self, name: &str, wealth: f64) -> QueryResult { + diesel::insert_into(players::table) + .values(&NewPlayer::create(name, wealth)) + .execute(self.0)?; + players::table.order(players::dsl::id.desc()).first(self.0) + } + + /// Notify all players of an event + pub fn notifiy_all>(&self, text: S) -> QueryResult<()> { + Err(diesel::result::Error::NotFound) + } + + /// Notify a single player of an event + pub fn notify>(&self, id: i32, text: S) -> QueryResult<()> { + Err(diesel::result::Error::NotFound) + } +} + +/// Wrapper for action of a single player +pub struct AsPlayer<'q>(pub &'q DbConnection, pub i32); + +impl<'q> AsPlayer<'q> { + /// Updates this player's wealth, returning the difference + pub fn update_wealth(&self, value_in_gp: f64) -> QueryResult { + use crate::schema::players::dsl::*; + let current_wealth = players + .find(self.1) + .select((cp, sp, gp, pp)) + .first::(self.0)?; + let updated_wealth = Wealth::from_gp(current_wealth.to_gp() + value_in_gp); + diesel::update(players) + .filter(id.eq(self.1)) + .set(&updated_wealth) + .execute(self.0)?; + Ok(updated_wealth - current_wealth) + } + + /// Updates this player's debt + pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> { + diesel::update(players::table.find(self.1)) + .set(players::dsl::debt.eq(players::dsl::debt + value_in_gp)) + .execute(self.0)?; + Ok(()) + } +} + +/// Representation of a new player record +#[derive(Insertable)] +#[table_name = "players"] +struct NewPlayer<'a> { + name: &'a str, + cp: i32, + sp: i32, + gp: i32, + pp: i32, +} + +impl<'a> NewPlayer<'a> { + fn create(name: &'a str, wealth_in_gp: f64) -> Self { + let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple(); + Self { + name, + cp, + sp, + gp, + pp, + } + } +} diff --git a/lootalot_db/src/models/player.rs b/lootalot_db/src/models/player/wealth.rs similarity index 52% rename from lootalot_db/src/models/player.rs rename to lootalot_db/src/models/player/wealth.rs index d7bbfab..1088ac7 100644 --- a/lootalot_db/src/models/player.rs +++ b/lootalot_db/src/models/player/wealth.rs @@ -1,80 +1,4 @@ use crate::schema::players; -use crate::{DbConnection, QueryResult}; -use diesel::prelude::*; - -/// Representation of a player in database -#[derive(Identifiable, Queryable, Serialize, Deserialize, Debug)] -pub struct Player { - /// DB Identitier - pub id: i32, - /// Full name of the character - pub name: String, - /// Amount of gold coins owed to the group. - /// Taking a looted items will increase the debt by it's sell value - pub debt: i32, - /// Count of copper pieces - pub cp: i32, - /// Count of silver pieces - pub sp: i32, - /// Count of gold pieces - pub gp: i32, - /// Count of platinum pieces - pub pp: i32, -} - -pub struct Players<'q>(pub &'q DbConnection); - -impl<'q> Players<'q> { - /// Get all players from database - pub fn all(&self) -> QueryResult> { - players::table.load(self.0) - } - - /// Find a player by id - pub fn find(&self, id: i32) -> QueryResult { - players::table.find(id).first(self.0) - } - - /// Add a new player with name and starting wealth - pub fn add(&self, name: &str, wealth: f64) -> QueryResult { - diesel::insert_into(players::table) - .values(&NewPlayer::create(name, wealth)) - .execute(self.0)?; - players::table.order(players::dsl::id.desc()).first(self.0) - } - - /// Notify all players of an event - pub fn notifiy_all>(&self, text: S) -> QueryResult<()> { - Err(diesel::result::Error::NotFound) - } -} - -pub struct AsPlayer<'q>(pub &'q DbConnection, pub i32); - -impl<'q> AsPlayer<'q> { - /// Updates this player's wealth, returning the difference - pub fn update_wealth(&self, value_in_gp: f64) -> QueryResult { - use crate::schema::players::dsl::*; - let current_wealth = players - .find(self.1) - .select((cp, sp, gp, pp)) - .first::(self.0)?; - let updated_wealth = Wealth::from_gp(current_wealth.to_gp() + value_in_gp); - diesel::update(players) - .filter(id.eq(self.1)) - .set(&updated_wealth) - .execute(self.0)?; - Ok(updated_wealth - current_wealth) - } - - /// Updates this player's debt - pub fn update_debt(&self, value_in_gp: i32) -> QueryResult<()> { - diesel::update(players::table.find(self.1)) - .set(players::dsl::debt.eq(players::dsl::debt + value_in_gp)) - .execute(self.0)?; - Ok(()) - } -} /// Unpack a floating value of gold pieces to integer /// values of copper, silver, gold and platinum pieces @@ -167,30 +91,6 @@ impl std::ops::Add for Wealth { } } -/// Representation of a new player record -#[derive(Insertable)] -#[table_name = "players"] -struct NewPlayer<'a> { - name: &'a str, - cp: i32, - sp: i32, - gp: i32, - pp: i32, -} - -impl<'a> NewPlayer<'a> { - fn create(name: &'a str, wealth_in_gp: f64) -> Self { - let (cp, sp, gp, pp) = Wealth::from_gp(wealth_in_gp).as_tuple(); - Self { - name, - cp, - sp, - gp, - pp, - } - } -} - #[cfg(test)] mod tests {