Rate

Struct Rate 

Source
pub struct Rate<From: Currency, To: Currency> {
    rate: Decimal,
    metadata_timestamp_unix_secs: Option<u64>,
    metadata_source: Option<&'static str>,
    _from: PhantomData<From>,
    _to: PhantomData<To>,
}
Expand description

An exchange rate from one currency to another.

Exchange rates are immutable after construction and use phantom types to ensure type-safe conversions at compile time.

§Type Parameters

  • From - The source currency
  • To - The target currency

§Examples

use typed_money::{Rate, USD, EUR};

// Create a rate: 1 USD = 0.85 EUR
let rate = Rate::<USD, EUR>::new(0.85);

§Immutability

Rates are immutable after creation to ensure auditability and prevent accidental modifications that could lead to financial errors.

Fields§

§rate: Decimal

The exchange rate value (always positive)

§metadata_timestamp_unix_secs: Option<u64>

Optional UNIX timestamp (seconds) representing when the rate was observed

Kept optional to avoid forcing callers to provide a timestamp. Using a primitive preserves Copy and avoids allocations.

§metadata_source: Option<&'static str>

Optional static source identifier for auditability (e.g., “ECB”, “Manual”)

Using &'static str preserves Copy. Callers can pass string literals for simple source tagging without allocations.

§_from: PhantomData<From>

Phantom data for source currency (zero runtime cost)

§_to: PhantomData<To>

Phantom data for target currency (zero runtime cost)

Implementations§

Source§

impl<From: Currency, To: Currency> Rate<From, To>

Source

pub fn try_new(rate: f64) -> MoneyResult<Self>

Tries to create a new exchange rate from a floating-point value.

Returns an error if the rate is zero, negative, NaN, or infinite.

§Examples
use typed_money::{Rate, USD, EUR};

let rate = Rate::<USD, EUR>::try_new(0.85)?;  // 1 USD = 0.85 EUR
assert!(rate.value() > &rust_decimal::Decimal::ZERO);

// Invalid rates return an error
assert!(Rate::<USD, EUR>::try_new(0.0).is_err());
assert!(Rate::<USD, EUR>::try_new(-1.0).is_err());
Examples found in repository?
examples/error_handling.rs (line 81)
11fn main() {
12    println!("=== Error Handling Examples ===\n");
13
14    // ========================================
15    // Parse Errors
16    // ========================================
17    println!("1. PARSING ERRORS");
18    println!("-----------------");
19
20    // Valid parsing
21    match Amount::<USD>::from_str("123.45") {
22        Ok(amount) => println!("✓ Parsed: {}", amount),
23        Err(e) => println!("✗ Error: {}", e),
24    }
25
26    // Invalid formats
27    let invalid_inputs = vec!["invalid", "12.34.56", "abc123", "", "  "];
28
29    println!("\nInvalid inputs:");
30    for input in invalid_inputs {
31        match Amount::<USD>::from_str(input) {
32            Ok(amount) => println!("  '{}' → {}", input, amount),
33            Err(MoneyError::ParseError { input: inp, .. }) => {
34                println!("  '{}' → Parse error (input: '{}')", input, inp);
35            }
36            Err(e) => println!("  '{}' → Error: {}", input, e),
37        }
38    }
39
40    // ========================================
41    // Precision Errors
42    // ========================================
43    println!("\n2. PRECISION ERRORS");
44    println!("-------------------");
45
46    // Division creates excess precision
47    let amount = Amount::<USD>::from_major(10) / 3; // $3.333...
48    println!("After division: {}", amount);
49    println!("Decimal places: {}", amount.precision());
50    println!("Currency expects: {}", Amount::<USD>::currency_precision());
51
52    // Check for precision issues
53    match amount.check_precision() {
54        Ok(()) => println!("✓ Precision OK"),
55        Err(MoneyError::PrecisionError {
56            expected,
57            actual,
58            suggestion,
59            ..
60        }) => {
61            println!("✗ Precision error:");
62            println!("  Expected: {} decimals", expected);
63            println!("  Actual: {} decimals", actual);
64            println!("  Suggestion: {}", suggestion);
65
66            // Recover by normalizing
67            let normalized = amount.normalize();
68            println!("\n✓ After normalizing: {}", normalized);
69            println!("  Precision OK: {}", normalized.check_precision().is_ok());
70        }
71        Err(e) => println!("✗ Unexpected error: {}", e),
72    }
73
74    // ========================================
75    // Invalid Rate Errors
76    // ========================================
77    println!("\n3. INVALID RATE ERRORS");
78    println!("----------------------");
79
80    // Valid rate
81    match Rate::<USD, EUR>::try_new(0.85) {
82        Ok(rate) => println!("✓ Valid rate: {}", rate.value()),
83        Err(e) => println!("✗ Error: {}", e),
84    }
85
86    // Invalid rates
87    let invalid_rates = vec![
88        ("negative", -1.0),
89        ("zero", 0.0),
90        ("NaN", f64::NAN),
91        ("infinity", f64::INFINITY),
92    ];
93
94    println!("\nInvalid rates:");
95    for (desc, value) in invalid_rates {
96        match Rate::<USD, EUR>::try_new(value) {
97            Ok(rate) => println!(
98                "  {} ({}) → Unexpected success: {}",
99                desc,
100                value,
101                rate.value()
102            ),
103            Err(MoneyError::InvalidRate { reason, .. }) => {
104                println!("  {} ({}) → {}", desc, value, reason);
105            }
106            Err(e) => println!("  {} ({}) → Error: {}", desc, value, e),
107        }
108    }
109
110    // ========================================
111    // Error Suggestions
112    // ========================================
113    println!("\n4. ERROR RECOVERY SUGGESTIONS");
114    println!("------------------------------");
115
116    let errors = vec![
117        MoneyError::PrecisionError {
118            currency: "USD",
119            expected: 2,
120            actual: 5,
121            suggestion: "Use normalize() or round() to adjust precision".to_string(),
122        },
123        MoneyError::InvalidRate {
124            value: "-1.0".to_string(),
125            reason: "Rate must be positive".to_string(),
126        },
127        MoneyError::ParseError {
128            input: "abc".to_string(),
129            expected_currency: Some("USD"),
130            reason: "Invalid number format".to_string(),
131        },
132    ];
133
134    for error in errors {
135        println!("\nError: {}", error);
136        println!("Suggestion: {}", error.suggestion());
137        if let Some(currency) = error.currency() {
138            println!("Currency: {}", currency);
139        }
140    }
141
142    // ========================================
143    // Safe Division
144    // ========================================
145    println!("\n5. SAFE DIVISION");
146    println!("----------------");
147
148    let amount = Amount::<USD>::from_major(100);
149
150    // Division by zero is handled
151    let divisor = 0;
152    println!("Dividing {} by {}...", amount, divisor);
153
154    if divisor == 0 {
155        println!("✗ Cannot divide by zero!");
156        println!("  Handled before attempting division");
157    } else {
158        let result = amount / divisor;
159        println!("✓ Result: {}", result);
160    }
161
162    // Safe division with non-zero
163    let safe_divisor = 3;
164    let result = amount / safe_divisor;
165    println!("\nDividing {} by {}: {}", amount, safe_divisor, result);
166
167    // ========================================
168    // Pattern Matching on Errors
169    // ========================================
170    println!("\n6. PATTERN MATCHING");
171    println!("-------------------");
172
173    fn parse_and_handle(input: &str) -> MoneyResult<Amount<USD>> {
174        Amount::<USD>::from_str(input)
175    }
176
177    let inputs = vec!["123.45", "invalid", "999.99"];
178
179    for input in inputs {
180        print!("Parsing '{}': ", input);
181
182        match parse_and_handle(input) {
183            Ok(amount) => {
184                println!("✓ Success: {}", amount);
185            }
186            Err(MoneyError::ParseError { input, reason, .. }) => {
187                println!("✗ Parse error");
188                println!("  Input: '{}'", input);
189                println!("  Reason: {}", reason);
190            }
191            Err(e) => {
192                println!("✗ Other error: {}", e);
193            }
194        }
195    }
196
197    // ========================================
198    // Error Propagation with ?
199    // ========================================
200    println!("\n7. ERROR PROPAGATION");
201    println!("--------------------");
202
203    fn calculate_total(price_str: &str, quantity: i64) -> MoneyResult<Amount<USD>> {
204        let price = Amount::<USD>::from_str(price_str)?;
205        let total = price * quantity;
206        total.check_precision()?;
207        Ok(total)
208    }
209
210    match calculate_total("29.99", 3) {
211        Ok(total) => println!("✓ Total: {}", total),
212        Err(e) => println!("✗ Error: {}", e),
213    }
214
215    match calculate_total("invalid", 3) {
216        Ok(total) => println!("✓ Total: {}", total),
217        Err(e) => println!("✗ Error: {}", e),
218    }
219
220    // ========================================
221    // Recovering from Errors
222    // ========================================
223    println!("\n8. ERROR RECOVERY");
224    println!("-----------------");
225
226    fn parse_with_fallback(input: &str, fallback: Amount<USD>) -> Amount<USD> {
227        Amount::<USD>::from_str(input).unwrap_or(fallback)
228    }
229
230    let fallback = Amount::<USD>::from_major(0);
231
232    let inputs = vec!["123.45", "invalid", "67.89"];
233    for input in inputs {
234        let amount = parse_with_fallback(input, fallback);
235        println!("'{}' → {}", input, amount);
236    }
237
238    // ========================================
239    // Validation Before Operations
240    // ========================================
241    println!("\n9. VALIDATION");
242    println!("-------------");
243
244    fn safe_divide(amount: Amount<USD>, divisor: i64) -> MoneyResult<Amount<USD>> {
245        if divisor == 0 {
246            return Err(MoneyError::InvalidAmount {
247                currency: Some("USD"),
248                reason: "Cannot divide by zero".to_string(),
249            });
250        }
251
252        let result = amount / divisor;
253
254        // Check precision after division
255        result.check_precision()?;
256
257        Ok(result)
258    }
259
260    let amount = Amount::<USD>::from_major(100);
261
262    match safe_divide(amount, 0) {
263        Ok(result) => println!("  Division by 0: {}", result),
264        Err(e) => println!("  Division by 0: Error - {}", e),
265    }
266
267    match safe_divide(amount, 3) {
268        Ok(result) => println!("  Division by 3: {}", result),
269        Err(e) => println!("  Division by 3: Error - {}", e),
270    }
271
272    // ========================================
273    // Real-World: Parsing User Input
274    // ========================================
275    println!("\n10. REAL-WORLD: PARSING USER INPUT");
276    println!("-----------------------------------");
277
278    fn process_payment(amount_str: &str) -> MoneyResult<String> {
279        // Parse the amount
280        let amount = Amount::<USD>::from_str(amount_str)?;
281
282        // Validate it's positive
283        if amount.to_minor() <= 0 {
284            return Err(MoneyError::InvalidAmount {
285                currency: Some("USD"),
286                reason: "Payment amount must be positive".to_string(),
287            });
288        }
289
290        // Process the payment
291        let fee = (amount * 3) / 100; // 3% fee
292        let total = amount + fee;
293
294        Ok(format!(
295            "Payment: {}, Fee: {}, Total: {}",
296            amount, fee, total
297        ))
298    }
299
300    let test_inputs = vec!["100.00", "0", "-50", "abc", "250.50"];
301
302    for input in test_inputs {
303        println!("\nProcessing payment: '{}'", input);
304        match process_payment(input) {
305            Ok(summary) => println!("  ✓ {}", summary),
306            Err(e) => {
307                println!("  ✗ Error: {}", e);
308                let suggestion = e.suggestion();
309                println!("    Hint: {}", suggestion);
310            }
311        }
312    }
313
314    // ========================================
315    // Rounding to Fix Precision
316    // ========================================
317    println!("\n11. FIXING PRECISION WITH ROUNDING");
318    println!("-----------------------------------");
319
320    let amount = Amount::<USD>::from_major(10) / 3; // Creates excess precision
321
322    println!("Original: {}", amount);
323    println!(
324        "Precision check: {}",
325        if amount.check_precision().is_ok() {
326            "✓ OK"
327        } else {
328            "✗ Excess precision"
329        }
330    );
331
332    // Fix with rounding
333    let rounded = amount.round(RoundingMode::HalfUp);
334    println!("\nRounded: {}", rounded);
335    println!(
336        "Precision check: {}",
337        if rounded.check_precision().is_ok() {
338            "✓ OK"
339        } else {
340            "✗ Excess precision"
341        }
342    );
343
344    // Or normalize (uses banker's rounding)
345    let normalized = amount.normalize();
346    println!("\nNormalized: {}", normalized);
347    println!(
348        "Precision check: {}",
349        if normalized.check_precision().is_ok() {
350            "✓ OK"
351        } else {
352            "✗ Excess precision"
353        }
354    );
355
356    println!("\n=== All error handling examples completed! ===");
357}
Source

