use arma_rs::{FromArma, IntoArma}; use forge_shared::BankValidationError; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Bank { pub uid: String, pub name: String, pub bank: f64, pub cash: f64, pub earnings: f64, pub transactions: Vec, pub phone_number: String, pub email: String, } impl Bank { pub fn new>( uid: S, name: S, phone_number: S, email: S, ) -> Result { let bank = Self { uid: uid.into(), name: name.into(), bank: 0.0, cash: 0.0, earnings: 0.0, transactions: Vec::new(), phone_number: phone_number.into(), email: email.into(), }; bank.validate()?; Ok(bank) } pub fn validate(&self) -> Result<(), BankValidationError> { if self.uid.trim().is_empty() { return Err(BankValidationError::UidEmpty); } if self.name.trim().is_empty() { return Err(BankValidationError::NameEmpty); } if self.bank < 0.0 { return Err(BankValidationError::BankNegative); } if self.cash < 0.0 { return Err(BankValidationError::CashNegative); } if self.phone_number.trim().is_empty() { return Err(BankValidationError::InvalidPhoneNumber( self.phone_number.clone(), )); } if self.email.trim().is_empty() { return Err(BankValidationError::InvalidEmail(self.email.clone())); } Ok(()) } pub fn uid(&self) -> &str { &self.uid } pub fn update_field(&mut self, field: &str, value: serde_json::Value) -> Result<(), String> { let mut temp_bank = self.clone(); match field { "uid" => { if let Some(uid_str) = value.as_str() { temp_bank.uid = uid_str.to_string(); } else { return Err("UID must be a string".to_string()); } } "name" => { if let Some(name_str) = value.as_str() { temp_bank.name = name_str.to_string(); } else { return Err("Name must be a string".to_string()); } } "bank" => { if let Some(bank_val) = value.as_f64() { temp_bank.bank = bank_val; } else { return Err("Bank must be a number".to_string()); } } "cash" => { if let Some(cash_val) = value.as_f64() { temp_bank.cash = cash_val; } else { return Err("Cash must be a number".to_string()); } } "earnings" => { if let Some(earnings_val) = value.as_f64() { temp_bank.earnings = earnings_val; } else { return Err("Earnings must be a number".to_string()); } } "transactions" => { if let serde_json::Value::Array(arr) = value { temp_bank.transactions = arr .into_iter() .filter_map(|val| val.as_str().map(|s| s.to_string())) .collect(); } else { return Err("Transactions must be an array of strings".to_string()); } } "email" => { if let Some(email_str) = value.as_str() { temp_bank.email = email_str.to_string(); } else { return Err("Email must be a string".to_string()); } } "phone_number" => { if let Some(phone_str) = value.as_str() { temp_bank.phone_number = phone_str.to_string(); } else { return Err("Phone number must be a string".to_string()); } } _ => return Err(format!("Unknown field: {}", field)), } temp_bank .validate() .map_err(|e| format!("Validation failed: {}", e))?; *self = temp_bank; Ok(()) } pub fn get_field(&self, field: &str) -> Option { match field { "uid" => Some(serde_json::Value::String(self.uid.clone())), "name" => Some(serde_json::Value::String(self.name.clone())), "bank" => Some(serde_json::Value::from(self.bank)), "cash" => Some(serde_json::Value::from(self.cash)), "earnings" => Some(serde_json::Value::from(self.earnings)), "transactions" => Some(serde_json::Value::Array( self.transactions .iter() .map(|s| serde_json::Value::String(s.clone())) .collect(), )), "phone_number" => Some(serde_json::Value::String(self.phone_number.clone())), "email" => Some(serde_json::Value::String(self.email.clone())), _ => None, } } pub fn update_from_json(&mut self, json_obj: serde_json::Value) -> Result<(), String> { if let serde_json::Value::Object(map) = json_obj { let mut temp_bank = self.clone(); for (field, value) in map { match field.as_str() { "uid" => { if let Some(uid_str) = value.as_str() { temp_bank.uid = uid_str.to_string(); } else { return Err("UID must be a string".to_string()); } } "name" => { if let Some(name_str) = value.as_str() { temp_bank.name = name_str.to_string(); } else { return Err("Name must be a string".to_string()); } } "bank" => { if let Some(bank_val) = value.as_f64() { temp_bank.bank = bank_val; } else { return Err("Bank must be a number".to_string()); } } "cash" => { if let Some(cash_val) = value.as_f64() { temp_bank.cash = cash_val; } else { return Err("Cash must be a number".to_string()); } } "earnings" => { if let Some(earnings_val) = value.as_f64() { temp_bank.earnings = earnings_val; } else { return Err("Earnings must be a number".to_string()); } } "transactions" => { if let serde_json::Value::Array(arr) = value { temp_bank.transactions = arr .into_iter() .filter_map(|val| val.as_str().map(|s| s.to_string())) .collect(); } else { return Err("Transactions must be an array of strings".to_string()); } } "phone_number" => { if let Some(phone_str) = value.as_str() { temp_bank.phone_number = phone_str.to_string(); } else { return Err("Phone number must be a string".to_string()); } } "email" => { if let Some(email_str) = value.as_str() { temp_bank.email = email_str.to_string(); } else { return Err("Email must be a string".to_string()); } } _ => return Err(format!("Unknown field: {}", field)), } } temp_bank .validate() .map_err(|e| format!("Validation failed: {}", e))?; *self = temp_bank; Ok(()) } else { Err("Invalid JSON object".to_string()) } } } impl FromArma for Bank { fn from_arma(s: String) -> Result { serde_json::from_str(&s) .map_err(|e| arma_rs::FromArmaError::InvalidPrimitive(format!("Invalid JSON: {}", e))) } } impl IntoArma for Bank { fn to_arma(&self) -> arma_rs::Value { let json_str = serde_json::to_string(self).unwrap_or_default(); arma_rs::Value::String(json_str) } }