bnr_xfs/currency/
code.rs

1use std::fmt;
2
3use currency_iso4217::Currency as IsoCurrency;
4
5use crate::xfs::{value::XfsValue, xfs_struct::XfsMember};
6use crate::{Error, Result};
7
8use super::Exponent;
9
10/// Represents an ISO 4217 currency code.
11#[repr(C)]
12#[derive(Clone, Copy, Debug, Default, PartialEq, serde::Deserialize, serde::Serialize)]
13pub struct CurrencyCode(IsoCurrency);
14
15impl CurrencyCode {
16    /// Creates a new [CurrencyCode].
17    pub const fn new() -> Self {
18        Self(IsoCurrency::new())
19    }
20
21    /// Creates a new [CurrencyCode] from the provided parameter.
22    pub const fn create(val: IsoCurrency) -> Self {
23        Self(val)
24    }
25
26    /// Gets the [XfsMember] name.
27    pub const fn xfs_name() -> &'static str {
28        "currencyCode"
29    }
30}
31
32impl From<&CurrencyCode> for Exponent {
33    fn from(val: &CurrencyCode) -> Self {
34        Self::create(match val.0 {
35            IsoCurrency::AUD
36            | IsoCurrency::CAD
37            | IsoCurrency::CHF
38            | IsoCurrency::EUR
39            | IsoCurrency::GBP
40            | IsoCurrency::USD => -2,
41            IsoCurrency::JPY | IsoCurrency::MXN => -1,
42            IsoCurrency::AMD => 0,
43            // FIXME: fill out with more actual values
44            _ => 1,
45        })
46    }
47}
48
49impl From<CurrencyCode> for Exponent {
50    fn from(val: CurrencyCode) -> Self {
51        (&val).into()
52    }
53}
54
55impl From<&str> for CurrencyCode {
56    fn from(val: &str) -> Self {
57        Self(val.into())
58    }
59}
60
61impl From<&CurrencyCode> for &'static str {
62    fn from(val: &CurrencyCode) -> Self {
63        val.0.into()
64    }
65}
66
67impl From<CurrencyCode> for &'static str {
68    fn from(val: CurrencyCode) -> Self {
69        (&val).into()
70    }
71}
72
73impl From<&CurrencyCode> for XfsValue {
74    fn from(val: &CurrencyCode) -> Self {
75        Self::new().with_string(<&str>::from(val))
76    }
77}
78
79impl From<CurrencyCode> for XfsValue {
80    fn from(val: CurrencyCode) -> Self {
81        (&val).into()
82    }
83}
84
85impl TryFrom<&XfsValue> for CurrencyCode {
86    type Error = Error;
87
88    fn try_from(val: &XfsValue) -> Result<Self> {
89        Ok(val
90            .string()
91            .ok_or(Error::Xfs(format!(
92                "Expected CurrencyCode XfsValue, have: {val}"
93            )))?
94            .into())
95    }
96}
97
98impl TryFrom<XfsValue> for CurrencyCode {
99    type Error = Error;
100
101    fn try_from(val: XfsValue) -> Result<Self> {
102        (&val).try_into()
103    }
104}
105
106impl From<&CurrencyCode> for XfsMember {
107    fn from(val: &CurrencyCode) -> Self {
108        Self::create(CurrencyCode::xfs_name(), val.into())
109    }
110}
111
112impl From<CurrencyCode> for XfsMember {
113    fn from(val: CurrencyCode) -> Self {
114        (&val).into()
115    }
116}
117
118impl TryFrom<&XfsMember> for CurrencyCode {
119    type Error = Error;
120
121    fn try_from(val: &XfsMember) -> Result<Self> {
122        match (val.name(), val.value().string()) {
123            (n, Some(v)) if n == CurrencyCode::xfs_name() => Ok(v.into()),
124            _ => Err(Error::Xfs(format!(
125                "Expected CurrencyCode XfsMember, have: {val}"
126            ))),
127        }
128    }
129}
130
131impl TryFrom<XfsMember> for CurrencyCode {
132    type Error = Error;
133
134    fn try_from(val: XfsMember) -> Result<Self> {
135        (&val).try_into()
136    }
137}
138
139impl fmt::Display for CurrencyCode {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        write!(f, "{}", self.0)
142    }
143}