pub fn new(rate: f64) -> Self

Creates a new exchange rate from a floating-point value.

§Panics

Panics if the rate is zero, negative, NaN, or infinite. For a non-panicking version, use try_new.

§Examples
use typed_money::{Rate, USD, EUR};

let rate = Rate::<USD, EUR>::new(0.85);  // 1 USD = 0.85 EUR
§Panics Examples
use typed_money::{Rate, USD, EUR};

let rate = Rate::<USD, EUR>::new(0.0);  // Panics: rate must be positive
Examples found in repository?
examples/conversions.rs (line 23)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}
More examples
Hide additional examples
examples/global_currencies.rs (line 157)
51fn main() {
52    println!("=== Typed Money - Global Currencies Example ===\n");
53
54    // 1. MAJOR FIAT CURRENCIES
55    println!("1. MAJOR FIAT CURRENCIES");
56    println!("------------------------");
57    let usd = Amount::<USD>::from_major(100);
58    let cad = Amount::<CAD>::from_major(135);
59    let chf = Amount::<CHF>::from_major(90);
60    let aud = Amount::<AUD>::from_major(150);
61    let nzd = Amount::<NZD>::from_major(160);
62
63    println!("USD: {} ({} decimals)", usd, USD::DECIMALS);
64    println!("CAD: {} ({} decimals)", cad, CAD::DECIMALS);
65    println!("CHF: {} ({} decimals)", chf, CHF::DECIMALS);
66    println!("AUD: {} ({} decimals)", aud, AUD::DECIMALS);
67    println!("NZD: {} ({} decimals)", nzd, NZD::DECIMALS);
68    println!();
69
70    // 2. ASIAN CURRENCIES
71    println!("2. ASIAN CURRENCIES");
72    println!("-------------------");
73    let cny = Amount::<CNY>::from_major(720);
74    let krw = Amount::<KRW>::from_major(130_000);
75    let sgd = Amount::<SGD>::from_major(135);
76    let hkd = Amount::<HKD>::from_major(780);
77    let twd = Amount::<TWD>::from_major(3100);
78    let inr = Amount::<INR>::from_major(8300);
79
80    println!("CNY: {} ({} decimals)", cny, CNY::DECIMALS);
81    println!("KRW: {} ({} decimals)", krw, KRW::DECIMALS);
82    println!("SGD: {} ({} decimals)", sgd, SGD::DECIMALS);
83    println!("HKD: {} ({} decimals)", hkd, HKD::DECIMALS);
84    println!("TWD: {} ({} decimals)", twd, TWD::DECIMALS);
85    println!("INR: {} ({} decimals)", inr, INR::DECIMALS);
86    println!();
87
88    // 3. EUROPEAN CURRENCIES
89    println!("3. EUROPEAN CURRENCIES");
90    println!("----------------------");
91    let eur = Amount::<EUR>::from_major(85);
92    let gbp = Amount::<GBP>::from_major(75);
93    let sek = Amount::<SEK>::from_major(1050);
94    let nok = Amount::<NOK>::from_major(1100);
95    let dkk = Amount::<DKK>::from_major(650);
96    let pln = Amount::<PLN>::from_major(400);
97    let czk = Amount::<CZK>::from_major(2300);
98    let huf = Amount::<HUF>::from_major(36_000);
99
100    println!("EUR: {} ({} decimals)", eur, EUR::DECIMALS);
101    println!("GBP: {} ({} decimals)", gbp, GBP::DECIMALS);
102    println!("SEK: {} ({} decimals)", sek, SEK::DECIMALS);
103    println!("NOK: {} ({} decimals)", nok, NOK::DECIMALS);
104    println!("DKK: {} ({} decimals)", dkk, DKK::DECIMALS);
105    println!("PLN: {} ({} decimals)", pln, PLN::DECIMALS);
106    println!("CZK: {} ({} decimals)", czk, CZK::DECIMALS);
107    println!("HUF: {} ({} decimals)", huf, HUF::DECIMALS);
108    println!();
109
110    // 4. AMERICAN CURRENCIES
111    println!("4. AMERICAN CURRENCIES");
112    println!("----------------------");
113    let brl = Amount::<BRL>::from_major(500);
114    let mxn = Amount::<MXN>::from_major(1700);
115    let ars = Amount::<ARS>::from_major(85_000);
116    let clp = Amount::<CLP>::from_major(90_000);
117
118    println!("BRL: {} ({} decimals)", brl, BRL::DECIMALS);
119    println!("MXN: {} ({} decimals)", mxn, MXN::DECIMALS);
120    println!("ARS: {} ({} decimals)", ars, ARS::DECIMALS);
121    println!("CLP: {} ({} decimals)", clp, CLP::DECIMALS);
122    println!();
123
124    // 5. AFRICAN/MIDDLE EASTERN CURRENCIES
125    println!("5. AFRICAN/MIDDLE EASTERN CURRENCIES");
126    println!("------------------------------------");
127    let zar = Amount::<ZAR>::from_major(1800);
128    let egp = Amount::<EGP>::from_major(3100);
129    let aed = Amount::<AED>::from_major(370);
130    let sar = Amount::<SAR>::from_major(375);
131    let ils = Amount::<ILS>::from_major(360);
132    let try_currency = Amount::<TRY>::from_major(3000);
133
134    println!("ZAR: {} ({} decimals)", zar, ZAR::DECIMALS);
135    println!("EGP: {} ({} decimals)", egp, EGP::DECIMALS);
136    println!("AED: {} ({} decimals)", aed, AED::DECIMALS);
137    println!("SAR: {} ({} decimals)", sar, SAR::DECIMALS);
138    println!("ILS: {} ({} decimals)", ils, ILS::DECIMALS);
139    println!("TRY: {} ({} decimals)", try_currency, TRY::DECIMALS);
140    println!();
141
142    // 6. CRYPTOCURRENCIES
143    println!("6. CRYPTOCURRENCIES");
144    println!("-------------------");
145    let btc = Amount::<BTC>::from_minor(100_000_000); // 1.00000000 BTC
146    let eth = Amount::<ETH>::from_minor(1_000_000_000_000_000_000); // 1.000000000000000000 ETH
147
148    println!("BTC: {} ({} decimals)", btc, BTC::DECIMALS);
149    println!("ETH: {} ({} decimals)", eth, ETH::DECIMALS);
150    println!();
151
152    // 7. CURRENCY CONVERSION EXAMPLES
153    println!("7. CURRENCY CONVERSION EXAMPLES");
154    println!("-------------------------------");
155
156    // USD to EUR
157    let usd_to_eur = Rate::<USD, EUR>::new(0.85)
158        .with_timestamp_unix_secs(1_700_000_000)
159        .with_source("ECB");
160    let eur_converted = usd.convert(&usd_to_eur);
161    println!(
162        "USD to EUR: {} → {} (rate: {})",
163        usd,
164        eur_converted,
165        usd_to_eur.value()
166    );
167
168    // EUR to GBP
169    let eur_to_gbp = Rate::<EUR, GBP>::new(0.87);
170    let gbp_converted = eur_converted.convert(&eur_to_gbp);
171    println!(
172        "EUR to GBP: {} → {} (rate: {})",
173        eur_converted,
174        gbp_converted,
175        eur_to_gbp.value()
176    );
177
178    // USD to JPY
179    let usd_to_jpy = Rate::<USD, JPY>::new(150.0);
180    let jpy_converted = usd.convert(&usd_to_jpy);
181    println!(
182        "USD to JPY: {} → {} (rate: {})",
183        usd,
184        jpy_converted,
185        usd_to_jpy.value()
186    );
187    println!();
188
189    // 8. ROUNDING EXAMPLES
190    println!("8. ROUNDING EXAMPLES");
191    println!("--------------------");
192    let usd_amount = Amount::<USD>::from_minor(12345); // $123.45
193    println!("Original: {}", usd_amount);
194    println!("Half Up: {}", usd_amount.round(RoundingMode::HalfUp));
195    println!("Half Down: {}", usd_amount.round(RoundingMode::HalfDown));
196    println!("Half Even: {}", usd_amount.round(RoundingMode::HalfEven));
197    println!("Floor: {}", usd_amount.round(RoundingMode::Floor));
198    println!("Ceiling: {}", usd_amount.round(RoundingMode::Ceiling));
199    println!();
200
201    // 9. CURRENCY METADATA
202    println!("9. CURRENCY METADATA");
203    println!("--------------------");
204    let currencies = [
205        ("USD", USD::CODE, USD::SYMBOL, USD::DECIMALS),
206        ("EUR", EUR::CODE, EUR::SYMBOL, EUR::DECIMALS),
207        ("JPY", JPY::CODE, JPY::SYMBOL, JPY::DECIMALS),
208        ("CNY", CNY::CODE, CNY::SYMBOL, CNY::DECIMALS),
209        ("BRL", BRL::CODE, BRL::SYMBOL, BRL::DECIMALS),
210        ("AED", AED::CODE, AED::SYMBOL, AED::DECIMALS),
211    ];
212
213    for (name, code, symbol, decimals) in currencies {
214        println!("{}: {} {} ({} decimals)", name, symbol, code, decimals);
215    }
216    println!();
217
218    // 10. TYPE SAFETY DEMONSTRATION
219    println!("10. TYPE SAFETY DEMONSTRATION");
220    println!("-----------------------------");
221    println!("✓ USD + USD = Valid");
222    println!("✓ EUR + EUR = Valid");
223    println!("✓ CAD + CAD = Valid");
224    println!("✗ USD + EUR = Compile Error!");
225    println!("✗ CAD + JPY = Compile Error!");
226    println!("✗ BRL + TRY = Compile Error!");
227    println!();
228
229    println!("=== Global Currencies Example Completed! ===");
230    println!("Total currencies supported: 30+");
231    println!("Regions covered: North America, Europe, Asia, South America, Africa, Middle East");
232    println!("Type safety: 100% compile-time currency mixing prevention");
233}
examples/custom_currency.rs (line 158)
99fn main() {
100    println!("=== Custom Currency Examples ===\n");
101
102    // ========================================
103    // Using Custom Fiat Currencies
104    // ========================================
105    println!("1. CUSTOM FIAT CURRENCIES");
106    println!("-------------------------");
107
108    let cad = Amount::<CAD>::from_major(100);
109    let chf = Amount::<CHF>::from_major(85);
110    let aud = Amount::<AUD>::from_major(150);
111
112    println!("Canadian Dollar: {}", cad);
113    println!("Swiss Franc:     {}", chf);
114    println!("Australian Dollar: {}", aud);
115
116    // Arithmetic works the same
117    let total_cad = cad + Amount::<CAD>::from_major(50);
118    println!("\nC$100 + C$50 = {}", total_cad);
119
120    // ========================================
121    // Currency Properties
122    // ========================================
123    println!("\n2. CURRENCY PROPERTIES");
124    println!("----------------------");
125
126    println!(
127        "CAD: code={}, symbol={}, decimals={}",
128        CAD::CODE,
129        CAD::SYMBOL,
130        CAD::DECIMALS
131    );
132    println!(
133        "CHF: code={}, symbol={}, decimals={}",
134        CHF::CODE,
135        CHF::SYMBOL,
136        CHF::DECIMALS
137    );
138    println!(
139        "DOGE: code={}, symbol={}, decimals={}",
140        DOGE::CODE,
141        DOGE::SYMBOL,
142        DOGE::DECIMALS
143    );
144    println!(
145        "GOLD: code={}, symbol={}, decimals={}",
146        GOLD::CODE,
147        GOLD::SYMBOL,
148        GOLD::DECIMALS
149    );
150
151    // ========================================
152    // Converting Between Custom Currencies
153    // ========================================
154    println!("\n3. CONVERTING CUSTOM CURRENCIES");
155    println!("--------------------------------");
156
157    let _cad_amount = Amount::<CAD>::from_major(100);
158    let cad_to_aud = Rate::<CAD, AUD>::new(1.08); // 1 CAD = 1.08 AUD
159
160    println!("Example: C$100 at rate {} CAD→AUD", cad_to_aud.value());
161
162    // ========================================
163    // Cryptocurrency Example
164    // ========================================
165    println!("\n4. CRYPTOCURRENCY (DOGECOIN)");
166    println!("-----------------------------");
167
168    // Dogecoin with 8 decimal places (like Bitcoin)
169    let doge = Amount::<DOGE>::from_minor(100_000_000); // 1 DOGE
170    println!("Amount: {} (1 DOGE)", doge);
171
172    let small_amount = Amount::<DOGE>::from_minor(12_345_678); // 0.12345678 DOGE
173    println!("Small amount: {} (0.12345678 DOGE)", small_amount);
174
175    let total = doge + small_amount;
176    println!("Total: {}", total);
177
178    // ========================================
179    // Video Game Currency
180    // ========================================
181    println!("\n5. VIDEO GAME CURRENCIES");
182    println!("------------------------");
183
184    // Gold coins (no fractional amounts)
185    let gold = Amount::<GOLD>::from_major(1000);
186    println!("Gold coins: {}", gold);
187
188    let loot = Amount::<GOLD>::from_major(150);
189    let total_gold = gold + loot;
190    println!(
191        "After looting: {} (was {}, found {})",
192        total_gold, gold, loot
193    );
194
195    // Premium gems (with fractional amounts for bonuses)
196    let gems = Amount::<GEMS>::from_major(50);
197    println!("\nPremium gems: {}", gems);
198
199    // 10% bonus
200    let bonus = (gems * 10) / 100;
201    println!("Bonus (10%): {}", bonus);
202
203    let total_gems = gems + bonus;
204    println!("Total with bonus: {}", total_gems);
205
206    // ========================================
207    // Loyalty Points System
208    // ========================================
209    println!("\n6. LOYALTY POINTS SYSTEM");
210    println!("------------------------");
211
212    let purchase = Amount::<POINTS>::from_major(100);
213    println!("Purchase: {}", purchase);
214
215    // Earn 5% back in points
216    let earn_rate = 5;
217    let points_earned = (purchase * earn_rate) / 100;
218    println!("Points earned ({}%): {}", earn_rate, points_earned);
219
220    // Accumulate points
221    let existing_points = Amount::<POINTS>::from_major(237);
222    let new_balance = existing_points + points_earned;
223    println!("\nPrevious balance: {}", existing_points);
224    println!("New balance: {}", new_balance);
225
226    // Redeem points
227    let redemption = Amount::<POINTS>::from_major(50);
228    let final_balance = new_balance - redemption;
229    println!("\nAfter redeeming {}: {}", redemption, final_balance);
230
231    // ========================================
232    // Exchange Rate Between Custom Currencies
233    // ========================================
234    println!("\n7. EXCHANGE RATES BETWEEN CUSTOM CURRENCIES");
235    println!("--------------------------------------------");
236
237    // Define exchange rates
238    let cad_to_aud = Rate::<CAD, AUD>::new(1.08); // 1 CAD = 1.08 AUD
239
240    let cad_amount = Amount::<CAD>::from_major(100);
241    println!("Canadian Dollars: {}", cad_amount);
242    println!("Exchange rate: 1 CAD = {} AUD", cad_to_aud.value());
243
244    let aud_amount = cad_amount.convert(&cad_to_aud);
245    println!("Australian Dollars: {}", aud_amount);
246
247    // ========================================
248    // Type Safety Still Works
249    // ========================================
250    println!("\n8. TYPE SAFETY");
251    println!("--------------");
252
253    println!("✓ Can add CAD + CAD");
254    println!("✓ Can add GOLD + GOLD");
255    println!("✗ Cannot add CAD + CHF (compile error!)");
256    println!("✗ Cannot add GOLD + GEMS (compile error!)");
257    println!("\nCustom currencies have the same type safety as built-in ones!");
258
259    // These would NOT compile:
260    // let invalid = cad + chf;      // Compile error: different currencies
261    // let invalid2 = gold + gems;   // Compile error: different currencies
262
263    // ========================================
264    // Rounding with Custom Currencies
265    // ========================================
266    println!("\n9. ROUNDING");
267    println!("-----------");
268
269    let cad = Amount::<CAD>::from_major(100) / 3; // C$33.333...
270    println!("CAD (exact): {}", cad);
271    println!("CAD (rounded): {}", cad.round(RoundingMode::HalfUp));
272
273    let doge = Amount::<DOGE>::from_minor(100_000_000) / 3; // 0.33333333 DOGE
274    println!("\nDOGE (exact): {}", doge);
275    println!("DOGE (rounded): {}", doge.round(RoundingMode::HalfUp));
276
277    let gold = Amount::<GOLD>::from_major(1000) / 3; // 333.333... coins
278    println!("\nGOLD (exact): {}", gold);
279    println!(
280        "GOLD (rounded): {} (no decimals)",
281        gold.round(RoundingMode::HalfUp)
282    );
283
284    // ========================================
285    // Real-World: Multi-Currency Wallet
286    // ========================================
287    println!("\n10. REAL-WORLD: MULTI-CURRENCY WALLET");
288    println!("--------------------------------------");
289
290    println!("Wallet balances:");
291    let cad_balance = Amount::<CAD>::from_major(500);
292    let aud_balance = Amount::<AUD>::from_major(300);
293    let chf_balance = Amount::<CHF>::from_major(200);
294
295    println!("  CAD: {}", cad_balance);
296    println!("  AUD: {}", aud_balance);
297    println!("  CHF: {}", chf_balance);
298
299    println!("\nTransaction: Spend C$50");
300    let new_cad = cad_balance - Amount::<CAD>::from_major(50);
301    println!("  New CAD balance: {}", new_cad);
302
303    println!("\nType system ensures you can't accidentally mix currencies!");
304
305    println!("\n=== All custom currency examples completed! ===");
306}
Source

