use serde::{Deserialize, Serialize}; use serenity::model::id::UserId; use std::fmt::{Display, Formatter}; #[derive(Debug, Clone)] #[allow(dead_code)] pub enum WalletError { NotEnoughFunds, InvalidTarget, } impl Display for WalletError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { WalletError::NotEnoughFunds => write!(f, "Not enough funds"), WalletError::InvalidTarget => write!(f, "Invalid target"), } } } #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Wallet { pub owner: UserId, pub coin_count: i64, } #[derive(Debug, Deserialize, Serialize, Clone, Default)] pub struct WalletManager { #[serde(default)] wallets: Vec, } impl WalletManager { pub fn get_user_wallet(&mut self, discord_id: UserId) -> &mut Wallet { if let Some(user_ndx) = self.wallets.iter().position(|u| u.owner == discord_id) { &mut self.wallets[user_ndx] } else { self.wallets.push(Wallet { owner: discord_id, coin_count: 100, }); self.wallets.last_mut().unwrap() } } pub fn transfer_funds( &mut self, src: UserId, dest: UserId, amount: u32, ) -> Result<(), WalletError> { self.try_take_funds(src, amount)?; self.give_funds(dest, amount); Ok(()) } pub fn give_funds(&mut self, discord_id: UserId, amount: u32) { let mut wallet = self.get_user_wallet(discord_id); wallet.coin_count += amount as i64; } pub fn try_take_funds(&mut self, discord_id: UserId, amount: u32) -> Result<(), WalletError> { let mut wallet = self.get_user_wallet(discord_id); if wallet.coin_count < amount as i64 { Err(WalletError::NotEnoughFunds) } else { wallet.coin_count -= amount as i64; Ok(()) } } }