use std::collections::{HashMap, HashSet}; use std::sync::RwLock; #[cfg(test)] use anyhow::Result; use crate::account::Account; pub struct Bank { pub accounts: HashMap>, } impl Bank { pub fn new() -> Self { Self { accounts: HashMap::new() } } pub fn account_numbers(&self) -> HashSet { self.accounts.iter() .filter(|(_, acc)| acc.read().unwrap().is_active) .map(|(_, acc)| acc.read().unwrap().number.clone()) .collect() } pub fn create_account(&mut self, owner: String) -> String { let acc = Account { owner, ..Default::default() }; let number = acc.number.clone(); self.accounts.insert(acc.number.clone(), RwLock::new(acc)); number } #[cfg(test)] pub fn transfer(&self, from: &mut Account, to: &mut Account, amount: f64) -> Result<()> { from.withdraw(amount)?; to.deposit(amount)?; Ok(()) } } #[cfg(test)] mod tests { use super::*; #[test] fn creation() { let mut bank = Bank::new(); let nr = bank.create_account("Rohaja".into()); assert!(bank.accounts.get(&nr).is_some()); assert!(bank.accounts.get("thisisnotauuid").is_none()); } #[test] fn transfer() { let mut bank = Bank::new(); let nr1 = bank.create_account("Rohaja".into()); let nr2 = bank.create_account("Hal".into()); { let mut acc1 = bank.accounts.get(&nr1).unwrap().write().unwrap(); let mut acc2 = bank.accounts.get(&nr2).unwrap().write().unwrap(); let result = bank.transfer(&mut acc1, &mut acc2, 100_f64); assert!(result.is_err()); acc1.deposit(100_f64).unwrap(); let result = bank.transfer(&mut acc1, &mut acc2, 50_f64); assert!(result.is_ok()); assert_eq!(acc2.balance, 50_f64); let result = bank.transfer(&mut acc1, &mut acc2, -50_f64); assert!(result.is_err()); acc2.withdraw(50_f64).unwrap(); assert!(acc2.passivate()); let result = bank.transfer(&mut acc1, &mut acc2, 50_f64); assert!(result.is_err()); } assert_eq!(1, bank.account_numbers().len()); } }