pub fn try_from_decimal(rate: Decimal) -> MoneyResult<Self>

Tries to create a new exchange rate from a Decimal value.

This is useful when you already have a precise decimal rate. Returns an error if the rate is zero or negative.

§Examples
use typed_money::{Rate, USD, EUR};
use rust_decimal::Decimal;

let decimal_rate = Decimal::new(85, 2);  // 0.85
let rate = Rate::<USD, EUR>::try_from_decimal(decimal_rate)?;

// Invalid rates return an error
assert!(Rate::<USD, EUR>::try_from_decimal(Decimal::ZERO).is_err());
Source

pub fn from_decimal(rate: Decimal) -> Self

Creates a new exchange rate from a Decimal value.

§Panics

Panics if the rate is zero or negative. For a non-panicking version, use try_from_decimal.

§Examples
use typed_money::{Rate, USD, EUR};
use rust_decimal::Decimal;

let decimal_rate = Decimal::new(85, 2);  // 0.85
let rate = Rate::<USD, EUR>::from_decimal(decimal_rate);
Source

pub const fn value(&self) -> &Decimal

Returns the exchange rate value.

§Examples
use typed_money::{Rate, USD, EUR};

let rate = Rate::<USD, EUR>::new(0.85);
println!("Rate: {}", rate.value());
Examples found in repository?
examples/conversions.rs (line 38)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}
More examples
Hide additional examples
examples/global_currencies.rs (line 165)
51fn main() {
52    println!("=== Typed Money - Global Currencies Example ===\n");
53
54    // 1. MAJOR FIAT CURRENCIES
55    println!("1. MAJOR FIAT CURRENCIES");
56    println!("------------------------");
57    let usd = Amount::<USD>::from_major(100);
58    let cad = Amount::<CAD>::from_major(135);
59    let chf = Amount::<CHF>::from_major(90);
60    let aud = Amount::<AUD>::from_major(150);
61    let nzd = Amount::<NZD>::from_major(160);
62
63    println!("USD: {} ({} decimals)", usd, USD::DECIMALS);
64    println!("CAD: {} ({} decimals)", cad, CAD::DECIMALS);
65    println!("CHF: {} ({} decimals)", chf, CHF::DECIMALS);
66    println!("AUD: {} ({} decimals)", aud, AUD::DECIMALS);
67    println!("NZD: {} ({} decimals)", nzd, NZD::DECIMALS);
68    println!();
69
70    // 2. ASIAN CURRENCIES
71    println!("2. ASIAN CURRENCIES");
72    println!("-------------------");
73    let cny = Amount::<CNY>::from_major(720);
74    let krw = Amount::<KRW>::from_major(130_000);
75    let sgd = Amount::<SGD>::from_major(135);
76    let hkd = Amount::<HKD>::from_major(780);
77    let twd = Amount::<TWD>::from_major(3100);
78    let inr = Amount::<INR>::from_major(8300);
79
80    println!("CNY: {} ({} decimals)", cny, CNY::DECIMALS);
81    println!("KRW: {} ({} decimals)", krw, KRW::DECIMALS);
82    println!("SGD: {} ({} decimals)", sgd, SGD::DECIMALS);
83    println!("HKD: {} ({} decimals)", hkd, HKD::DECIMALS);
84    println!("TWD: {} ({} decimals)", twd, TWD::DECIMALS);
85    println!("INR: {} ({} decimals)", inr, INR::DECIMALS);
86    println!();
87
88    // 3. EUROPEAN CURRENCIES
89    println!("3. EUROPEAN CURRENCIES");
90    println!("----------------------");
91    let eur = Amount::<EUR>::from_major(85);
92    let gbp = Amount::<GBP>::from_major(75);
93    let sek = Amount::<SEK>::from_major(1050);
94    let nok = Amount::<NOK>::from_major(1100);
95    let dkk = Amount::<DKK>::from_major(650);
96    let pln = Amount::<PLN>::from_major(400);
97    let czk = Amount::<CZK>::from_major(2300);
98    let huf = Amount::<HUF>::from_major(36_000);
99
100    println!("EUR: {} ({} decimals)", eur, EUR::DECIMALS);
101    println!("GBP: {} ({} decimals)", gbp, GBP::DECIMALS);
102    println!("SEK: {} ({} decimals)", sek, SEK::DECIMALS);
103    println!("NOK: {} ({} decimals)", nok, NOK::DECIMALS);
104    println!("DKK: {} ({} decimals)", dkk, DKK::DECIMALS);
105    println!("PLN: {} ({} decimals)", pln, PLN::DECIMALS);
106    println!("CZK: {} ({} decimals)", czk, CZK::DECIMALS);
107    println!("HUF: {} ({} decimals)", huf, HUF::DECIMALS);
108    println!();
109
110    // 4. AMERICAN CURRENCIES
111    println!("4. AMERICAN CURRENCIES");
112    println!("----------------------");
113    let brl = Amount::<BRL>::from_major(500);
114    let mxn = Amount::<MXN>::from_major(1700);
115    let ars = Amount::<ARS>::from_major(85_000);
116    let clp = Amount::<CLP>::from_major(90_000);
117
118    println!("BRL: {} ({} decimals)", brl, BRL::DECIMALS);
119    println!("MXN: {} ({} decimals)", mxn, MXN::DECIMALS);
120    println!("ARS: {} ({} decimals)", ars, ARS::DECIMALS);
121    println!("CLP: {} ({} decimals)", clp, CLP::DECIMALS);
122    println!();
123
124    // 5. AFRICAN/MIDDLE EASTERN CURRENCIES
125    println!("5. AFRICAN/MIDDLE EASTERN CURRENCIES");
126    println!("------------------------------------");
127    let zar = Amount::<ZAR>::from_major(1800);
128    let egp = Amount::<EGP>::from_major(3100);
129    let aed = Amount::<AED>::from_major(370);
130    let sar = Amount::<SAR>::from_major(375);
131    let ils = Amount::<ILS>::from_major(360);
132    let try_currency = Amount::<TRY>::from_major(3000);
133
134    println!("ZAR: {} ({} decimals)", zar, ZAR::DECIMALS);
135    println!("EGP: {} ({} decimals)", egp, EGP::DECIMALS);
136    println!("AED: {} ({} decimals)", aed, AED::DECIMALS);
137    println!("SAR: {} ({} decimals)", sar, SAR::DECIMALS);
138    println!("ILS: {} ({} decimals)", ils, ILS::DECIMALS);
139    println!("TRY: {} ({} decimals)", try_currency, TRY::DECIMALS);
140    println!();
141
142    // 6. CRYPTOCURRENCIES
143    println!("6. CRYPTOCURRENCIES");
144    println!("-------------------");
145    let btc = Amount::<BTC>::from_minor(100_000_000); // 1.00000000 BTC
146    let eth = Amount::<ETH>::from_minor(1_000_000_000_000_000_000); // 1.000000000000000000 ETH
147
148    println!("BTC: {} ({} decimals)", btc, BTC::DECIMALS);
149    println!("ETH: {} ({} decimals)", eth, ETH::DECIMALS);
150    println!();
151
152    // 7. CURRENCY CONVERSION EXAMPLES
153    println!("7. CURRENCY CONVERSION EXAMPLES");
154    println!("-------------------------------");
155
156    // USD to EUR
157    let usd_to_eur = Rate::<USD, EUR>::new(0.85)
158        .with_timestamp_unix_secs(1_700_000_000)
159        .with_source("ECB");
160    let eur_converted = usd.convert(&usd_to_eur);
161    println!(
162        "USD to EUR: {} → {} (rate: {})",
163        usd,
164        eur_converted,
165        usd_to_eur.value()
166    );
167
168    // EUR to GBP
169    let eur_to_gbp = Rate::<EUR, GBP>::new(0.87);
170    let gbp_converted = eur_converted.convert(&eur_to_gbp);
171    println!(
172        "EUR to GBP: {} → {} (rate: {})",
173        eur_converted,
174        gbp_converted,
175        eur_to_gbp.value()
176    );
177
178    // USD to JPY
179    let usd_to_jpy = Rate::<USD, JPY>::new(150.0);
180    let jpy_converted = usd.convert(&usd_to_jpy);
181    println!(
182        "USD to JPY: {} → {} (rate: {})",
183        usd,
184        jpy_converted,
185        usd_to_jpy.value()
186    );
187    println!();
188
189    // 8. ROUNDING EXAMPLES
190    println!("8. ROUNDING EXAMPLES");
191    println!("--------------------");
192    let usd_amount = Amount::<USD>::from_minor(12345); // $123.45
193    println!("Original: {}", usd_amount);
194    println!("Half Up: {}", usd_amount.round(RoundingMode::HalfUp));
195    println!("Half Down: {}", usd_amount.round(RoundingMode::HalfDown));
196    println!("Half Even: {}", usd_amount.round(RoundingMode::HalfEven));
197    println!("Floor: {}", usd_amount.round(RoundingMode::Floor));
198    println!("Ceiling: {}", usd_amount.round(RoundingMode::Ceiling));
199    println!();
200
201    // 9. CURRENCY METADATA
202    println!("9. CURRENCY METADATA");
203    println!("--------------------");
204    let currencies = [
205        ("USD", USD::CODE, USD::SYMBOL, USD::DECIMALS),
206        ("EUR", EUR::CODE, EUR::SYMBOL, EUR::DECIMALS),
207        ("JPY", JPY::CODE, JPY::SYMBOL, JPY::DECIMALS),
208        ("CNY", CNY::CODE, CNY::SYMBOL, CNY::DECIMALS),
209        ("BRL", BRL::CODE, BRL::SYMBOL, BRL::DECIMALS),
210        ("AED", AED::CODE, AED::SYMBOL, AED::DECIMALS),
211    ];
212
213    for (name, code, symbol, decimals) in currencies {
214        println!("{}: {} {} ({} decimals)", name, symbol, code, decimals);
215    }
216    println!();
217
218    // 10. TYPE SAFETY DEMONSTRATION
219    println!("10. TYPE SAFETY DEMONSTRATION");
220    println!("-----------------------------");
221    println!("✓ USD + USD = Valid");
222    println!("✓ EUR + EUR = Valid");
223    println!("✓ CAD + CAD = Valid");
224    println!("✗ USD + EUR = Compile Error!");
225    println!("✗ CAD + JPY = Compile Error!");
226    println!("✗ BRL + TRY = Compile Error!");
227    println!();
228
229    println!("=== Global Currencies Example Completed! ===");
230    println!("Total currencies supported: 30+");
231    println!("Regions covered: North America, Europe, Asia, South America, Africa, Middle East");
232    println!("Type safety: 100% compile-time currency mixing prevention");
233}
examples/custom_currency.rs (line 160)
99fn main() {
100    println!("=== Custom Currency Examples ===\n");
101
102    // ========================================
103    // Using Custom Fiat Currencies
104    // ========================================
105    println!("1. CUSTOM FIAT CURRENCIES");
106    println!("-------------------------");
107
108    let cad = Amount::<CAD>::from_major(100);
109    let chf = Amount::<CHF>::from_major(85);
110    let aud = Amount::<AUD>::from_major(150);
111
112    println!("Canadian Dollar: {}", cad);
113    println!("Swiss Franc:     {}", chf);
114    println!("Australian Dollar: {}", aud);
115
116    // Arithmetic works the same
117    let total_cad = cad + Amount::<CAD>::from_major(50);
118    println!("\nC$100 + C$50 = {}", total_cad);
119
120    // ========================================
121    // Currency Properties
122    // ========================================
123    println!("\n2. CURRENCY PROPERTIES");
124    println!("----------------------");
125
126    println!(
127        "CAD: code={}, symbol={}, decimals={}",
128        CAD::CODE,
129        CAD::SYMBOL,
130        CAD::DECIMALS
131    );
132    println!(
133        "CHF: code={}, symbol={}, decimals={}",
134        CHF::CODE,
135        CHF::SYMBOL,
136        CHF::DECIMALS
137    );
138    println!(
139        "DOGE: code={}, symbol={}, decimals={}",
140        DOGE::CODE,
141        DOGE::SYMBOL,
142        DOGE::DECIMALS
143    );
144    println!(
145        "GOLD: code={}, symbol={}, decimals={}",
146        GOLD::CODE,
147        GOLD::SYMBOL,
148        GOLD::DECIMALS
149    );
150
151    // ========================================
152    // Converting Between Custom Currencies
153    // ========================================
154    println!("\n3. CONVERTING CUSTOM CURRENCIES");
155    println!("--------------------------------");
156
157    let _cad_amount = Amount::<CAD>::from_major(100);
158    let cad_to_aud = Rate::<CAD, AUD>::new(1.08); // 1 CAD = 1.08 AUD
159
160    println!("Example: C$100 at rate {} CAD→AUD", cad_to_aud.value());
161
162    // ========================================
163    // Cryptocurrency Example
164    // ========================================
165    println!("\n4. CRYPTOCURRENCY (DOGECOIN)");
166    println!("-----------------------------");
167
168    // Dogecoin with 8 decimal places (like Bitcoin)
169    let doge = Amount::<DOGE>::from_minor(100_000_000); // 1 DOGE
170    println!("Amount: {} (1 DOGE)", doge);
171
172    let small_amount = Amount::<DOGE>::from_minor(12_345_678); // 0.12345678 DOGE
173    println!("Small amount: {} (0.12345678 DOGE)", small_amount);
174
175    let total = doge + small_amount;
176    println!("Total: {}", total);
177
178    // ========================================
179    // Video Game Currency
180    // ========================================
181    println!("\n5. VIDEO GAME CURRENCIES");
182    println!("------------------------");
183
184    // Gold coins (no fractional amounts)
185    let gold = Amount::<GOLD>::from_major(1000);
186    println!("Gold coins: {}", gold);
187
188    let loot = Amount::<GOLD>::from_major(150);
189    let total_gold = gold + loot;
190    println!(
191        "After looting: {} (was {}, found {})",
192        total_gold, gold, loot
193    );
194
195    // Premium gems (with fractional amounts for bonuses)
196    let gems = Amount::<GEMS>::from_major(50);
197    println!("\nPremium gems: {}", gems);
198
199    // 10% bonus
200    let bonus = (gems * 10) / 100;
201    println!("Bonus (10%): {}", bonus);
202
203    let total_gems = gems + bonus;
204    println!("Total with bonus: {}", total_gems);
205
206    // ========================================
207    // Loyalty Points System
208    // ========================================
209    println!("\n6. LOYALTY POINTS SYSTEM");
210    println!("------------------------");
211
212    let purchase = Amount::<POINTS>::from_major(100);
213    println!("Purchase: {}", purchase);
214
215    // Earn 5% back in points
216    let earn_rate = 5;
217    let points_earned = (purchase * earn_rate) / 100;
218    println!("Points earned ({}%): {}", earn_rate, points_earned);
219
220    // Accumulate points
221    let existing_points = Amount::<POINTS>::from_major(237);
222    let new_balance = existing_points + points_earned;
223    println!("\nPrevious balance: {}", existing_points);
224    println!("New balance: {}", new_balance);
225
226    // Redeem points
227    let redemption = Amount::<POINTS>::from_major(50);
228    let final_balance = new_balance - redemption;
229    println!("\nAfter redeeming {}: {}", redemption, final_balance);
230
231    // ========================================
232    // Exchange Rate Between Custom Currencies
233    // ========================================
234    println!("\n7. EXCHANGE RATES BETWEEN CUSTOM CURRENCIES");
235    println!("--------------------------------------------");
236
237    // Define exchange rates
238    let cad_to_aud = Rate::<CAD, AUD>::new(1.08); // 1 CAD = 1.08 AUD
239
240    let cad_amount = Amount::<CAD>::from_major(100);
241    println!("Canadian Dollars: {}", cad_amount);
242    println!("Exchange rate: 1 CAD = {} AUD", cad_to_aud.value());
243
244    let aud_amount = cad_amount.convert(&cad_to_aud);
245    println!("Australian Dollars: {}", aud_amount);
246
247    // ========================================
248    // Type Safety Still Works
249    // ========================================
250    println!("\n8. TYPE SAFETY");
251    println!("--------------");
252
253    println!("✓ Can add CAD + CAD");
254    println!("✓ Can add GOLD + GOLD");
255    println!("✗ Cannot add CAD + CHF (compile error!)");
256    println!("✗ Cannot add GOLD + GEMS (compile error!)");
257    println!("\nCustom currencies have the same type safety as built-in ones!");
258
259    // These would NOT compile:
260    // let invalid = cad + chf;      // Compile error: different currencies
261    // let invalid2 = gold + gems;   // Compile error: different currencies
262
263    // ========================================
264    // Rounding with Custom Currencies
265    // ========================================
266    println!("\n9. ROUNDING");
267    println!("-----------");
268
269    let cad = Amount::<CAD>::from_major(100) / 3; // C$33.333...
270    println!("CAD (exact): {}", cad);
271    println!("CAD (rounded): {}", cad.round(RoundingMode::HalfUp));
272
273    let doge = Amount::<DOGE>::from_minor(100_000_000) / 3; // 0.33333333 DOGE
274    println!("\nDOGE (exact): {}", doge);
275    println!("DOGE (rounded): {}", doge.round(RoundingMode::HalfUp));
276
277    let gold = Amount::<GOLD>::from_major(1000) / 3; // 333.333... coins
278    println!("\nGOLD (exact): {}", gold);
279    println!(
280        "GOLD (rounded): {} (no decimals)",
281        gold.round(RoundingMode::HalfUp)
282    );
283
284    // ========================================
285    // Real-World: Multi-Currency Wallet
286    // ========================================
287    println!("\n10. REAL-WORLD: MULTI-CURRENCY WALLET");
288    println!("--------------------------------------");
289
290    println!("Wallet balances:");
291    let cad_balance = Amount::<CAD>::from_major(500);
292    let aud_balance = Amount::<AUD>::from_major(300);
293    let chf_balance = Amount::<CHF>::from_major(200);
294
295    println!("  CAD: {}", cad_balance);
296    println!("  AUD: {}", aud_balance);
297    println!("  CHF: {}", chf_balance);
298
299    println!("\nTransaction: Spend C$50");
300    let new_cad = cad_balance - Amount::<CAD>::from_major(50);
301    println!("  New CAD balance: {}", new_cad);
302
303    println!("\nType system ensures you can't accidentally mix currencies!");
304
305    println!("\n=== All custom currency examples completed! ===");
306}
examples/error_handling.rs (line 82)
11fn main() {
12    println!("=== Error Handling Examples ===\n");
13
14    // ========================================
15    // Parse Errors
16    // ========================================
17    println!("1. PARSING ERRORS");
18    println!("-----------------");
19
20    // Valid parsing
21    match Amount::<USD>::from_str("123.45") {
22        Ok(amount) => println!("✓ Parsed: {}", amount),
23        Err(e) => println!("✗ Error: {}", e),
24    }
25
26    // Invalid formats
27    let invalid_inputs = vec!["invalid", "12.34.56", "abc123", "", "  "];
28
29    println!("\nInvalid inputs:");
30    for input in invalid_inputs {
31        match Amount::<USD>::from_str(input) {
32            Ok(amount) => println!("  '{}' → {}", input, amount),
33            Err(MoneyError::ParseError { input: inp, .. }) => {
34                println!("  '{}' → Parse error (input: '{}')", input, inp);
35            }
36            Err(e) => println!("  '{}' → Error: {}", input, e),
37        }
38    }
39
40    // ========================================
41    // Precision Errors
42    // ========================================
43    println!("\n2. PRECISION ERRORS");
44    println!("-------------------");
45
46    // Division creates excess precision
47    let amount = Amount::<USD>::from_major(10) / 3; // $3.333...
48    println!("After division: {}", amount);
49    println!("Decimal places: {}", amount.precision());
50    println!("Currency expects: {}", Amount::<USD>::currency_precision());
51
52    // Check for precision issues
53    match amount.check_precision() {
54        Ok(()) => println!("✓ Precision OK"),
55        Err(MoneyError::PrecisionError {
56            expected,
57            actual,
58            suggestion,
59            ..
60        }) => {
61            println!("✗ Precision error:");
62            println!("  Expected: {} decimals", expected);
63            println!("  Actual: {} decimals", actual);
64            println!("  Suggestion: {}", suggestion);
65
66            // Recover by normalizing
67            let normalized = amount.normalize();
68            println!("\n✓ After normalizing: {}", normalized);
69            println!("  Precision OK: {}", normalized.check_precision().is_ok());
70        }
71        Err(e) => println!("✗ Unexpected error: {}", e),
72    }
73
74    // ========================================
75    // Invalid Rate Errors
76    // ========================================
77    println!("\n3. INVALID RATE ERRORS");
78    println!("----------------------");
79
80    // Valid rate
81    match Rate::<USD, EUR>::try_new(0.85) {
82        Ok(rate) => println!("✓ Valid rate: {}", rate.value()),
83        Err(e) => println!("✗ Error: {}", e),
84    }
85
86    // Invalid rates
87    let invalid_rates = vec![
88        ("negative", -1.0),
89        ("zero", 0.0),
90        ("NaN", f64::NAN),
91        ("infinity", f64::INFINITY),
92    ];
93
94    println!("\nInvalid rates:");
95    for (desc, value) in invalid_rates {
96        match Rate::<USD, EUR>::try_new(value) {
97            Ok(rate) => println!(
98                "  {} ({}) → Unexpected success: {}",
99                desc,
100                value,
101                rate.value()
102            ),
103            Err(MoneyError::InvalidRate { reason, .. }) => {
104                println!("  {} ({}) → {}", desc, value, reason);
105            }
106            Err(e) => println!("  {} ({}) → Error: {}", desc, value, e),
107        }
108    }
109
110    // ========================================
111    // Error Suggestions
112    // ========================================
113    println!("\n4. ERROR RECOVERY SUGGESTIONS");
114    println!("------------------------------");
115
116    let errors = vec![
117        MoneyError::PrecisionError {
118            currency: "USD",
119            expected: 2,
120            actual: 5,
121            suggestion: "Use normalize() or round() to adjust precision".to_string(),
122        },
123        MoneyError::InvalidRate {
124            value: "-1.0".to_string(),
125            reason: "Rate must be positive".to_string(),
126        },
127        MoneyError::ParseError {
128            input: "abc".to_string(),
129            expected_currency: Some("USD"),
130            reason: "Invalid number format".to_string(),
131        },
132    ];
133
134    for error in errors {
135        println!("\nError: {}", error);
136        println!("Suggestion: {}", error.suggestion());
137        if let Some(currency) = error.currency() {
138            println!("Currency: {}", currency);
139        }
140    }
141
142    // ========================================
143    // Safe Division
144    // ========================================
145    println!("\n5. SAFE DIVISION");
146    println!("----------------");
147
148    let amount = Amount::<USD>::from_major(100);
149
150    // Division by zero is handled
151    let divisor = 0;
152    println!("Dividing {} by {}...", amount, divisor);
153
154    if divisor == 0 {
155        println!("✗ Cannot divide by zero!");
156        println!("  Handled before attempting division");
157    } else {
158        let result = amount / divisor;
159        println!("✓ Result: {}", result);
160    }
161
162    // Safe division with non-zero
163    let safe_divisor = 3;
164    let result = amount / safe_divisor;
165    println!("\nDividing {} by {}: {}", amount, safe_divisor, result);
166
167    // ========================================
168    // Pattern Matching on Errors
169    // ========================================
170    println!("\n6. PATTERN MATCHING");
171    println!("-------------------");
172
173    fn parse_and_handle(input: &str) -> MoneyResult<Amount<USD>> {
174        Amount::<USD>::from_str(input)
175    }
176
177    let inputs = vec!["123.45", "invalid", "999.99"];
178
179    for input in inputs {
180        print!("Parsing '{}': ", input);
181
182        match parse_and_handle(input) {
183            Ok(amount) => {
184                println!("✓ Success: {}", amount);
185            }
186            Err(MoneyError::ParseError { input, reason, .. }) => {
187                println!("✗ Parse error");
188                println!("  Input: '{}'", input);
189                println!("  Reason: {}", reason);
190            }
191            Err(e) => {
192                println!("✗ Other error: {}", e);
193            }
194        }
195    }
196
197    // ========================================
198    // Error Propagation with ?
199    // ========================================
200    println!("\n7. ERROR PROPAGATION");
201    println!("--------------------");
202
203    fn calculate_total(price_str: &str, quantity: i64) -> MoneyResult<Amount<USD>> {
204        let price = Amount::<USD>::from_str(price_str)?;
205        let total = price * quantity;
206        total.check_precision()?;
207        Ok(total)
208    }
209
210    match calculate_total("29.99", 3) {
211        Ok(total) => println!("✓ Total: {}", total),
212        Err(e) => println!("✗ Error: {}", e),
213    }
214
215    match calculate_total("invalid", 3) {
216        Ok(total) => println!("✓ Total: {}", total),
217        Err(e) => println!("✗ Error: {}", e),
218    }
219
220    // ========================================
221    // Recovering from Errors
222    // ========================================
223    println!("\n8. ERROR RECOVERY");
224    println!("-----------------");
225
226    fn parse_with_fallback(input: &str, fallback: Amount<USD>) -> Amount<USD> {
227        Amount::<USD>::from_str(input).unwrap_or(fallback)
228    }
229
230    let fallback = Amount::<USD>::from_major(0);
231
232    let inputs = vec!["123.45", "invalid", "67.89"];
233    for input in inputs {
234        let amount = parse_with_fallback(input, fallback);
235        println!("'{}' → {}", input, amount);
236    }
237
238    // ========================================
239    // Validation Before Operations
240    // ========================================
241    println!("\n9. VALIDATION");
242    println!("-------------");
243
244    fn safe_divide(amount: Amount<USD>, divisor: i64) -> MoneyResult<Amount<USD>> {
245        if divisor == 0 {
246            return Err(MoneyError::InvalidAmount {
247                currency: Some("USD"),
248                reason: "Cannot divide by zero".to_string(),
249            });
250        }
251
252        let result = amount / divisor;
253
254        // Check precision after division
255        result.check_precision()?;
256
257        Ok(result)
258    }
259
260    let amount = Amount::<USD>::from_major(100);
261
262    match safe_divide(amount, 0) {
263        Ok(result) => println!("  Division by 0: {}", result),
264        Err(e) => println!("  Division by 0: Error - {}", e),
265    }
266
267    match safe_divide(amount, 3) {
268        Ok(result) => println!("  Division by 3: {}", result),
269        Err(e) => println!("  Division by 3: Error - {}", e),
270    }
271
272    // ========================================
273    // Real-World: Parsing User Input
274    // ========================================
275    println!("\n10. REAL-WORLD: PARSING USER INPUT");
276    println!("-----------------------------------");
277
278    fn process_payment(amount_str: &str) -> MoneyResult<String> {
279        // Parse the amount
280        let amount = Amount::<USD>::from_str(amount_str)?;
281
282        // Validate it's positive
283        if amount.to_minor() <= 0 {
284            return Err(MoneyError::InvalidAmount {
285                currency: Some("USD"),
286                reason: "Payment amount must be positive".to_string(),
287            });
288        }
289
290        // Process the payment
291        let fee = (amount * 3) / 100; // 3% fee
292        let total = amount + fee;
293
294        Ok(format!(
295            "Payment: {}, Fee: {}, Total: {}",
296            amount, fee, total
297        ))
298    }
299
300    let test_inputs = vec!["100.00", "0", "-50", "abc", "250.50"];
301
302    for input in test_inputs {
303        println!("\nProcessing payment: '{}'", input);
304        match process_payment(input) {
305            Ok(summary) => println!("  ✓ {}", summary),
306            Err(e) => {
307                println!("  ✗ Error: {}", e);
308                let suggestion = e.suggestion();
309                println!("    Hint: {}", suggestion);
310            }
311        }
312    }
313
314    // ========================================
315    // Rounding to Fix Precision
316    // ========================================
317    println!("\n11. FIXING PRECISION WITH ROUNDING");
318    println!("-----------------------------------");
319
320    let amount = Amount::<USD>::from_major(10) / 3; // Creates excess precision
321
322    println!("Original: {}", amount);
323    println!(
324        "Precision check: {}",
325        if amount.check_precision().is_ok() {
326            "✓ OK"
327        } else {
328            "✗ Excess precision"
329        }
330    );
331
332    // Fix with rounding
333    let rounded = amount.round(RoundingMode::HalfUp);
334    println!("\nRounded: {}", rounded);
335    println!(
336        "Precision check: {}",
337        if rounded.check_precision().is_ok() {
338            "✓ OK"
339        } else {
340            "✗ Excess precision"
341        }
342    );
343
344    // Or normalize (uses banker's rounding)
345    let normalized = amount.normalize();
346    println!("\nNormalized: {}", normalized);
347    println!(
348        "Precision check: {}",
349        if normalized.check_precision().is_ok() {
350            "✓ OK"
351        } else {
352            "✗ Excess precision"
353        }
354    );
355
356    println!("\n=== All error handling examples completed! ===");
357}
Source

