iati_types/
money.rs

1use chrono::NaiveDate;
2use rust_decimal::Decimal;
3use serde::{Deserialize, Serialize};
4
5/// ISO 4217 currency code stored as uppercase string.
6/// Kept as a newtype to allow lightweight validation/normalisation later.
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 
8#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
9pub struct CurrencyCode(pub String);
10
11impl From<&str> for CurrencyCode {  
12    fn from(s: &str) -> Self {
13        Self(s.to_ascii_uppercase()) 
14    }
15}
16impl From<String> for CurrencyCode {
17    fn from(s: String) -> Self {  
18        Self(s.to_ascii_uppercase())
19    }
20}
21
22/// Monetary amount with currency and value-date.
23/// In IATI, '<value>' carries '@currency' and '@value-date' attributes.
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25#[derive(Debug, Clone, PartialEq)]
26pub struct Money {
27    pub amount: Decimal,
28    /// If 'None', callers may fall back to 'Activity.default_currency'.
29    pub currency: Option<CurrencyCode>,
30    /// Preferred date to use for FX. If 'None', callers may fall back to
31    /// 'Transaction.transaction_date' or 'Activity.activity_start'.
32    pub value_date: Option<NaiveDate>, 
33}
34
35impl Money { 
36    pub fn new(amount: Decimal) -> Self {
37        Self {
38            amount,
39            currency: None,
40            value_date: None,
41        }
42    }
43}