etopay_sdk/types/
currencies.rs

1use super::error::{Result, TypeError};
2use api_types::api::{generic::ApiCryptoCurrency, viviswap::detail::SwapPaymentDetailKey};
3use serde::Serialize;
4
5/// Supported currencies (mirrors `api_types` but needed so we can implement the additional
6/// `coin_type` and `to_vivi_payment_method_key` function)
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
8pub enum Currency {
9    /// Iota token
10    Iota,
11    /// Ethereum token
12    Eth,
13}
14
15impl TryFrom<String> for Currency {
16    type Error = TypeError;
17    /// Convert from String to Currency, used at the API boundary to interface with the bindings.
18    fn try_from(currency: String) -> Result<Self> {
19        match currency.to_lowercase().as_str() {
20            "iota" => Ok(Self::Iota),
21            "eth" => Ok(Self::Eth),
22            _ => Err(TypeError::InvalidCurrency(currency)),
23        }
24    }
25}
26
27impl Currency {
28    /// Convert this [`Currency`] into a [`SwapPaymentDetailKey`]
29    pub fn to_vivi_payment_method_key(self) -> SwapPaymentDetailKey {
30        match self {
31            Self::Iota => SwapPaymentDetailKey::Iota,
32            Self::Eth => SwapPaymentDetailKey::Eth,
33        }
34    }
35}
36
37/// We want to convert from our internal Currency enum into the one used in the API.
38impl From<Currency> for ApiCryptoCurrency {
39    fn from(value: Currency) -> Self {
40        match value {
41            Currency::Iota => ApiCryptoCurrency::Iota,
42            Currency::Eth => ApiCryptoCurrency::Eth,
43        }
44    }
45}
46impl From<ApiCryptoCurrency> for Currency {
47    fn from(value: ApiCryptoCurrency) -> Self {
48        match value {
49            ApiCryptoCurrency::Iota => Currency::Iota,
50            ApiCryptoCurrency::Eth => Currency::Eth,
51        }
52    }
53}
54
55// the display implementation must be compatible with TryFrom<String> since it is part of the
56// public binding interface.
57impl std::fmt::Display for Currency {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        match self {
60            Currency::Iota => write!(f, "Iota"),
61            Currency::Eth => write!(f, "Eth"),
62        }
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use crate::types::currencies::Currency;
69
70    #[rstest::rstest]
71    fn test_display_roundtrip(#[values(Currency::Iota, Currency::Eth)] c: Currency) {
72        assert_eq!(c, Currency::try_from(c.to_string()).unwrap());
73    }
74}