pub const fn timestamp_unix_secs(&self) -> Option<u64>

Returns the optional UNIX timestamp (seconds) metadata.

Examples found in repository?
examples/conversions.rs (line 114)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}
Source

pub const fn source(&self) -> Option<&'static str>

Returns the optional static source identifier metadata.

Examples found in repository?
examples/conversions.rs (line 115)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}
Source

pub const fn with_timestamp_unix_secs(self, timestamp_unix_secs: u64) -> Self

Returns a new Rate with the given UNIX timestamp (seconds) metadata set.

Existing metadata values not provided by this method are preserved.

Examples found in repository?
examples/conversions.rs (line 110)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}
More examples
Hide additional examples
examples/global_currencies.rs (line 158)
51fn main() {
52    println!("=== Typed Money - Global Currencies Example ===\n");
53
54    // 1. MAJOR FIAT CURRENCIES
55    println!("1. MAJOR FIAT CURRENCIES");
56    println!("------------------------");
57    let usd = Amount::<USD>::from_major(100);
58    let cad = Amount::<CAD>::from_major(135);
59    let chf = Amount::<CHF>::from_major(90);
60    let aud = Amount::<AUD>::from_major(150);
61    let nzd = Amount::<NZD>::from_major(160);
62
63    println!("USD: {} ({} decimals)", usd, USD::DECIMALS);
64    println!("CAD: {} ({} decimals)", cad, CAD::DECIMALS);
65    println!("CHF: {} ({} decimals)", chf, CHF::DECIMALS);
66    println!("AUD: {} ({} decimals)", aud, AUD::DECIMALS);
67    println!("NZD: {} ({} decimals)", nzd, NZD::DECIMALS);
68    println!();
69
70    // 2. ASIAN CURRENCIES
71    println!("2. ASIAN CURRENCIES");
72    println!("-------------------");
73    let cny = Amount::<CNY>::from_major(720);
74    let krw = Amount::<KRW>::from_major(130_000);
75    let sgd = Amount::<SGD>::from_major(135);
76    let hkd = Amount::<HKD>::from_major(780);
77    let twd = Amount::<TWD>::from_major(3100);
78    let inr = Amount::<INR>::from_major(8300);
79
80    println!("CNY: {} ({} decimals)", cny, CNY::DECIMALS);
81    println!("KRW: {} ({} decimals)", krw, KRW::DECIMALS);
82    println!("SGD: {} ({} decimals)", sgd, SGD::DECIMALS);
83    println!("HKD: {} ({} decimals)", hkd, HKD::DECIMALS);
84    println!("TWD: {} ({} decimals)", twd, TWD::DECIMALS);
85    println!("INR: {} ({} decimals)", inr, INR::DECIMALS);
86    println!();
87
88    // 3. EUROPEAN CURRENCIES
89    println!("3. EUROPEAN CURRENCIES");
90    println!("----------------------");
91    let eur = Amount::<EUR>::from_major(85);
92    let gbp = Amount::<GBP>::from_major(75);
93    let sek = Amount::<SEK>::from_major(1050);
94    let nok = Amount::<NOK>::from_major(1100);
95    let dkk = Amount::<DKK>::from_major(650);
96    let pln = Amount::<PLN>::from_major(400);
97    let czk = Amount::<CZK>::from_major(2300);
98    let huf = Amount::<HUF>::from_major(36_000);
99
100    println!("EUR: {} ({} decimals)", eur, EUR::DECIMALS);
101    println!("GBP: {} ({} decimals)", gbp, GBP::DECIMALS);
102    println!("SEK: {} ({} decimals)", sek, SEK::DECIMALS);
103    println!("NOK: {} ({} decimals)", nok, NOK::DECIMALS);
104    println!("DKK: {} ({} decimals)", dkk, DKK::DECIMALS);
105    println!("PLN: {} ({} decimals)", pln, PLN::DECIMALS);
106    println!("CZK: {} ({} decimals)", czk, CZK::DECIMALS);
107    println!("HUF: {} ({} decimals)", huf, HUF::DECIMALS);
108    println!();
109
110    // 4. AMERICAN CURRENCIES
111    println!("4. AMERICAN CURRENCIES");
112    println!("----------------------");
113    let brl = Amount::<BRL>::from_major(500);
114    let mxn = Amount::<MXN>::from_major(1700);
115    let ars = Amount::<ARS>::from_major(85_000);
116    let clp = Amount::<CLP>::from_major(90_000);
117
118    println!("BRL: {} ({} decimals)", brl, BRL::DECIMALS);
119    println!("MXN: {} ({} decimals)", mxn, MXN::DECIMALS);
120    println!("ARS: {} ({} decimals)", ars, ARS::DECIMALS);
121    println!("CLP: {} ({} decimals)", clp, CLP::DECIMALS);
122    println!();
123
124    // 5. AFRICAN/MIDDLE EASTERN CURRENCIES
125    println!("5. AFRICAN/MIDDLE EASTERN CURRENCIES");
126    println!("------------------------------------");
127    let zar = Amount::<ZAR>::from_major(1800);
128    let egp = Amount::<EGP>::from_major(3100);
129    let aed = Amount::<AED>::from_major(370);
130    let sar = Amount::<SAR>::from_major(375);
131    let ils = Amount::<ILS>::from_major(360);
132    let try_currency = Amount::<TRY>::from_major(3000);
133
134    println!("ZAR: {} ({} decimals)", zar, ZAR::DECIMALS);
135    println!("EGP: {} ({} decimals)", egp, EGP::DECIMALS);
136    println!("AED: {} ({} decimals)", aed, AED::DECIMALS);
137    println!("SAR: {} ({} decimals)", sar, SAR::DECIMALS);
138    println!("ILS: {} ({} decimals)", ils, ILS::DECIMALS);
139    println!("TRY: {} ({} decimals)", try_currency, TRY::DECIMALS);
140    println!();
141
142    // 6. CRYPTOCURRENCIES
143    println!("6. CRYPTOCURRENCIES");
144    println!("-------------------");
145    let btc = Amount::<BTC>::from_minor(100_000_000); // 1.00000000 BTC
146    let eth = Amount::<ETH>::from_minor(1_000_000_000_000_000_000); // 1.000000000000000000 ETH
147
148    println!("BTC: {} ({} decimals)", btc, BTC::DECIMALS);
149    println!("ETH: {} ({} decimals)", eth, ETH::DECIMALS);
150    println!();
151
152    // 7. CURRENCY CONVERSION EXAMPLES
153    println!("7. CURRENCY CONVERSION EXAMPLES");
154    println!("-------------------------------");
155
156    // USD to EUR
157    let usd_to_eur = Rate::<USD, EUR>::new(0.85)
158        .with_timestamp_unix_secs(1_700_000_000)
159        .with_source("ECB");
160    let eur_converted = usd.convert(&usd_to_eur);
161    println!(
162        "USD to EUR: {} → {} (rate: {})",
163        usd,
164        eur_converted,
165        usd_to_eur.value()
166    );
167
168    // EUR to GBP
169    let eur_to_gbp = Rate::<EUR, GBP>::new(0.87);
170    let gbp_converted = eur_converted.convert(&eur_to_gbp);
171    println!(
172        "EUR to GBP: {} → {} (rate: {})",
173        eur_converted,
174        gbp_converted,
175        eur_to_gbp.value()
176    );
177
178    // USD to JPY
179    let usd_to_jpy = Rate::<USD, JPY>::new(150.0);
180    let jpy_converted = usd.convert(&usd_to_jpy);
181    println!(
182        "USD to JPY: {} → {} (rate: {})",
183        usd,
184        jpy_converted,
185        usd_to_jpy.value()
186    );
187    println!();
188
189    // 8. ROUNDING EXAMPLES
190    println!("8. ROUNDING EXAMPLES");
191    println!("--------------------");
192    let usd_amount = Amount::<USD>::from_minor(12345); // $123.45
193    println!("Original: {}", usd_amount);
194    println!("Half Up: {}", usd_amount.round(RoundingMode::HalfUp));
195    println!("Half Down: {}", usd_amount.round(RoundingMode::HalfDown));
196    println!("Half Even: {}", usd_amount.round(RoundingMode::HalfEven));
197    println!("Floor: {}", usd_amount.round(RoundingMode::Floor));
198    println!("Ceiling: {}", usd_amount.round(RoundingMode::Ceiling));
199    println!();
200
201    // 9. CURRENCY METADATA
202    println!("9. CURRENCY METADATA");
203    println!("--------------------");
204    let currencies = [
205        ("USD", USD::CODE, USD::SYMBOL, USD::DECIMALS),
206        ("EUR", EUR::CODE, EUR::SYMBOL, EUR::DECIMALS),
207        ("JPY", JPY::CODE, JPY::SYMBOL, JPY::DECIMALS),
208        ("CNY", CNY::CODE, CNY::SYMBOL, CNY::DECIMALS),
209        ("BRL", BRL::CODE, BRL::SYMBOL, BRL::DECIMALS),
210        ("AED", AED::CODE, AED::SYMBOL, AED::DECIMALS),
211    ];
212
213    for (name, code, symbol, decimals) in currencies {
214        println!("{}: {} {} ({} decimals)", name, symbol, code, decimals);
215    }
216    println!();
217
218    // 10. TYPE SAFETY DEMONSTRATION
219    println!("10. TYPE SAFETY DEMONSTRATION");
220    println!("-----------------------------");
221    println!("✓ USD + USD = Valid");
222    println!("✓ EUR + EUR = Valid");
223    println!("✓ CAD + CAD = Valid");
224    println!("✗ USD + EUR = Compile Error!");
225    println!("✗ CAD + JPY = Compile Error!");
226    println!("✗ BRL + TRY = Compile Error!");
227    println!();
228
229    println!("=== Global Currencies Example Completed! ===");
230    println!("Total currencies supported: 30+");
231    println!("Regions covered: North America, Europe, Asia, South America, Africa, Middle East");
232    println!("Type safety: 100% compile-time currency mixing prevention");
233}
Source

