260 lines
9.0 KiB
Rust
260 lines
9.0 KiB
Rust
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<String>,
|
|
pub phone_number: String,
|
|
pub email: String,
|
|
}
|
|
|
|
impl Bank {
|
|
pub fn new<S: Into<String>>(
|
|
uid: S,
|
|
name: S,
|
|
phone_number: S,
|
|
email: S,
|
|
) -> Result<Self, BankValidationError> {
|
|
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<serde_json::Value> {
|
|
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<Self, arma_rs::FromArmaError> {
|
|
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)
|
|
}
|
|
}
|