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 { 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 { 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, currency_code: Option, } 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>(mut self, currency_code: S) -> Self { self.currency_code = Some(currency_code.into()); self } /// Build the Currency object pub fn build(self) -> Result { 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" } }