pub const fn with_source(self, source: &'static str) -> Self

Returns a new Rate with the given static source identifier set.

Existing metadata values not provided by this method are preserved.

Examples found in repository?
examples/conversions.rs (line 111)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}
More examples
Hide additional examples
examples/global_currencies.rs (line 159)
51fn main() {
52    println!("=== Typed Money - Global Currencies Example ===\n");
53
54    // 1. MAJOR FIAT CURRENCIES
55    println!("1. MAJOR FIAT CURRENCIES");
56    println!("------------------------");
57    let usd = Amount::<USD>::from_major(100);
58    let cad = Amount::<CAD>::from_major(135);
59    let chf = Amount::<CHF>::from_major(90);
60    let aud = Amount::<AUD>::from_major(150);
61    let nzd = Amount::<NZD>::from_major(160);
62
63    println!("USD: {} ({} decimals)", usd, USD::DECIMALS);
64    println!("CAD: {} ({} decimals)", cad, CAD::DECIMALS);
65    println!("CHF: {} ({} decimals)", chf, CHF::DECIMALS);
66    println!("AUD: {} ({} decimals)", aud, AUD::DECIMALS);
67    println!("NZD: {} ({} decimals)", nzd, NZD::DECIMALS);
68    println!();
69
70    // 2. ASIAN CURRENCIES
71    println!("2. ASIAN CURRENCIES");
72    println!("-------------------");
73    let cny = Amount::<CNY>::from_major(720);
74    let krw = Amount::<KRW>::from_major(130_000);
75    let sgd = Amount::<SGD>::from_major(135);
76    let hkd = Amount::<HKD>::from_major(780);
77    let twd = Amount::<TWD>::from_major(3100);
78    let inr = Amount::<INR>::from_major(8300);
79
80    println!("CNY: {} ({} decimals)", cny, CNY::DECIMALS);
81    println!("KRW: {} ({} decimals)", krw, KRW::DECIMALS);
82    println!("SGD: {} ({} decimals)", sgd, SGD::DECIMALS);
83    println!("HKD: {} ({} decimals)", hkd, HKD::DECIMALS);
84    println!("TWD: {} ({} decimals)", twd, TWD::DECIMALS);
85    println!("INR: {} ({} decimals)", inr, INR::DECIMALS);
86    println!();
87
88    // 3. EUROPEAN CURRENCIES
89    println!("3. EUROPEAN CURRENCIES");
90    println!("----------------------");
91    let eur = Amount::<EUR>::from_major(85);
92    let gbp = Amount::<GBP>::from_major(75);
93    let sek = Amount::<SEK>::from_major(1050);
94    let nok = Amount::<NOK>::from_major(1100);
95    let dkk = Amount::<DKK>::from_major(650);
96    let pln = Amount::<PLN>::from_major(400);
97    let czk = Amount::<CZK>::from_major(2300);
98    let huf = Amount::<HUF>::from_major(36_000);
99
100    println!("EUR: {} ({} decimals)", eur, EUR::DECIMALS);
101    println!("GBP: {} ({} decimals)", gbp, GBP::DECIMALS);
102    println!("SEK: {} ({} decimals)", sek, SEK::DECIMALS);
103    println!("NOK: {} ({} decimals)", nok, NOK::DECIMALS);
104    println!("DKK: {} ({} decimals)", dkk, DKK::DECIMALS);
105    println!("PLN: {} ({} decimals)", pln, PLN::DECIMALS);
106    println!("CZK: {} ({} decimals)", czk, CZK::DECIMALS);
107    println!("HUF: {} ({} decimals)", huf, HUF::DECIMALS);
108    println!();
109
110    // 4. AMERICAN CURRENCIES
111    println!("4. AMERICAN CURRENCIES");
112    println!("----------------------");
113    let brl = Amount::<BRL>::from_major(500);
114    let mxn = Amount::<MXN>::from_major(1700);
115    let ars = Amount::<ARS>::from_major(85_000);
116    let clp = Amount::<CLP>::from_major(90_000);
117
118    println!("BRL: {} ({} decimals)", brl, BRL::DECIMALS);
119    println!("MXN: {} ({} decimals)", mxn, MXN::DECIMALS);
120    println!("ARS: {} ({} decimals)", ars, ARS::DECIMALS);
121    println!("CLP: {} ({} decimals)", clp, CLP::DECIMALS);
122    println!();
123
124    // 5. AFRICAN/MIDDLE EASTERN CURRENCIES
125    println!("5. AFRICAN/MIDDLE EASTERN CURRENCIES");
126    println!("------------------------------------");
127    let zar = Amount::<ZAR>::from_major(1800);
128    let egp = Amount::<EGP>::from_major(3100);
129    let aed = Amount::<AED>::from_major(370);
130    let sar = Amount::<SAR>::from_major(375);
131    let ils = Amount::<ILS>::from_major(360);
132    let try_currency = Amount::<TRY>::from_major(3000);
133
134    println!("ZAR: {} ({} decimals)", zar, ZAR::DECIMALS);
135    println!("EGP: {} ({} decimals)", egp, EGP::DECIMALS);
136    println!("AED: {} ({} decimals)", aed, AED::DECIMALS);
137    println!("SAR: {} ({} decimals)", sar, SAR::DECIMALS);
138    println!("ILS: {} ({} decimals)", ils, ILS::DECIMALS);
139    println!("TRY: {} ({} decimals)", try_currency, TRY::DECIMALS);
140    println!();
141
142    // 6. CRYPTOCURRENCIES
143    println!("6. CRYPTOCURRENCIES");
144    println!("-------------------");
145    let btc = Amount::<BTC>::from_minor(100_000_000); // 1.00000000 BTC
146    let eth = Amount::<ETH>::from_minor(1_000_000_000_000_000_000); // 1.000000000000000000 ETH
147
148    println!("BTC: {} ({} decimals)", btc, BTC::DECIMALS);
149    println!("ETH: {} ({} decimals)", eth, ETH::DECIMALS);
150    println!();
151
152    // 7. CURRENCY CONVERSION EXAMPLES
153    println!("7. CURRENCY CONVERSION EXAMPLES");
154    println!("-------------------------------");
155
156    // USD to EUR
157    let usd_to_eur = Rate::<USD, EUR>::new(0.85)
158        .with_timestamp_unix_secs(1_700_000_000)
159        .with_source("ECB");
160    let eur_converted = usd.convert(&usd_to_eur);
161    println!(
162        "USD to EUR: {} → {} (rate: {})",
163        usd,
164        eur_converted,
165        usd_to_eur.value()
166    );
167
168    // EUR to GBP
169    let eur_to_gbp = Rate::<EUR, GBP>::new(0.87);
170    let gbp_converted = eur_converted.convert(&eur_to_gbp);
171    println!(
172        "EUR to GBP: {} → {} (rate: {})",
173        eur_converted,
174        gbp_converted,
175        eur_to_gbp.value()
176    );
177
178    // USD to JPY
179    let usd_to_jpy = Rate::<USD, JPY>::new(150.0);
180    let jpy_converted = usd.convert(&usd_to_jpy);
181    println!(
182        "USD to JPY: {} → {} (rate: {})",
183        usd,
184        jpy_converted,
185        usd_to_jpy.value()
186    );
187    println!();
188
189    // 8. ROUNDING EXAMPLES
190    println!("8. ROUNDING EXAMPLES");
191    println!("--------------------");
192    let usd_amount = Amount::<USD>::from_minor(12345); // $123.45
193    println!("Original: {}", usd_amount);
194    println!("Half Up: {}", usd_amount.round(RoundingMode::HalfUp));
195    println!("Half Down: {}", usd_amount.round(RoundingMode::HalfDown));
196    println!("Half Even: {}", usd_amount.round(RoundingMode::HalfEven));
197    println!("Floor: {}", usd_amount.round(RoundingMode::Floor));
198    println!("Ceiling: {}", usd_amount.round(RoundingMode::Ceiling));
199    println!();
200
201    // 9. CURRENCY METADATA
202    println!("9. CURRENCY METADATA");
203    println!("--------------------");
204    let currencies = [
205        ("USD", USD::CODE, USD::SYMBOL, USD::DECIMALS),
206        ("EUR", EUR::CODE, EUR::SYMBOL, EUR::DECIMALS),
207        ("JPY", JPY::CODE, JPY::SYMBOL, JPY::DECIMALS),
208        ("CNY", CNY::CODE, CNY::SYMBOL, CNY::DECIMALS),
209        ("BRL", BRL::CODE, BRL::SYMBOL, BRL::DECIMALS),
210        ("AED", AED::CODE, AED::SYMBOL, AED::DECIMALS),
211    ];
212
213    for (name, code, symbol, decimals) in currencies {
214        println!("{}: {} {} ({} decimals)", name, symbol, code, decimals);
215    }
216    println!();
217
218    // 10. TYPE SAFETY DEMONSTRATION
219    println!("10. TYPE SAFETY DEMONSTRATION");
220    println!("-----------------------------");
221    println!("✓ USD + USD = Valid");
222    println!("✓ EUR + EUR = Valid");
223    println!("✓ CAD + CAD = Valid");
224    println!("✗ USD + EUR = Compile Error!");
225    println!("✗ CAD + JPY = Compile Error!");
226    println!("✗ BRL + TRY = Compile Error!");
227    println!();
228
229    println!("=== Global Currencies Example Completed! ===");
230    println!("Total currencies supported: 30+");
231    println!("Regions covered: North America, Europe, Asia, South America, Africa, Middle East");
232    println!("Type safety: 100% compile-time currency mixing prevention");
233}
Source

