crypto_pay_api/models/
currency.rs

1use std::fmt::Display;
2
3use crate::utils::deserialize_currency_code;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Serialize, Deserialize)]
7pub struct Currency {
8    pub is_blockchain: bool,
9    pub is_stablecoin: bool,
10    pub is_fiat: bool,
11    pub name: String,
12    #[serde(deserialize_with = "deserialize_currency_code")]
13    pub code: CurrencyCode,
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub url: Option<String>,
16    pub decimals: u8,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
20#[serde(untagged)]
21pub enum CurrencyCode {
22    Crypto(CryptoCurrencyCode),
23    Fiat(FiatCurrencyCode),
24}
25
26#[cfg(not(tarpaulin))]
27impl Display for CurrencyCode {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            CurrencyCode::Crypto(code) => write!(f, "{}", code),
31            CurrencyCode::Fiat(code) => write!(f, "{}", code),
32        }
33    }
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
37#[serde(rename_all = "UPPERCASE")]
38pub enum CryptoCurrencyCode {
39    Usdt,
40    Ton,
41    Btc,
42    Eth,
43    Ltc,
44    Bnb,
45    Trx,
46    Usdc,
47    Doge,
48    Send,
49    Jet,
50    #[serde(other)]
51    Unknown,
52}
53
54#[cfg(not(tarpaulin))]
55impl Display for CryptoCurrencyCode {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        write!(f, "{:?}", self)
58    }
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
62#[serde(rename_all = "UPPERCASE")]
63pub enum FiatCurrencyCode {
64    Usd,
65    Eur,
66    Rub,
67    Byn,
68    Uah,
69    Gbp,
70    Cny,
71    Kgs,
72    Kzt,
73    Uzs,
74    Gel,
75    Try,
76    Amd,
77    Thb,
78    Tjs,
79    Inr,
80    Brl,
81    Idr,
82    Azn,
83    Aed,
84    Pln,
85    Ils,
86    #[serde(other)]
87    Unknown,
88}
89
90#[cfg(not(tarpaulin))]
91impl Display for FiatCurrencyCode {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        write!(f, "{:?}", self)
94    }
95}
96
97#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
98#[serde(rename_all = "lowercase")]
99pub enum CurrencyType {
100    Crypto,
101    Fiat,
102}
103
104#[cfg(not(tarpaulin))]
105impl Display for CurrencyType {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        write!(f, "{:?}", self)
108    }
109}
110
111impl From<CryptoCurrencyCode> for CurrencyCode {
112    fn from(code: CryptoCurrencyCode) -> Self {
113        CurrencyCode::Crypto(code)
114    }
115}
116
117impl From<FiatCurrencyCode> for CurrencyCode {
118    fn from(code: FiatCurrencyCode) -> Self {
119        CurrencyCode::Fiat(code)
120    }
121}
122
123#[cfg(test)]
124mod tests {
125    use super::*;
126
127    #[test]
128    fn test_currency_type_serialization() {
129        let crypto = CurrencyType::Crypto;
130        let fiat = CurrencyType::Fiat;
131
132        assert_eq!(serde_json::to_string(&crypto).unwrap(), "\"crypto\"");
133        assert_eq!(serde_json::to_string(&fiat).unwrap(), "\"fiat\"");
134    }
135
136    #[test]
137    fn test_crypto_currency_code_serialization() {
138        let btc = CryptoCurrencyCode::Btc;
139        let ton = CryptoCurrencyCode::Ton;
140
141        assert_eq!(serde_json::to_string(&btc).unwrap(), "\"BTC\"");
142        assert_eq!(serde_json::to_string(&ton).unwrap(), "\"TON\"");
143    }
144
145    #[test]
146    fn test_fiat_currency_code_serialization() {
147        let usd = FiatCurrencyCode::Usd;
148        let eur = FiatCurrencyCode::Eur;
149
150        assert_eq!(serde_json::to_string(&usd).unwrap(), "\"USD\"");
151        assert_eq!(serde_json::to_string(&eur).unwrap(), "\"EUR\"");
152    }
153
154    #[test]
155    fn test_currency_code_deserialization() {
156        let crypto: CryptoCurrencyCode = serde_json::from_str("\"BTC\"").unwrap();
157        let fiat: FiatCurrencyCode = serde_json::from_str("\"USD\"").unwrap();
158
159        assert_eq!(crypto, CryptoCurrencyCode::Btc);
160        assert_eq!(fiat, FiatCurrencyCode::Usd);
161
162        assert_eq!(
163            serde_json::from_str::<CryptoCurrencyCode>("\"btc\"").unwrap(),
164            CryptoCurrencyCode::Unknown
165        );
166        assert_eq!(
167            serde_json::from_str::<FiatCurrencyCode>("\"usd\"").unwrap(),
168            FiatCurrencyCode::Unknown
169        );
170    }
171
172    #[test]
173    fn test_currency_code_conversion() {
174        let crypto = CryptoCurrencyCode::Btc;
175        let fiat = FiatCurrencyCode::Usd;
176
177        let currency_code_crypto: CurrencyCode = crypto.into();
178        let currency_code_fiat: CurrencyCode = fiat.into();
179
180        assert!(matches!(
181            currency_code_crypto,
182            CurrencyCode::Crypto(CryptoCurrencyCode::Btc)
183        ));
184        assert!(matches!(currency_code_fiat, CurrencyCode::Fiat(FiatCurrencyCode::Usd)));
185    }
186}