use crate::schema::looted; use diesel::dsl::{exists, Eq, Filter, Find, Select}; use diesel::expression::exists::Exists; use diesel::prelude::*; type ItemColumns = (looted::id, looted::name, looted::base_price); const ITEM_COLUMNS: ItemColumns = (looted::id, looted::name, looted::base_price); type OwnedBy = Select; /// Represents a unique item in inventory /// /// It is also used as a public representation of Loot, since owner /// information is implicit. /// Or maybe this is a little too confusing ?? #[derive(Debug, Queryable, Serialize)] pub struct Item { pub id: i32, pub name: String, pub base_price: i32, } impl Item { /// Public proxy for Loot::owned_by that selects only Item fields pub fn owned_by(player: i32) -> OwnedBy { Loot::owned_by(player).select(ITEM_COLUMNS) } } type WithOwner = Eq; type OwnedLoot = Filter; /// Represents an item that has been looted #[derive(Identifiable, Debug, Queryable, Serialize)] #[table_name = "looted"] pub(crate) struct Loot { id: i32, name: String, base_price: i32, owner: i32, } impl Loot { /// A filter on Loot that is owned by given player pub(crate) fn owned_by(id: i32) -> OwnedLoot { looted::table.filter(looted::owner_id.eq(id)) } pub(crate) fn owns(player: i32, item: i32) -> Exists> { exists(Loot::owned_by(player).find(item)) } pub(crate) fn exists(id: i32) -> Exists> { exists(looted::table.find(id)) } } /// Description of an item : (name, value in gold) pub type ItemDesc<'a> = (&'a str, i32); /// An item being looted or bought. /// /// The owner is set to 0 in case of looting, /// to the id of buying player otherwise. #[derive(Insertable)] #[table_name = "looted"] pub(crate) struct NewLoot<'a> { name: &'a str, base_price: i32, owner_id: i32, } impl<'a> NewLoot<'a> { /// A new loot going to the group (loot procedure) pub(crate) fn to_group(desc: ItemDesc<'a>) -> Self { Self { name: desc.0, base_price: desc.1, owner_id: 0, } } /// A new loot going to a specific player (buy procedure) pub(crate) fn to_player(player: i32, desc: ItemDesc<'a>) -> Self { Self { name: desc.0, base_price: desc.1, owner_id: player, } } }