pub const fn with_metadata( self, timestamp_unix_secs: u64, source: &'static str, ) -> Self

Convenience method to set both timestamp and source metadata at once.

Source

pub fn inverse(&self) -> Rate<To, From>

Returns the inverse rate (To -> From).

§Examples
use typed_money::{Rate, USD, EUR};

let usd_to_eur = Rate::<USD, EUR>::new(0.85);
let eur_to_usd = usd_to_eur.inverse();

// Inverse of 0.85 is approximately 1.176
Examples found in repository?
examples/conversions.rs (line 41)
10fn main() {
11    println!("=== Currency Conversion Examples ===\n");
12
13    // ========================================
14    // Basic Conversion
15    // ========================================
16    println!("1. BASIC CONVERSION");
17    println!("-------------------");
18
19    let usd_amount = Amount::<USD>::from_major(100);
20    println!("Starting amount: {}", usd_amount);
21
22    // Create an exchange rate: 1 USD = 0.85 EUR
23    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
24    println!("Exchange rate: 1 USD = 0.85 EUR");
25
26    // Convert
27    let eur_amount = usd_amount.convert(&usd_to_eur);
28    println!("Converted amount: {}", eur_amount);
29    println!("(${} × 0.85 = €{})\n", 100, eur_amount.to_major_floor());
30
31    // ========================================
32    // Inverse Rates
33    // ========================================
34    println!("2. INVERSE RATES");
35    println!("----------------");
36
37    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
38    println!("USD → EUR rate: {}", usd_to_eur.value());
39
40    // Get the inverse rate automatically
41    let eur_to_usd = usd_to_eur.inverse();
42    println!("EUR → USD rate (inverse): {}", eur_to_usd.value());
43    println!("(1 / 0.85 = ~1.176)\n");
44
45    // Converting back
46    let original_usd = Amount::<USD>::from_major(100);
47    let eur = original_usd.convert(&usd_to_eur);
48    let back_to_usd = eur.convert(&eur_to_usd);
49
50    println!("Original: {}", original_usd);
51    println!("To EUR:   {}", eur);
52    println!("Back to USD: {}", back_to_usd);
53    println!("(Should be approximately the same)\n");
54
55    // ========================================
56    // Multiple Conversions
57    // ========================================
58    println!("3. MULTIPLE CONVERSIONS");
59    println!("-----------------------");
60
61    let usd = Amount::<USD>::from_major(1000);
62    println!("Starting with: {}", usd);
63
64    // Define multiple rates
65    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
66    let usd_to_gbp = Rate::<USD, GBP>::new(0.73);
67    let usd_to_jpy = Rate::<USD, JPY>::new(110.0);
68
69    println!("\nExchange rates:");
70    println!("  1 USD = {} EUR", usd_to_eur.value());
71    println!("  1 USD = {} GBP", usd_to_gbp.value());
72    println!("  1 USD = {} JPY", usd_to_jpy.value());
73
74    println!("\nConversions:");
75    let eur = usd.convert(&usd_to_eur);
76    let gbp = usd.convert(&usd_to_gbp);
77    let jpy = usd.convert(&usd_to_jpy);
78
79    println!("  {} → {}", usd, eur);
80    println!("  {} → {}", usd, gbp);
81    println!("  {} → {}", usd, jpy);
82
83    // ========================================
84    // Chained Conversions
85    // ========================================
86    println!("\n4. CHAINED CONVERSIONS");
87    println!("----------------------");
88
89    println!("Converting USD → EUR → GBP");
90
91    let usd = Amount::<USD>::from_major(100);
92    let usd_to_eur = Rate::<USD, EUR>::new(0.85);
93    let eur_to_gbp = Rate::<EUR, GBP>::new(0.86);
94
95    println!("Starting: {}", usd);
96    let eur = usd.convert(&usd_to_eur);
97    println!("After USD→EUR: {}", eur);
98    let gbp = eur.convert(&eur_to_gbp);
99    println!("After EUR→GBP: {}", gbp);
100    println!("(${} × 0.85 × 0.86 = £{})\n", 100, gbp.to_major_floor());
101
102    // ========================================
103    // Rate Metadata for Auditability
104    // ========================================
105    println!("5. RATE METADATA FOR AUDITABILITY");
106    println!("----------------------------------");
107
108    // Create a rate with metadata
109    let rate = Rate::<USD, EUR>::new(0.85)
110        .with_timestamp_unix_secs(1700000000)
111        .with_source("ECB"); // European Central Bank
112
113    println!("Rate: {}", rate.value());
114    println!("Timestamp: {:?}", rate.timestamp_unix_secs());
115    println!("Source: {:?}", rate.source());
116
117    let amount = Amount::<USD>::from_major(1000);
118    let converted = amount.convert(&rate);
119    println!(
120        "\nConverted {} to {} using rate from {:?}",
121        amount,
122        converted,
123        rate.source().unwrap_or("unknown")
124    );
125
126    // ========================================
127    // Real-World Example: International Payment
128    // ========================================
129    println!("\n6. REAL-WORLD EXAMPLE: INTERNATIONAL PAYMENT");
130    println!("---------------------------------------------");
131
132    // Customer pays in USD
133    let payment_usd = Amount::<USD>::from_major(250);
134    println!("Customer payment: {}", payment_usd);
135
136    // Current exchange rate (would come from an API in production)
137    let current_rate = Rate::<USD, EUR>::new(0.92)
138        .with_timestamp_unix_secs(1700000000)
139        .with_source("API");
140
141    // Convert to EUR
142    let payment_eur = payment_usd.convert(&current_rate);
143    println!("Converted to EUR: {}", payment_eur);
144
145    // Calculate fees
146    let fee_percentage = 3; // 3% transaction fee
147    let fee = (payment_eur * fee_percentage) / 100;
148    println!("Transaction fee ({}%): {}", fee_percentage, fee);
149
150    let final_amount = payment_eur - fee;
151    println!("Final amount to recipient: {}", final_amount);
152
153    println!("\nTransaction summary:");
154    println!("  Original: {}", payment_usd);
155    println!(
156        "  Rate: {} (from {:?})",
157        current_rate.value(),
158        current_rate.source().unwrap_or("N/A")
159    );
160    println!("  Converted: {}", payment_eur);
161    println!("  Fee: -{}", fee);
162    println!("  Final: {}", final_amount);
163
164    // ========================================
165    // Type Safety with Conversions
166    // ========================================
167    println!("\n7. TYPE SAFETY");
168    println!("--------------");
169
170    println!("✓ Can only convert with matching rate types");
171    println!("✓ USD amount requires Rate<USD, X>");
172    println!("✗ Cannot use Rate<EUR, GBP> on USD amount (compile error!)");
173    println!("\nThe type system ensures you always use the correct exchange rate!");
174
175    // This would NOT compile:
176    // let usd = Amount::<USD>::from_major(100);
177    // let wrong_rate = Rate::<EUR, GBP>::new(0.86);
178    // let invalid = usd.convert(&wrong_rate);  // Compile error!
179
180    println!("\n=== All conversion examples completed! ===");
181}

Trait Implementations§

Source§

impl<From: Clone + Currency, To: Clone + Currency> Clone for Rate<From, To>

Source§

fn clone(&self) -> Rate<From, To>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<From: Debug + Currency, To: Debug + Currency> Debug for Rate<From, To>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<From: PartialEq + Currency, To: PartialEq + Currency> PartialEq for Rate<From, To>

Source§

fn eq(&self, other: &Rate<From, To>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<From: Copy + Currency, To: Copy + Currency> Copy for Rate<From, To>

Source§

impl<From: Currency, To: Currency> StructuralPartialEq for Rate<From, To>

Auto Trait Implementations§

§

impl<From, To> Freeze for Rate<From, To>

§

impl<From, To> RefUnwindSafe for Rate<From, To>
where From: RefUnwindSafe, To: RefUnwindSafe,

§

impl<From, To> Send for Rate<From, To>
where From: Send, To: Send,

§

impl<From, To> Sync for Rate<From, To>
where From: Sync, To: Sync,

§

impl<From, To> Unpin for Rate<From, To>
where From: Unpin, To: Unpin,

§

impl<From, To> UnwindSafe for Rate<From, To>
where From: UnwindSafe, To: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.