rateslib/fx/rates/
fxpair.rs1use crate::fx::rates::ccy::Ccy;
2use pyo3::exceptions::PyValueError;
3use pyo3::PyErr;
4use serde::{Deserialize, Serialize};
5use std::fmt;
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub struct FXPair(pub(crate) Ccy, pub(crate) Ccy);
10
11impl FXPair {
12 pub fn try_new(lhs: &str, rhs: &str) -> Result<Self, PyErr> {
14 let lhs_ = Ccy::try_new(lhs)?;
15 let rhs_ = Ccy::try_new(rhs)?;
16 if lhs_ == rhs_ {
17 return Err(PyValueError::new_err(
18 "`FXPair` must be created from two distinct currencies, not same.",
19 ));
20 }
21 Ok(FXPair(lhs_, rhs_))
22 }
23}
24
25impl fmt::Display for FXPair {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27 write!(f, "{}{}", self.0.name, self.1.name)
28 }
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn fxpair_creation() {
37 let a = FXPair::try_new("usd", "eur").unwrap();
38 let b = FXPair::try_new("USD", "EUR").unwrap();
39 assert_eq!(a, b)
40 }
41
42 #[test]
43 fn fxpair_creation_error() {
44 match FXPair::try_new("usd", "USD") {
45 Ok(_) => assert!(false),
46 Err(_) => assert!(true),
47 }
48 }
49}