db/herodb/src/models/biz/currency.rs
2025-04-04 12:15:30 +02:00

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"
}
}