93 lines
2.5 KiB
Rust
93 lines
2.5 KiB
Rust
use chrono::{DateTime, Utc, Duration};
|
|
use serde::{Deserialize, Serialize};
|
|
use crate::db::base::{SledModel, Storable}; // Import Sled traits from db module
|
|
use crate::models::biz::exchange_rate::EXCHANGE_RATE_SERVICE;
|
|
|
|
/// Currency represents a monetary value with amount and currency code
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Currency {
|
|
pub amount: f64,
|
|
pub currency_code: String,
|
|
}
|
|
|
|
impl Currency {
|
|
/// Create a new currency with amount and code
|
|
pub fn new(amount: f64, currency_code: String) -> Self {
|
|
Self {
|
|
amount,
|
|
currency_code,
|
|
}
|
|
}
|
|
|
|
/// Convert the currency to USD
|
|
pub fn to_usd(&self) -> Option<Currency> {
|
|
if self.currency_code == "USD" {
|
|
return Some(self.clone());
|
|
}
|
|
|
|
EXCHANGE_RATE_SERVICE.convert(self.amount, &self.currency_code, "USD")
|
|
.map(|amount| Currency::new(amount, "USD".to_string()))
|
|
}
|
|
|
|
/// Convert the currency to another currency
|
|
pub fn to_currency(&self, target_currency: &str) -> Option<Currency> {
|
|
if self.currency_code == target_currency {
|
|
return Some(self.clone());
|
|
}
|
|
|
|
EXCHANGE_RATE_SERVICE.convert(self.amount, &self.currency_code, target_currency)
|
|
.map(|amount| Currency::new(amount, target_currency.to_string()))
|
|
}
|
|
}
|
|
|
|
/// Builder for Currency
|
|
pub struct CurrencyBuilder {
|
|
amount: Option<f64>,
|
|
currency_code: Option<String>,
|
|
}
|
|
|
|
impl CurrencyBuilder {
|
|
/// Create a new CurrencyBuilder with all fields set to None
|
|
pub fn new() -> Self {
|
|
Self {
|
|
amount: None,
|
|
currency_code: None,
|
|
}
|
|
}
|
|
|
|
/// Set the amount
|
|
pub fn amount(mut self, amount: f64) -> Self {
|
|
self.amount = Some(amount);
|
|
self
|
|
}
|
|
|
|
/// Set the currency code
|
|
pub fn currency_code<S: Into<String>>(mut self, currency_code: S) -> Self {
|
|
self.currency_code = Some(currency_code.into());
|
|
self
|
|
}
|
|
|
|
/// Build the Currency object
|
|
pub fn build(self) -> Result<Currency, &'static str> {
|
|
Ok(Currency {
|
|
amount: self.amount.ok_or("amount is required")?,
|
|
currency_code: self.currency_code.ok_or("currency_code is required")?,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Implement Storable trait (provides default dump/load)
|
|
impl Storable for Currency {}
|
|
|
|
// Implement SledModel trait
|
|
impl SledModel for Currency {
|
|
fn get_id(&self) -> String {
|
|
// Use the currency code as the ID
|
|
self.currency_code.clone()
|
|
}
|
|
|
|
fn db_prefix() -> &'static str {
|
|
"currency"
|
|
}
|
|
}
|